diff --git a/src/lib/pages/start-workflow.svelte b/src/lib/pages/start-workflow.svelte index 2708eac9a..0b8034f79 100644 --- a/src/lib/pages/start-workflow.svelte +++ b/src/lib/pages/start-workflow.svelte @@ -105,6 +105,7 @@ value: workflowId, url: $page.url, allowEmpty: true, + options: { keepFocus: true, noScroll: true, replaceState: true }, }); }; @@ -144,6 +145,7 @@ value, url: $page.url, allowEmpty: true, + options: { keepFocus: true, noScroll: true, replaceState: true }, }); }; diff --git a/src/lib/utilities/update-query-parameters.test.ts b/src/lib/utilities/update-query-parameters.test.ts index 2d68ae33a..bffb168a8 100644 --- a/src/lib/utilities/update-query-parameters.test.ts +++ b/src/lib/utilities/update-query-parameters.test.ts @@ -136,7 +136,23 @@ describe('updateQueryParameters', () => { const [href, options] = goto.mock.calls[0]; - expect(href).toBe('/?other=value¶meter=value'); + expect(href).toBe('/?parameter=value&other=value'); + expect(options).toEqual(gotoOptions); + }); + + it('should call `goto` with the correct path for the updated param and keep order if there are other params', () => { + const parameter = 'parameter'; + const value = 'newValue'; + const url = new URL( + `https://temporal.io/?other1=value1&${parameter}=oldValue&other2=value2`, + ); + const goto = vi.fn().mockImplementation(() => Promise.resolve(null)); + + updateQueryParameters({ parameter, value, url, goto }); + + const [href, options] = goto.mock.calls[0]; + + expect(href).toBe('/?other1=value1¶meter=newValue&other2=value2'); expect(options).toEqual(gotoOptions); }); diff --git a/src/lib/utilities/update-query-parameters.ts b/src/lib/utilities/update-query-parameters.ts index 5d9a84bf2..4d3b47512 100644 --- a/src/lib/utilities/update-query-parameters.ts +++ b/src/lib/utilities/update-query-parameters.ts @@ -9,11 +9,13 @@ type UpdateQueryParams = { goto?: typeof navigateTo; allowEmpty?: boolean; clearParameters?: string[]; + options?: typeof gotoOptions; }; export const gotoOptions = { keepFocus: true, noScroll: true, + replaceState: false, }; export const updateQueryParameters = async ({ @@ -23,19 +25,30 @@ export const updateQueryParameters = async ({ goto = navigateTo, allowEmpty = false, clearParameters = [], + options = gotoOptions, }: UpdateQueryParams): Promise => { const next = String(value); const params = {}; + let replaced = false; + url.searchParams.forEach((value, key) => { if (key !== parameter) { params[key] = value; + } else { + if (next) { + params[key] = next; + replaced = true; + } else if (allowEmpty) { + params[key] = ''; + replaced = true; + } } }); const newQuery = new URLSearchParams(params); - if (value) { + if (value && !replaced) { newQuery.set(parameter, next); - } else if (allowEmpty) { + } else if (allowEmpty && !replaced) { newQuery.set(parameter, ''); } @@ -49,7 +62,7 @@ export const updateQueryParameters = async ({ const query = newQuery?.toString(); const newUrl = query ? `${url.pathname}?${query}` : url.pathname; - goto(newUrl, gotoOptions); + goto(newUrl, options); } return value;