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: popover to configure editor #62452
Conversation
Update: Since the comment below, I reworked the code to use svelte stores which makes this look nicer. It could still need some improvement, but I'm happier with the code now. The current setup works, but I'm not very happy with it. The main problem is that So to get the lastID when starting out (to make sure that the user's settings haven't been modified in another tab or so), we need to get the lastID that was present when the user open the popover. The lastID changes when we make an edit call, so we have to request it again in between. I'm hoping there's another way to make this work nicely, but couldn't find one yet. Maybe there's a better Svelte-style approach? |
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 left a couple of comments inline. This might be a tricky one because I assume you just want to get this "done", but at the same time its introducing new behavior (updating user settings) for which it makes sense to have a reasonable API, instead of just doing it "ad hoc". Let me know what you think!
client/web-sveltekit/src/lib/repo/open-in-editor/OpenInEditor.svelte
Outdated
Show resolved
Hide resolved
settings, | ||
subjects, |
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 was hoping we can get away without having to expose individual subjects, but I guess not. However, if we have to expose both then I think we should expose viewerSettings
directly (subjects
by itself isn't very descriptive). That would require updating all places where we access data.settings
of course (of which there seem only two atm).
$: start = position ?? range?.start | ||
|
||
$: lastId = writable<number>(subjects.at(-1)?.latestSettings?.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.
I don't know whether we can assume that the last subject is the user one. Looking at the React code, they are extracting the subject with type 'user' which seems safer.
updateEditor: async (subject: string, lastID: number, edit: SettingsEdit) => { | ||
const mutationResult1 = await client.mutation( | ||
EditSettings, | ||
{ | ||
lastID, | ||
subject, | ||
edit, | ||
}, | ||
{ requestPolicy: 'network-only', fetch } | ||
) | ||
if (!mutationResult1.data || mutationResult1.error) { | ||
throw new Error(`Failed to update editor path: ${mutationResult1.error}`) | ||
} | ||
const settingsResult = await client.query(LatestSettingsQuery, {}) | ||
if (!settingsResult.data || settingsResult.error) { | ||
throw new Error(`Failed to fetch latest settings during editor update: ${settingsResult.error}`) | ||
} | ||
const newLastId = settingsResult.data.viewerSettings.subjects.at(-1)?.latestSettings?.id | ||
if (!newLastId) { | ||
throw new Error('Failed to get new last ID from settings result') | ||
} | ||
return newLastId | ||
}, |
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 function is called updateEditor
but it seems possible to update arbitrary settings with this function.
I'd suggest to create a generic updateSettings
function in the root layout data loader.
Looking at the React version it also seems they are retrying the mutation when there was a version error, so the "current" settings ID doesn't seem necessary. Relevant code: https://sourcegraph.sourcegraph.com/github.com/sourcegraph/sourcegraph@cb03009ca0fb1c504f3903bf48e7f5531b6d1cb4/-/blob/client/web/src/platform/context.ts?L51-85
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.
If I can just refresh the IDs it makes things a lot easier! I'll push a new version where I was able to remove a lot of code, and pull the lastID before sending a request.
$: handleEditorUpdate = async (): Promise<void> => { | ||
if (!$selectedEditorId || !$defaultProjectPath) { | ||
return; | ||
} | ||
isSaving = true; | ||
const newLastId1 = await updateEditor($subjectId, $lastId, { | ||
value: $defaultProjectPath, | ||
keyPath: [{property: 'openInEditor'}, {property: 'projectPaths.default'}], | ||
}); | ||
lastId.set(newLastId1); | ||
const newLastId2 = await updateEditor($subjectId, $lastId, { | ||
value: [$selectedEditorId], | ||
keyPath: [{property: 'openInEditor'}, {property: 'editorIds'}], | ||
}); | ||
lastId.set(newLastId2); | ||
isSaving = false; | ||
|
||
openInEditor = { | ||
editorIds: [$selectedEditorId], | ||
'projectPaths.default': $defaultProjectPath, | ||
} | ||
} |
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 think it would make sense to abstract some of details of updating settings. E.g. we could provide an API that actually takes an arbitrary number of fields so that the details of the lastId stuff is hidden.
For reference, here is the React version: https://sourcegraph.sourcegraph.com/github.com/sourcegraph/sourcegraph@cb03009ca0fb1c504f3903bf48e7f5531b6d1cb4/-/blob/client/web/src/open-in-editor/OpenInEditorActionItem.tsx?L80-95
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 pushed a new version that hides the lastID.
I'm happy to take the hard route. This was my attempt to get something done, so that we can iterate together on making it nice :) |
…svelte Co-authored-by: Felix Kling <felix@felix-kling.de>
(Notifying @sourcegraph/source of a change that affects gitserver) |
eede6e6
to
565e790
Compare
@fkling I've done another pass, and it looks much cleaner now. The main change was to drop the initial subjects fetch, assuming that we can fetch the lastID before submitting the SettingsEdit. I'm happy to merge this if you agree. |
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.
lgtm, just some nits inside.
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
…svelte Co-authored-by: Felix Kling <felix@felix-kling.de>
Closes #62292
This PR introduces a new popover to configure the editor.
I had to extend the initial settings to get the current settings, introduce new methods to update settings, and handle the two-step update (because each SettingsEdit can only modify one field). With this solution we get the same look-and-feel like the React app, and the editor icon updates without a page reload.There's a new
updateUserSetting
on the root layout, with which this change and other features can update user settings. It fetches thelastID
before writing a change, which means it will force the given setting and won't recheck if something changed.Screen.Recording.2024-05-14.at.13.52.10.mov
Test plan
Manual testing, see video above