Skip to content

Commit

Permalink
Option to preserve main query params on route change
Browse files Browse the repository at this point in the history
  • Loading branch information
stanleychh authored Nov 16, 2021
1 parent d94943a commit ae109d4
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 8 deletions.
10 changes: 10 additions & 0 deletions client/luigi-client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,16 @@ export declare interface LinkManager {
* LuigiClient.linkManager().newTab().navigate('/projects/xy/foobar');
*/
newTab: () => this;

/**
* Keeps the URL's query parameters for a navigation request.
* @param {boolean} preserve By default, it is set to `false`. If it is set to `true`, the URL's query parameters will be kept after navigation.
* @since NEXT_RELEASE
* @example
* LuigiClient.linkManager().preserveQueryParams(true).navigate('/projects/xy/foobar');
* LuigiClient.linkManager().preserveQueryParams(false).navigate('/projects/xy/foobar');
*/
preserveQueryParams: (preserve: boolean) => this;
}

export declare interface StorageManager {
Expand Down
16 changes: 15 additions & 1 deletion client/src/linkManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export class linkManager extends LuigiClientBase {
fromParent: false,
relative: false,
link: '',
newTab: false
newTab: false,
preserveQueryParams: false
};
}

Expand Down Expand Up @@ -375,4 +376,17 @@ export class linkManager extends LuigiClientBase {
this.options.newTab = true;
return this;
}

/**
* Keeps the URL's query parameters for a navigation request.
* @param {boolean} preserve By default, it is set to `false`. If it is set to `true`, the URL's query parameters will be kept after navigation.
* @since NEXT_RELEASE
* @example
* LuigiClient.linkManager().preserveQueryParams(true).navigate('/projects/xy/foobar');
* LuigiClient.linkManager().preserveQueryParams(false).navigate('/projects/xy/foobar');
*/
preserveQueryParams(preserve = false) {
this.options.preserveQueryParams = preserve;
return this;
}
}
4 changes: 3 additions & 1 deletion core/src/App.html
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,9 @@
let path = buildPath(data.params, srcNode, srcPathParams);

path = GenericHelpers.addLeadingSlash(path);

path = data.params.preserveQueryParams
? RoutingHelpers.composeSearchParamsToRoute(path)
: path;
addPreserveView(data, config);

// Navigate to the raw path. Any errors/alerts are handled later.
Expand Down
4 changes: 3 additions & 1 deletion core/src/services/routing.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Please consider adding any new methods to 'routing-helpers' if they don't require anything from this file.
import { Navigation } from '../navigation/services/navigation';
import { GenericHelpers, IframeHelpers, NavigationHelpers, RoutingHelpers } from '../utilities/helpers';
import { LuigiConfig, LuigiI18N, LuigiNavigation } from '../core-api';
import { LuigiConfig, LuigiNavigation } from '../core-api';
import { Iframe } from './';
import { NAVIGATION_DEFAULTS } from './../utilities/luigi-config-defaults';
import { NodeDataManagementStorage } from './node-data-management';
Expand Down Expand Up @@ -57,7 +57,9 @@ class RoutingClass {
return;
}
const hashRouting = LuigiConfig.getConfigValue('routing.useHashRouting');
const preserveQueryParams = LuigiConfig.getConfigValue('routing.preserveQueryParams');
let url = new URL(location.href);
route = preserveQueryParams ? RoutingHelpers.composeSearchParamsToRoute(route) : route;
hashRouting ? (url.hash = route) : (url.pathname = route);

const chosenHistoryMethod = pushState ? 'pushState' : 'replaceState';
Expand Down
14 changes: 14 additions & 0 deletions core/src/utilities/helpers/routing-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,20 @@ class RoutingHelpersClass {
return location.search ? RoutingHelpers.parseParams(location.search.slice(1)) : {};
}

/**
* Append search query parameters to the route
@param route string absolute path of the new route
@returns resulting route with or without appended params, for example /someroute?query=test
*/
composeSearchParamsToRoute(route) {
const hashRoutingActive = LuigiConfig.getConfigBooleanValue('routing.useHashRouting');
if (hashRoutingActive) {
const queryParamIndex = location.hash.indexOf(this.defaultQueryParamSeparator);
return queryParamIndex !== -1 ? route + location.hash.slice(queryParamIndex) : route;
}
return location.search ? route + location.search : route;
}

getModalPathFromPath() {
const path = this.getQueryParam(this.getModalViewParamName());
return path && decodeURIComponent(path);
Expand Down
29 changes: 29 additions & 0 deletions core/test/utilities/helpers/routing-helpers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -821,4 +821,33 @@ describe('Routing-helpers', () => {
assert.equal(undefined, expected);
});
});

describe('composeSearchParamsToRoute', () => {
let globalLocationRef = global.location;
const route = '/home';

afterEach(() => {
global.location = globalLocationRef;
});

it('with location search params', () => {
global.location = {
search: '?query=params'
};
const actual = RoutingHelpers.composeSearchParamsToRoute(route);
const expected = '/home?query=params';

assert.equal(actual, expected);
});

it('without location search params', () => {
global.location = {
search: ''
};
const actual = RoutingHelpers.composeSearchParamsToRoute(route);
const expected = '/home';

assert.equal(actual, expected);
});
});
});
19 changes: 19 additions & 0 deletions docs/luigi-client-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,25 @@ LuigiClient.linkManager().newTab().navigate('/projects/xy/foobar');

- **since**: NEXT_RELEASE

#### preserveQueryParams

Keeps url's query parameters for a navigation request.

##### Parameters

- `preserve` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** By default, it is set to `false`. If it is set to `true` the url's query parameters will be kept after navigation. (optional, default `false`)

##### Examples

```javascript
LuigiClient.linkManager().preserveQueryParams(true).navigate('/projects/xy/foobar');
LuigiClient.linkManager().preserveQueryParams(false).navigate('/projects/xy/foobar');
```

**Meta**

- **since**: NEXT_RELEASE

#### navigate

Navigates to the given path in the application hosted by Luigi. It contains either a full absolute path or a relative path without a leading slash that uses the active route as a base. This is the standard navigation.
Expand Down
4 changes: 0 additions & 4 deletions docs/luigi-core-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -884,10 +884,6 @@ Returns **[promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/

- **since**: 0.6.4

<!-- add-attribute:class:warning -->

> **NOTE:** You can also define a [customAlertHandler](general-settings.md#general-parameters) function to implement custom alerts.
#### showConfirmationModal

Shows a confirmation modal.
Expand Down
5 changes: 5 additions & 0 deletions docs/navigation-parameters-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ You can configure the way Luigi tackles routing in your application in the `rout
- **description**: defines either hash-based (`example.com/#/yourpath`) or path-based (`example.com/yourpath`) routing.
- **default**: the default is `false`, which means path routing is used.

### preserveQueryParams
- **type**: boolean
- **description**: defines if query parameters are persisted in the URL after path changes.
- **default**: the default is `false`, which means query parameters are not persisted in the URL after navigation request.

## Navigation parameters
The navigation parameters allow you to configure **global** navigation settings directly under the `navigation:` section in the configuration file.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -562,4 +562,32 @@ describe('Luigi client linkManager', () => {
});
});
});

describe('linkManager preserveQueryParams features', () => {
let $iframeBody;
beforeEach(() => {
// "clear" variables to make sure they are not reused and throw error in case something goes wrong
$iframeBody = undefined;
cy.visitLoggedIn('/projects/pr1/settings?query=test&ft=ft1');
cy.getIframeBody().then(result => {
$iframeBody = result;
});
});

it('Naviage to pr2 with query parameters', () => {
cy.wrap($iframeBody)
.contains('navigate to project 2 with query parameters')
.click();
cy.expectPathToBe('/projects/pr2');
cy.expectSearchToBe('?query=test&ft=ft1');
});

it('Naviage to pr2 without query parameters', () => {
cy.wrap($iframeBody)
.contains('navigate to project 2 without query parameters')
.click();
cy.expectPathToBe('/projects/pr2');
cy.expectSearchToBe('');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,40 @@ <h3 class="fd-layout-panel__title">Navigate</h3>
>
</app-code-snippet>
</li>
<li class="fd-list__item">
<a
href="javascript:void(0)"
class="fd-link"
(click)="
linkManager()
.preserveQueryParams(true)
.navigate('/projects/pr2')
"
>
navigate to project 2 with query parameters</a
>
<app-code-snippet
data="linkManager().preserveQueryParams(true).navigate('/projects/pr2')"
>
</app-code-snippet>
</li>
<li class="fd-list__item">
<a
href="javascript:void(0)"
class="fd-link"
(click)="
linkManager()
.preserveQueryParams(false)
.navigate('/projects/pr2')
"
>
navigate to project 2 without query parameters</a
>
<app-code-snippet
data="linkManager().preserveQueryParams(false).navigate('/projects/pr2')"
>
</app-code-snippet>
</li>
</ul>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ class Routing {
* For path routing, set to false and run `npm run start`
*/
useHashRouting = false;

/**
* preserveQueryParams
* Default: false. Set to true to preserve the query parameters of the URL after navigation request.
*/
preserveQueryParams = false;
/**
* Prefix for reflecting params in the url, which is used when navigating .withParams() function.
*/
Expand Down

0 comments on commit ae109d4

Please sign in to comment.