History

fix(web): remove duplicate provider update progress (#7761)

Naveed Iqbal committed 2 months ago

Commit 4e169df1 parent 5a7a7cf3 files · +49 −47Browse files

Unified · Split

3 files
  1. apps/web/src/components/ProviderUpdateLaunchNotification.logic.test.ts +16 −0
  2. apps/web/src/components/ProviderUpdateLaunchNotification.logic.ts +4 −0
  3. apps/web/src/components/ProviderUpdatePrimaryNotification.tsx +29 −47
apps/web/src/components/ProviderUpdateLaunchNotification.logic.test.ts+16−0
@@ -31,6 +31,7 @@ import { · 30 unmodified lines
3131 parseWslDistroFromInstanceId,
3232 providerUpdateNotificationKey,
3333 resolveEnvironmentUpdateRowStatus,
34+ shouldShowPrimaryProviderUpdateToast,
3435 type LocalEnvironmentProvidersInput,
3536 type LocalEnvironmentUpdateGroup,
3637 type LocalProviderUpdateOutcome,
@@ -325,6 +326,21 @@ describe("provider update launch notification logic", () => { · 288 unmodified lines
325326 type: "loading",
326327 title: "Updating provider",
327328 });
329+ expect(shouldShowPrimaryProviderUpdateToast(view)).toBe(false);
330+ });
331+
332+ it("keeps the initial prompt and terminal outcomes visible as toasts", () => {
333+ expect(
334+ shouldShowPrimaryProviderUpdateToast(
335+ getProviderUpdateInitialToastView({
336+ updateProviders: [updateCandidate({ driver: driver("codex") })],
337+ oneClickProviders: [updateCandidate({ driver: driver("codex") })],
338+ }),
339+ ),
340+ ).toBe(true);
341+ expect(
342+ shouldShowPrimaryProviderUpdateToast(getProviderUpdateRejectedToastView(1, "boom")),
343+ ).toBe(true);
328344 });
329345
330346 it("uses server failure state for failed progress", () => {
apps/web/src/components/ProviderUpdateLaunchNotification.logic.ts+4−0
@@ -231,6 +231,10 @@ export function getProviderUpdateInitialToastView(input: { · 230 unmodified lines
231231 };
232232 }
233233
234+export function shouldShowPrimaryProviderUpdateToast(view: ProviderUpdateToastView): boolean {
235+ return view.phase !== "running";
236+}
237+
234238 export function getProviderUpdateRunningToastView(providerCount: number): ProviderUpdateToastView {
235239 return {
236240 phase: "running",
apps/web/src/components/ProviderUpdatePrimaryNotification.tsx+29−47
@@ -16,8 +16,8 @@ import { · 15 unmodified lines
1616 getProviderUpdateInitialToastView,
1717 getProviderUpdateProgressToastView,
1818 getProviderUpdateRejectedToastView,
19− getProviderUpdateRunningToastView,
2019 providerUpdateNotificationKey,
20+ shouldShowPrimaryProviderUpdateToast,
2121 type ProviderUpdateToastView,
2222 } from "./ProviderUpdateLaunchNotification.logic";
2323 import { hiddenToastActionProps, stackedThreadToast, toastManager } from "./ui/toast";
@@ -31,7 +31,6 @@ type ActiveProviderUpdateToast = · 7 unmodified lines
3131 | {
3232 readonly kind: "update";
3333 readonly key: string;
34− readonly toastId: ProviderUpdateToastId;
3534 readonly providerInstanceIds: ReadonlySet<ProviderInstanceId>;
3635 readonly providerCount: number;
3736 };
@@ -57,20 +56,16 @@ function ProviderUpdateToastIcon({ provider }: { provider: ProviderDriverKind }) · 19 unmodified lines
5756 );
5857 }
5958
60−function updateProviderUpdateToast(input: {
61− readonly toastId: ProviderUpdateToastId;
59+function addProviderUpdateToast(input: {
6260 readonly view: ProviderUpdateToastView;
63− readonly openSettings: () => void;
61+ readonly openSettings: (toastId: ProviderUpdateToastId) => void;
6462 }) {
6563 if (input.view.type === "loading" || input.view.type === "success") {
66− toastManager.update(input.toastId, {
64+ return toastManager.add({
6765 type: input.view.type,
6866 title: input.view.title,
6967 description: input.view.description,
7068 timeout: 0,
71− // Base UI merges toast updates and omits `undefined` keys, so `undefined`
72− // would leave the prompt's Update button in place. Replace it with a
73− // defined empty action so the CTA cannot linger while the update runs.
7469 actionProps: hiddenToastActionProps,
7570 data: {
7671 hideCopyButton: true,
@@ -79,11 +74,10 @@ function updateProviderUpdateToast(input: { · 2 unmodified lines
7974 : {}),
8075 },
8176 });
82− return;
8377 }
8478
85− toastManager.update(
86− input.toastId,
79+ let toastId!: ProviderUpdateToastId;
80+ toastId = toastManager.add(
8781 stackedThreadToast({
8882 type: input.view.type,
8983 title: input.view.title,
@@ -91,7 +85,7 @@ function updateProviderUpdateToast(input: { · 1 unmodified line
9185 timeout: 0,
9286 actionProps: {
9387 children: "Settings",
94− onClick: input.openSettings,
88+ onClick: () => input.openSettings(toastId),
9589 },
9690 actionVariant: "outline",
9791 data: {
@@ -99,10 +93,7 @@ function updateProviderUpdateToast(input: { · 1 unmodified line
9993 },
10094 }),
10195 );
102−}
103−
104−function isTerminalProviderUpdateToastView(view: ProviderUpdateToastView) {
105− return view.phase === "failed" || view.phase === "unchanged" || view.phase === "succeeded";
96+ return toastId;
10697 }
10798
10899 /**
@@ -126,10 +117,10 @@ export function ProviderUpdatePrimaryNotification() { · 17 unmodified lines
126117 useEffect(() => {
127118 return () => {
128119 const activeToast = activeToastRef.current;
129− if (activeToast) {
120+ if (activeToast?.kind === "prompt") {
130121 toastManager.close(activeToast.toastId);
131− activeToastRef.current = null;
132122 }
123+ activeToastRef.current = null;
133124 };
134125 }, []);
135126
@@ -149,10 +140,14 @@ export function ProviderUpdatePrimaryNotification() { · 13 unmodified lines
149140 const activeToast = activeToastRef.current;
150141 if (toastId !== undefined) {
151142 toastManager.close(toastId);
152− } else if (activeToast) {
143+ } else if (activeToast?.kind === "prompt") {
153144 toastManager.close(activeToast.toastId);
154145 }
155− if (activeToast && (toastId === undefined || activeToast.toastId === toastId)) {
146+ if (
147+ activeToast &&
148+ (toastId === undefined ||
149+ (activeToast.kind === "prompt" && activeToast.toastId === toastId))
150+ ) {
156151 activeToastRef.current = null;
157152 }
158153 void navigate({ to: "/settings/providers" });
@@ -173,15 +168,12 @@ export function ProviderUpdatePrimaryNotification() { · 14 unmodified lines
173168 providers: activeProviders,
174169 providerCount: activeToast.providerCount,
175170 });
176− updateProviderUpdateToast({
177− toastId: activeToast.toastId,
178− view,
179− openSettings: () => openProviderSettings(activeToast.toastId),
180− });
181−
182− if (isTerminalProviderUpdateToastView(view)) {
183− activeToastRef.current = null;
171+ if (!shouldShowPrimaryProviderUpdateToast(view)) {
172+ return;
184173 }
174+
175+ addProviderUpdateToast({ view, openSettings: openProviderSettings });
176+ activeToastRef.current = null;
185177 }, [providers, openProviderSettings]);
186178
187179 useEffect(() => {
@@ -219,19 +211,15 @@ export function ProviderUpdatePrimaryNotification() { · 31 unmodified lines
219211
220212 const providerCount = oneClickProviders.length;
221213 const providerInstanceIds = new Set(oneClickProviders.map((provider) => provider.instanceId));
222− activeToastRef.current = {
214+ const activeUpdate: ActiveProviderUpdateToast = {
223215 kind: "update",
224216 key: notificationKey,
225− toastId,
226217 providerInstanceIds,
227218 providerCount,
228219 };
220+ activeToastRef.current = activeUpdate;
229221
230− updateProviderUpdateToast({
231− toastId,
232− view: getProviderUpdateRunningToastView(providerCount),
233− openSettings,
234− });
222+ toastManager.close(toastId);
235223
236224 void (async () => {
237225 const results = [];
@@ -248,16 +236,15 @@ export function ProviderUpdatePrimaryNotification() { · 10 unmodified lines
248236 }
249237
250238 const activeUpdateToast = activeToastRef.current;
251− if (activeUpdateToast?.kind !== "update" || activeUpdateToast.toastId !== toastId) {
239+ if (activeUpdateToast !== activeUpdate) {
252240 return;
253241 }
254242
255243 const failedMessage = firstFailedProviderUpdateMessage(results);
256244 if (failedMessage) {
257− updateProviderUpdateToast({
258− toastId,
245+ addProviderUpdateToast({
259246 view: getProviderUpdateRejectedToastView(providerCount, failedMessage),
260− openSettings,
247+ openSettings: openProviderSettings,
261248 });
262249 activeToastRef.current = null;
263250 return;
@@ -271,13 +258,8 @@ export function ProviderUpdatePrimaryNotification() { · 7 unmodified lines
271258 providers: updatedProviderSnapshots,
272259 providerCount,
273260 });
274− updateProviderUpdateToast({
275− toastId,
276− view,
277− openSettings,
278− });
279−
280− if (isTerminalProviderUpdateToastView(view)) {
261+ if (shouldShowPrimaryProviderUpdateToast(view)) {
262+ addProviderUpdateToast({ view, openSettings: openProviderSettings });
281263 activeToastRef.current = null;
282264 }
283265 })();

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t