Skip to content

Commit ddd0437

Browse files
tyler-daneclaude
andauthored
fix(web): close overlay after successful sync (#1482)
* refactor(issue-templates): simplify feature request and bug report templates - Removed unnecessary emoji from template names for a cleaner presentation. - Eliminated the priority dropdown from the feature request template to streamline the submission process. - Updated the bug report template to remove the emoji, enhancing consistency across issue templates. - Adjusted the configuration file to reflect these changes, ensuring clarity in the issue submission process. * test(socket): enhance SocketProvider tests with async act calls - Updated SocketProvider tests to utilize `act` for asynchronous callback invocations, ensuring proper handling of state updates during testing. - Improved test reliability by wrapping callback executions in `act`, aligning with React's testing best practices. * test(socket): add race condition handling test for useGcalSync - Introduced a new test case to verify the correct handling of import end events when the awaitingImportResults state changes mid-render. - Utilized a ref to prevent stale closures, ensuring that the correct state is referenced during socket event processing. - Enhanced the reliability of the useGcalSync hook by ensuring it properly processes events even when state changes occur asynchronously. * delete(svg): remove unused circle.svg file - Deleted the circle.svg file from the public SVG assets as it is no longer needed in the project. - This cleanup helps streamline the asset management and reduces unnecessary file clutter. * fix(socket): address PR review comments for useGcalSync - Update ref synchronously during render instead of in useEffect to fully eliminate race condition window - Rename misleading test name (timeout -> successfully) - Fix test assertions to validate action creator calls directly instead of using unused variable and dispatch-based assertions Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor(sync): rename awaitingImportResults to isImportPending - Updated state management and selectors to reflect the new naming convention for clarity. - Adjusted related components and tests to ensure consistency with the updated state name. - This change enhances code readability and aligns with the overall naming strategy in the project. * refactor(socket): simplify reconnect logic and update test case - Removed the 1-second delay in the reconnect function, allowing for immediate reconnection after disconnection. - Updated the corresponding test case to reflect the change in behavior, ensuring it accurately tests the immediate reconnection functionality. - This change enhances the responsiveness of the socket client and improves the clarity of the test case. * refactor(tests): update useGcalSync tests to remove fake timers - Removed the use of fake timers in the tests for useGcalSync, simplifying the test setup. - Updated type definitions for event handler variables to allow for undefined values, enhancing type safety. - This change improves test clarity and aligns with best practices for handling asynchronous events in React testing. * test(socket): add integration tests for Google Calendar re-authentication flow - Introduced a new test suite for the Google Calendar re-authentication process, validating user experience during import operations. - Implemented tests to ensure the spinner visibility during import initiation, handling of socket events, and correct state updates upon import completion. - Enhanced test reliability by utilizing `act` for asynchronous operations and capturing socket event callbacks. - This addition improves coverage for the re-authentication flow and ensures a seamless user experience during Google Calendar synchronization. * refactor(sync): rename setAwaitingImportResults to setIsImportPending - Updated the Redux action and corresponding function names to improve clarity and consistency in the import state management. - Adjusted all related components and tests to reflect the new naming convention, ensuring seamless integration across the codebase. - This change enhances code readability and aligns with the overall naming strategy in the project. --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6936f5c commit ddd0437

18 files changed

Lines changed: 783 additions & 76 deletions

File tree

.github/ISSUE_TEMPLATE/1-feature-request.yml

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Feature Request
1+
name: Feature Request
22
description: You want something added to the app
33
labels: [enhancement]
44
projects: [SwitchbackTech/4]
@@ -9,17 +9,6 @@ body:
99
value: |
1010
Thanks for taking the time to fill out this feature request!
1111
12-
- type: dropdown
13-
attributes:
14-
label: Priority
15-
description: How important is this feature to you?
16-
multiple: false
17-
options:
18-
- Critical (blocking my workflow)
19-
- High (would significantly improve my experience)
20-
- Medium (nice to have)
21-
- Low (minor improvement)
22-
2312
- type: textarea
2413
attributes:
2514
label: Feature Description

.github/ISSUE_TEMPLATE/2-bug-report.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Bug Report 🐞
1+
name: Bug Report
22
description: You found something wrong
33
labels: [bug]
44
projects: [SwitchbackTech/4]

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
blank_issues_enabled: true
22
contact_links:
3-
- name: 💬 GitHub Discussions
3+
- name: GitHub Discussions
44
url: https://github.com/SwitchbackTech/compass/discussions
55
about: Start a GitHub Discussion for general questions and feedback
6-
- name: 📚 Documentation
6+
- name: Documentation
77
url: https://docs.compasscalendar.com
88
about: Check our documentation for setup guides, API reference, and contributing guidelines

e2e/utils/oauth-test-utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ export const setIsSyncing = async (page: Page, value: boolean) => {
7474
/**
7575
* Set the awaitingImportResults state in Redux (triggers import phase when true).
7676
*/
77-
export const setAwaitingImportResults = async (page: Page, value: boolean) => {
78-
await page.evaluate((awaitingValue) => {
77+
export const setIsImportPending = async (page: Page, value: boolean) => {
78+
await page.evaluate((isImportPendingValue) => {
7979
const store = (window as any).__COMPASS_STORE__;
8080
if (store) {
8181
store.dispatch({
82-
type: "async/importGCal/setAwaitingImportResults",
83-
payload: awaitingValue,
82+
type: "async/importGCal/setIsImportPending",
83+
payload: isImportPendingValue,
8484
});
8585
}
8686
}, value);

packages/web/src/__tests__/utils/state/store.test.util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ export const createInitialState = (
122122
importing: false,
123123
importResults: null,
124124
pendingLocalEventsSynced: null,
125-
awaitingImportResults: false,
125+
isImportPending: false,
126126
importError: null,
127127
},
128128
importLatest: {

packages/web/src/auth/hooks/oauth/useGoogleAuth.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ describe("useGoogleAuth", () => {
161161
);
162162
expect(mockDispatchFn).toHaveBeenCalledWith(
163163
expect.objectContaining({
164-
type: "async/importGCal/setAwaitingImportResults",
164+
type: "async/importGCal/setIsImportPending",
165165
payload: true,
166166
}),
167167
);
@@ -193,7 +193,7 @@ describe("useGoogleAuth", () => {
193193

194194
expect(mockDispatchFn).toHaveBeenCalledWith(
195195
expect.objectContaining({
196-
type: "async/importGCal/setAwaitingImportResults",
196+
type: "async/importGCal/setIsImportPending",
197197
payload: false,
198198
}),
199199
);
@@ -252,7 +252,7 @@ describe("useGoogleAuth", () => {
252252
expect(mockSetAuthenticated).not.toHaveBeenCalled();
253253
expect(mockDispatchFn).toHaveBeenCalledWith(
254254
expect.objectContaining({
255-
type: "async/importGCal/setAwaitingImportResults",
255+
type: "async/importGCal/setIsImportPending",
256256
payload: false,
257257
}),
258258
);
@@ -298,7 +298,7 @@ describe("useGoogleAuth", () => {
298298

299299
expect(mockDispatchFn).toHaveBeenCalledWith(
300300
expect.objectContaining({
301-
type: "async/importGCal/setAwaitingImportResults",
301+
type: "async/importGCal/setIsImportPending",
302302
payload: false,
303303
}),
304304
);

packages/web/src/auth/hooks/oauth/useGoogleAuth.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export function useGoogleAuth() {
3131
onStart: () => {
3232
dismissErrorToast(SESSION_EXPIRED_TOAST_ID);
3333
dispatch(startAuthenticating());
34-
dispatch(importGCalSlice.actions.setAwaitingImportResults(true));
34+
dispatch(importGCalSlice.actions.setIsImportPending(true));
3535
dispatch(importGCalSlice.actions.clearImportResults(undefined));
3636
},
3737
onSuccess: async (data) => {
@@ -42,7 +42,7 @@ export function useGoogleAuth() {
4242
dispatch(
4343
authError(authResult.error?.message || "Authentication failed"),
4444
);
45-
dispatch(importGCalSlice.actions.setAwaitingImportResults(false));
45+
dispatch(importGCalSlice.actions.setIsImportPending(false));
4646
dispatch(importGCalSlice.actions.importing(false));
4747
return;
4848
}
@@ -59,7 +59,7 @@ export function useGoogleAuth() {
5959
dispatch(authSuccess());
6060
// Now that OAuth is complete, indicate that calendar import is starting
6161
dispatch(importGCalSlice.actions.importing(true));
62-
dispatch(importGCalSlice.actions.setAwaitingImportResults(true));
62+
dispatch(importGCalSlice.actions.setIsImportPending(true));
6363
});
6464

6565
const syncResult = await syncLocalEvents();
@@ -90,7 +90,7 @@ export function useGoogleAuth() {
9090
error instanceof Error ? error.message : "Authentication failed",
9191
),
9292
);
93-
dispatch(importGCalSlice.actions.setAwaitingImportResults(false));
93+
dispatch(importGCalSlice.actions.setIsImportPending(false));
9494
dispatch(importGCalSlice.actions.importing(false));
9595
throw error; // Re-throw so useGoogleLoginWithSyncOverlay can handle it via onError
9696
}
@@ -102,7 +102,7 @@ export function useGoogleAuth() {
102102
error instanceof Error ? error.message : "Authentication failed",
103103
),
104104
);
105-
dispatch(importGCalSlice.actions.setAwaitingImportResults(false));
105+
dispatch(importGCalSlice.actions.setIsImportPending(false));
106106
dispatch(importGCalSlice.actions.importing(false));
107107
},
108108
});

packages/web/src/components/SyncEventsOverlay/SyncEventsOverlay.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import "@testing-library/jest-dom";
33
import { render, screen } from "@testing-library/react";
44
import { selectIsAuthenticating } from "@web/ducks/auth/selectors/auth.selectors";
55
import {
6-
selectAwaitingImportResults,
76
selectImporting,
7+
selectIsImportPending,
88
} from "@web/ducks/events/selectors/sync.selector";
99
import { useAppSelector } from "@web/store/store.hooks";
1010
import { SyncEventsOverlay } from "./SyncEventsOverlay";
@@ -33,7 +33,7 @@ describe("SyncEventsOverlay", () => {
3333
if (selector === selectImporting) {
3434
return importingValue;
3535
}
36-
if (selector === selectAwaitingImportResults) {
36+
if (selector === selectIsImportPending) {
3737
return awaitingValue;
3838
}
3939
if (selector === selectIsAuthenticating) {

packages/web/src/components/SyncEventsOverlay/SyncEventsOverlay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { useBufferedVisibility } from "@web/common/hooks/useBufferedVisibility";
33
import { OverlayPanel } from "@web/components/OverlayPanel/OverlayPanel";
44
import { selectIsAuthenticating } from "@web/ducks/auth/selectors/auth.selectors";
55
import {
6-
selectAwaitingImportResults,
76
selectImporting,
7+
selectIsImportPending,
88
} from "@web/ducks/events/selectors/sync.selector";
99
import { useAppSelector } from "@web/store/store.hooks";
1010

1111
export const SyncEventsOverlay = () => {
1212
const importing = useAppSelector(selectImporting);
13-
const awaitingImportResults = useAppSelector(selectAwaitingImportResults);
13+
const awaitingImportResults = useAppSelector(selectIsImportPending);
1414
const isAuthenticating = useAppSelector(selectIsAuthenticating);
1515

1616
// Show overlay when:

packages/web/src/ducks/events/selectors/sync.selector.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export const selectImportGCalState = ({ sync }: RootState) => sync.importGCal;
88
export const selectImporting = ({ sync }: RootState) =>
99
sync.importGCal.importing;
1010

11-
export const selectAwaitingImportResults = ({ sync }: RootState) =>
12-
sync.importGCal.awaitingImportResults;
11+
export const selectIsImportPending = ({ sync }: RootState) =>
12+
sync.importGCal.isImportPending;
1313

1414
export const selectImportResults = ({ sync }: RootState) =>
1515
sync.importGCal.importResults;

0 commit comments

Comments
 (0)