-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
feat: add button to open a file in the editor for the webapp rewrite #61782
Conversation
client/web-sveltekit/src/lib/repo/open-in-editor/EditorIcon.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/editor-settings.ts
Outdated
Show resolved
Hide resolved
...t/web-sveltekit/src/routes/[...repo=reporev]/(validrev)/(code)/-/blob/[...path]/+page.svelte
Show resolved
Hide resolved
I won't have time to give this a thorough review today, so just a couple of high level points:
|
client/web-sveltekit/src/lib/repo/open-in-editor/EditorIcon.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/EditorIcon.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/routes/[...repo=reporev]/(validrev)/(code)/-/blob/[...path]/+page.ts
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
...t/web-sveltekit/src/routes/[...repo=reporev]/(validrev)/(code)/-/blob/[...path]/+page.svelte
Show resolved
Hide resolved
Co-authored-by: Camden Cheek <camden@ccheek.com>
Co-authored-by: Camden Cheek <camden@ccheek.com>
client/web-sveltekit/src/lib/repo/open-in-editor/EditorIcon.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/EditorIcon.svelte
Outdated
Show resolved
Hide resolved
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
</script> | ||
|
||
{#if editors} | ||
{#each editors as e, i} |
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.
editor
instead of e
would be more readable (no Go conventions here ;) )
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.
:D
import {SourcegraphURL} from '$lib/common'; | ||
import {page} from '$app/stores'; | ||
|
||
export let externalServiceType: string = '' |
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.
Does this have to be a string? I think we have GraphQL types for those, or not?
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.
Nope, I'm adding the type from GraphQL 👍
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 can still use the function from client/web/
. If you are concerned about the link to /users/settings
: Clicking it will simply load the React app, so that's not a problem.
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.
My main issue was with the markdown that the client/web function produces. We don't have markdown rendering in our tooltips, so it looked a bit ugly. When I added markdown support, I noticed that the styling of the tooltip got a bit wonky and more importantly I noticed that the Tooltip doesn't stay open when I hover from the button to the tooltip, rendering its link useless. Instead of digging deeper here, I thought it's a cleaner solution to give the button the href action.
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.
Ah, got it. Yes, the tooltip really is a tooltip that doesn't expect to have any interactive contents inside... 🤔 You could use a popover as alternative maybe? Like we use for the experimental
badge.
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 gave the Popover component a quick spin, and it looks like I'd have to do a significant amount of CSS to align the look and feel to the other actions. In favor of consistent behavior I would stick with the current version of the Tooltip. It may also feel odd that some tooltips of the actions would close on hover and others don't. If you don't have a strong opinion here I would keep the current approach.
In the ticket I noted that I'd scope out the dialog about setting up the editor. That may be a good place to revisit the Popover approach.
Screen.Recording.2024-04-15.at.14.27.48.mov
client/web-sveltekit/src/routes/[...repo=reporev]/(validrev)/(code)/-/blob/[...path]/page.gql
Outdated
Show resolved
Hide resolved
target="_blank" | ||
rel="noopener noreferrer" | ||
> | ||
<EditorIcon editorId={e.id} /> |
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.
Forgot this earlier: We should somehow fallback to a default icon if we don't have one for the configured editor, otherwise nothing will be displayed when the actions are in "compact" mode.
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.
Looking at fallbacks and error handling I feel like a script based approach is the way to go. Here's what I came up with:
<script lang="ts">
import type {Editor} from '$lib/web'
import DefaultEditorIcon from './DefaultEditorIcon.svelte';
import type {SvelteComponent} from 'svelte';
export let editorId: Editor['id']
let Icon: typeof SvelteComponent | typeof DefaultEditorIcon;
$: import(`./editors/${editorId}.svelte`)
.then(i => Icon = i.default)
.catch((err) => {
console.error(err);
Icon = DefaultEditorIcon
})
</script>
If we were to do it in the component body, it would look something like the version below. That version has an error because error
is unhandled, and I don't feel like adding a console.error
(or a telemetry call) into the component body would be the right way to go.
{#await import(`./editors/${editorId}.svelte`) then {default: Icon}}
<Icon />
{:catch error}
<DefaultEditorIcon />
{/await}
What do you think? Is there another way to do this within the Svelte body?
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.
Just having {:catch}
(without variable name) is valid too.
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.
Alternatively, we do have a list of known editor IDs, right? We could test against that list before we try to fetch the icon. Maybe we could even generate that list from the list of files at build time.
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.
Just having {:catch} (without variable name) is valid too.
My IDE was complaining that this was invalid syntax, but I see that svelte check doesn't complain. I'm leaning towards the svelte component body approach then.
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 minor comments inside, overall looks good!
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
{:catch error} | ||
<Alert variant="danger"> | ||
Unable to fetch external service type: {error.message} | ||
</Alert> | ||
{/await} |
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 don't think this is necessary though I also acknowledge that it's not obvious why this can't error. If parent
fails to resolves we will likely render an error elsewhere.
Regardless rendering the alert here probably doesn't look good either way. As a precaution we could instead catch any error in the loader and log it in the console (see below).
Eventually we will collect such errors with sentry (I think).
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.
Applied your suggestion so that we get those errors through sentry. That means I can reduce this part to just an await ... then ...
and an inner if
. Looks clean to me.
client/web-sveltekit/src/routes/[...repo=reporev]/(validrev)/(code)/-/blob/[...path]/+page.ts
Outdated
Show resolved
Hide resolved
@@ -102,6 +103,15 @@ | |||
<FileHeader> | |||
<FileIcon slot="icon" file={blob} inline /> | |||
<svelte:fragment slot="actions"> | |||
{#await data.externalServiceType} | |||
<OpenInEditor /> |
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.
What would happen if someone clicks the button while the data is not available yet? Can that even happen?
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.
Not applicable anymore after #61782 (comment)
FWIW, here is an example of how images can be used by importing as "URL"s. That would also be an acceptable approach instead of converting them all to Svelte files, especially if you can use the existing files. |
…svelte Co-authored-by: Felix Kling <felix@felix-kling.de>
…code)/-/blob/[...path]/+page.ts Co-authored-by: Felix Kling <felix@felix-kling.de>
That's a nice approach! However, since we're rebuilding the blob page (and the old OpenInEditorAction is only used there), I'm pushing for duplicating the images so we can later more easily remove the old ones. As far as I see the editor images are not used anywhere else. This keeps cross-client dependencies lower. |
Thank you for the tests! |
For #61629
This is the first iteration of a button to open the currently viewed file in your IDE. I reduced the scope of this task, and will follow up with more PRs. See #61629 (comment).
How it looks when you've configured an editor:
How it looks when you did not configure an editor:
Some utility files and icons have been copied from the old webapp.
Test plan
My plan is to get feedback on this work, review the scoping and what is important to implement now, and then write tests depending on how much coverage we need. There are no automated tests (beyond what was copied) yet, but it manual testing was good.