Skip to content

Commit

Permalink
Make url stateful in hash
Browse files Browse the repository at this point in the history
Make url stateful in hash
  • Loading branch information
SuZhou-Joe authored Feb 29, 2024
2 parents 03e4897 + 476812d commit c0ba8d8
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 5 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1028,4 +1028,4 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### 🔩 Tests

- Update caniuse to fix failed integration tests ([#2322](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2322))
- Update caniuse to fix failed integration tests ([#2322](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/2322))
1 change: 1 addition & 0 deletions src/plugins/workspace/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
* SPDX-License-Identifier: Apache-2.0
*/

export const WORKSPACE_ID_STATE_KEY = '_w';
export const WORKSPACE_SAVED_OBJECTS_CLIENT_WRAPPER_ID = 'workspace';
5 changes: 3 additions & 2 deletions src/plugins/workspace/opensearch_dashboards.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
"id": "workspace",
"version": "opensearchDashboards",
"server": true,
"ui": false,
"ui": true,
"requiredPlugins": [
"savedObjects"
"savedObjects",
"opensearchDashboardsUtils"
],
"optionalPlugins": [],
"requiredBundles": []
Expand Down
91 changes: 89 additions & 2 deletions src/plugins/workspace/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,97 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { Plugin } from '../../../core/public';
import { BehaviorSubject, combineLatest } from 'rxjs';
import { debounce } from 'lodash';
import { CoreSetup, Plugin } from '../../../core/public';
import { getStateFromOsdUrl } from '../../opensearch_dashboards_utils/public';
import { formatUrlWithWorkspaceId } from './utils';
import { WORKSPACE_ID_STATE_KEY } from '../common/constants';

export class WorkspacePlugin implements Plugin<{}, {}, {}> {
public async setup() {
private core?: CoreSetup;
private URLChange$ = new BehaviorSubject('');
private getWorkpsaceIdFromURL(): string | null {
return getStateFromOsdUrl(WORKSPACE_ID_STATE_KEY);
}
private async getWorkpsaceId(): Promise<string> {
if (this.getWorkpsaceIdFromURL()) {
return this.getWorkpsaceIdFromURL() || '';
}

return (await this.core?.workspaces.currentWorkspaceId$.getValue()) || '';
}
private getPatchedUrl = (url: string, workspaceId: string) => {
return formatUrlWithWorkspaceId(url, workspaceId);
};
private async listenToHashChange(): Promise<void> {
window.addEventListener('hashchange', async () => {
if (this.shouldPatchUrl()) {
const workspaceId = await this.getWorkpsaceId();
this.URLChange$.next(this.getPatchedUrl(window.location.href, workspaceId));
}
});
}
private shouldPatchUrl(): boolean {
const currentWorkspaceId = this.core?.workspaces.currentWorkspaceId$.getValue();
const workspaceIdFromURL = this.getWorkpsaceIdFromURL();
if (!currentWorkspaceId && !workspaceIdFromURL) {
return false;
}

if (currentWorkspaceId === workspaceIdFromURL) {
return false;
}

return true;
}
private async listenToApplicationChange(): Promise<void> {
const startService = await this.core?.getStartServices();
if (startService) {
combineLatest([
this.core?.workspaces.currentWorkspaceId$,
startService[0].application.currentAppId$,
]).subscribe(async ([]) => {
if (this.shouldPatchUrl()) {
const currentWorkspaceId = await this.getWorkpsaceId();
this.URLChange$.next(this.getPatchedUrl(window.location.href, currentWorkspaceId));
}
});
}
}
public async setup(core: CoreSetup) {
this.core = core;
/**
* Retrive workspace id from url
*/
const workspaceId = this.getWorkpsaceIdFromURL();

if (workspaceId) {
/**
* Enter a workspace
*/
this.core.workspaces.currentWorkspaceId$.next(workspaceId);
}

/**
* listen to application change and patch workspace id in hash
*/
this.listenToApplicationChange();

/**
* listen to application internal hash change and patch workspace id in hash
*/
this.listenToHashChange();

/**
* All the URLChange will flush in this subscriber
*/
this.URLChange$.subscribe(
debounce(async (url) => {
history.replaceState(history.state, '', url);
}, 500)
);

return {};
}

Expand Down
11 changes: 11 additions & 0 deletions src/plugins/workspace/public/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import { setStateToOsdUrl } from '../../opensearch_dashboards_utils/public';
import { WORKSPACE_ID_STATE_KEY } from '../common/constants';

export const formatUrlWithWorkspaceId = (url: string, workspaceId: string) => {
return setStateToOsdUrl(WORKSPACE_ID_STATE_KEY, workspaceId, undefined, url);
};

0 comments on commit c0ba8d8

Please sign in to comment.