-
Notifications
You must be signed in to change notification settings - Fork 168
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework reconnect logic, add "Port could not be opened" modal #1513
Conversation
f79588c
to
f68639f
Compare
202b490
to
2648fde
Compare
src/application/App.tsx
Outdated
onClose={() => send({ type: "closeModal" })} | ||
onRetry={() => send({ type: "retry" })} | ||
/> | ||
<Modals /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All modals live in that file now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we name this something like ErrorModals
? Ideally we have some namespace that describes that these are the modals opened when the clients can't connect in some way.
Otherwise it looks a little bit weird to have SettingsModal
right next to Modals
😂.
<BannerAlert /> | ||
<Tabs | ||
value={selected} | ||
onChange={(screen) => currentScreen(screen)} | ||
className="flex flex-col h-screen bg-primary dark:bg-primary-dark" | ||
> | ||
<div className="flex items-center border-b border-b-primary dark:border-b-primary-dark gap-4 px-4"> | ||
<a | ||
<ExternalLink |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<a
tags in VSCode cannot open new windows, so I need a component for that. The base implementation really just renders an a
tag, and we have a .vscode.tsx
version of that.
@@ -21,7 +22,7 @@ export const SECTIONS = { | |||
<!-- Please provide the version of \`@apollo/client\` you are using. --> | |||
`, | |||
devtoolsVersion: `### Apollo Client Devtools version | |||
${VERSION} | |||
${VERSION} (${__IS_FIREFOX__ ? "Firefox" : __IS_VSCODE__ ? "VSCode" : "Chrome"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some additional info can be very helpful here to distinguish the different builds in bug reports.
@@ -18,15 +18,17 @@ interface ModalProps { | |||
className?: string; | |||
children: ReactNode; | |||
open: boolean; | |||
onClose: (value: boolean) => void; | |||
onClose?: (value: boolean) => void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making onClose
optional since most of our modals cannot be closed.
open: boolean; | ||
onClose: () => void; | ||
onRetry: () => void; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This modal cannot be closed anymore - before, closing it would leave the user with a somewhat defunct UI, so it never made much sense to me. Going this step massively simplifies logic.
invoke: { | ||
id: "reconnect", | ||
src: "reconnect", | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This invokes the child machine while in this state and stops it as soon as this state is left.
}, | ||
}, | ||
}); | ||
|
||
export const DevToolsMachineContext = createContext<DevToolsActor | null>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We now use Context to pass this down into the React app - but not the createContext
from xState, as that would create the actor from the machine and we want to create the actor outside of React (the Actor renders React).
"reconnect.retry": "retrying", | ||
}, | ||
entry: ["notifyNotFound"], | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, this also had a timedout
state, but we never triggered it from anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm glad you got rid of it. It was a relic from the days before we had the client send a register event. Devtools used to ping the content scripts, so the timedout
event was used if devtools couldn't communicate with the content scripts anymore, but that is largely a thing of the past.
}, | ||
}, | ||
}, | ||
notFound: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The modal is now shown while the machine is in this state. If we wanted to show the modal in more states that just one, we could look into tag
.
export const reconnectMachine = setup({ | ||
delays: { connectTimeout: 500 }, | ||
}).createMachine({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In VSCode, we want to show this from the start, as it has valuable information.
We will wait for a very short amount of time though, in case something immediately connects - that way we avoid flickering of the modal.
f68639f
to
961a1ae
Compare
405da4b
to
6975f63
Compare
commit: |
HTMLAnchorElement, | ||
ComponentProps<"a"> & { href: string } | ||
>((props, ref) => { | ||
return <a {...props} ref={ref} />; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are moving to this, let's add target="_blank" rel="noopener noreferrer"
as props here as well since external links on the web side don't open unless they are in a new tab.
target="_blank" | ||
rel="noreferrer" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
target="_blank" | |
rel="noreferrer" |
Can we remove these props once the browser ExternalLink
is updated to add these props directly?
10ac491
to
0550206
Compare
#1061 Bundle Size — 1.63MiB (+0.68%).06c817b(current) vs 31394f0 main#1051(baseline) Warning Bundle contains 13 duplicate packages – View duplicate packages Bundle metrics
|
Current #1061 |
Baseline #1051 |
|
---|---|---|
Initial JS | 1.49MiB (+0.19% ) |
1.49MiB |
Initial CSS | 0B |
0B |
Cache Invalidation | 88.78% |
0% |
Chunks | 5 |
5 |
Assets | 157 (+6.8% ) |
147 |
Modules | 1228 (+0.33% ) |
1224 |
Duplicate Modules | 45 |
45 |
Duplicate Code | 3.12% |
3.12% |
Packages | 183 |
183 |
Duplicate Packages | 10 |
10 |
Bundle size by type 2 changes
2 regressions
Current #1061 |
Baseline #1051 |
|
---|---|---|
JS | 1.49MiB (+0.19% ) |
1.49MiB |
Other | 100.55KiB (+8.92% ) |
92.32KiB |
IMG | 35.85KiB |
35.85KiB |
HTML | 857B |
857B |
Bundle analysis report Branch pr/port-info Project dashboard
Generated by RelativeCI Documentation Report issue
Okay, I went over that - re-review please :) |
actions: sendTo("reconnect", ({ event }) => event), | ||
}, | ||
// on an `emit.*` event, `emit` that event so it can be subscribed to from the app | ||
"emit.*": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about this one. I searched the changes for anything that listens to these emitted events, but I didn't see anything. Am I missing something obvious?
If not used, I'm curious do you still want to keep the emitted events?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before https://github.com/apollographql/apollo-client-devtools/pull/1536/files, this would allow us to call refetch
as a reaction to that event.
It's not like we need this anymore right now, but it is a good blueprint we can build on if we need something like this in the future, and it doesn't hurt, so I'd keep it in for now.
const StartCommandLabel = "Apollo: Start Apollo Client DevTools Server"; | ||
const StartCommand = "apollographql/startDevToolsServer"; | ||
const StopCommandLabel = "Apollo: Stop Apollo Client DevTools Server"; | ||
const PortSetting = "apollographql.devTools.serverPort"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind switching these either to SCREAMING_SNAKE_CASE or camelCase? We don't use PascalCase for anything but components, classes or types so would be great to keep this consistent 🙂.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4679bd9 ✅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I go back on forth on the VSCode
folder. While I agree that it does convey its meant for VSCode
, we've been using the .vscode
extension here for that. I tend to prefer that since it remains consistent for every vscode component.
If you make this change, perhaps in the file its imported, you just import with the .vscode
extension so you don't have to create a browser version?
// PortNotOpenModal.tsx
import { VSCodeCommandButton } from './VSCodeCommandButton.vscode';
import { Button, type ButtonProps } from "../Button"; | ||
import { forwardRef } from "react"; | ||
|
||
export const VSCodeCommandButton = forwardRef< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now we really gotta update to React 19 😆
{StartCommandLabel} | ||
</VSCodeCommandButton> | ||
<VSCodeSettingButton settingsKey={PortSetting}> | ||
Open Settings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open Settings | |
Open settings |
Studio uses sentence case for everything, so we should do the same here 🙂
<Button | ||
variant="primary" | ||
size="sm" | ||
icon={<IconRun />} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getPanelActor(window).send({ | ||
type: "vscode:executeCommand", | ||
command: "workbench.action.openSettings", | ||
arguments: [settingsKey], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we use args
as the key here? I know this is technically fine, but makes it easier to distinguish that its not arguments
available inside a function when looking at it from a glance. I think this was used on the vscode side?
"reconnect.retry": "retrying", | ||
}, | ||
entry: ["notifyNotFound"], | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm glad you got rid of it. It was a relic from the days before we had the client send a register event. Devtools used to ping the content scripts, so the timedout
event was used if devtools couldn't communicate with the content scripts anymore, but that is largely a thing of the past.
src/application/App.tsx
Outdated
onClose={() => send({ type: "closeModal" })} | ||
onRetry={() => send({ type: "retry" })} | ||
/> | ||
<Modals /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we name this something like ErrorModals
? Ideally we have some namespace that describes that these are the modals opened when the clients can't connect in some way.
Otherwise it looks a little bit weird to have SettingsModal
right next to Modals
😂.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went over this in person.
Only feedback I have left is to rename that Modals
folder (#1513 (comment)), but I'll trust you'll do that.
Looking forward to getting this out!
* Adjustments to VSCode <-> DevTools communication adjustments for apollographql/apollo-client-devtools#1513 * use CI devtools build * feedback from code review * second adjustment * adjust CI to GH runner changes
Also see the accompanying apollographql/vscode-graphql#197