Skip to content

Commit a7ee12d

Browse files
feat: enable basename for multi cluster version
1 parent 24a34f8 commit a7ee12d

File tree

7 files changed

+59
-23
lines changed

7 files changed

+59
-23
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"build": "rm -rf build && DISABLE_ESLINT_PLUGIN=true CI=true react-app-rewired build",
7070
"//build:embedded": "echo 'PUBLIC_URL is a setting for create-react-app. Embedded version is built and hosted as is on ydb servers, with no way of knowing the final URL pattern. PUBLIC_URL=. keeps paths to all static relative, allowing servers to handle them as needed'",
7171
"build:embedded": "GENERATE_SOURCEMAP=false PUBLIC_URL=. REACT_APP_BACKEND=http://localhost:8765 REACT_APP_META_BACKEND=undefined npm run build",
72+
"build:embedded-mc": "GENERATE_SOURCEMAP=false PUBLIC_URL=. REACT_APP_BACKEND= REACT_APP_META_BACKEND= npm run build",
7273
"build:embedded:archive": "npm run build:embedded && mv build embedded-ui && cp CHANGELOG.md embedded-ui/CHANGELOG.md && zip -r embedded-ui.zip embedded-ui && rm -rf embedded-ui",
7374
"lint": "run-p lint:*",
7475
"lint:js": "eslint --ext .js,.jsx,.ts,.tsx .",

src/components/TenantNameWrapper/TenantNameWrapper.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,13 @@ export function TenantNameWrapper({tenant, additionalTenantsProps}: TenantNameWr
6767
status={tenant.Overall}
6868
infoPopoverContent={infoPopoverContent}
6969
hasClipboardButton
70-
path={getTenantPath({
71-
database: tenant.Name,
72-
backend,
73-
})}
70+
path={getTenantPath(
71+
{
72+
database: tenant.Name,
73+
backend,
74+
},
75+
{withBasename: isExternalLink},
76+
)}
7477
/>
7578
);
7679
}

src/containers/Cluster/utils.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {CreateHrefOptions} from '../../routes';
12
import routes, {createHref} from '../../routes';
23
import type {ValueOf} from '../../types/common';
34

@@ -44,6 +45,6 @@ export function isClusterTab(tab: any): tab is ClusterTab {
4445
return Object.values(clusterTabsIds).includes(tab);
4546
}
4647

47-
export const getClusterPath = (activeTab?: ClusterTab, query = {}) => {
48-
return createHref(routes.cluster, activeTab ? {activeTab} : undefined, query);
48+
export const getClusterPath = (activeTab?: ClusterTab, query = {}, options?: CreateHrefOptions) => {
49+
return createHref(routes.cluster, activeTab ? {activeTab} : undefined, query, options);
4950
};

src/containers/Clusters/columns.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const CLUSTERS_COLUMNS: Column<PreparedCluster>[] = [
3636
const clusterPath =
3737
useEmbeddedUi && backend
3838
? createDeveloperUIMonitoringPageHref(backend)
39-
: getClusterPath(undefined, {backend, clusterName});
39+
: getClusterPath(undefined, {backend, clusterName}, {withBasename: true});
4040

4141
const clusterStatus = row.cluster?.Overall;
4242

@@ -110,7 +110,11 @@ export const CLUSTERS_COLUMNS: Column<PreparedCluster>[] = [
110110
preparedVersions.length > 0 && (
111111
<ExternalLink
112112
className={b('cluster-versions')}
113-
href={getClusterPath(clusterTabsIds.versions, {backend, clusterName})}
113+
href={getClusterPath(
114+
clusterTabsIds.versions,
115+
{backend, clusterName},
116+
{withBasename: true},
117+
)}
114118
>
115119
<React.Fragment>
116120
{preparedVersions.map((item, index) => (

src/containers/Tenant/TenantPages.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type {CreateHrefOptions} from '../../routes';
12
import routes, {createHref} from '../../routes';
23
import {TENANT_SUMMARY_TABS_IDS} from '../../store/reducers/tenant/constants';
34
import type {paramSetup} from '../../store/state-url-mapping';
@@ -40,6 +41,6 @@ export const TENANT_SCHEMA_TAB = [
4041
},
4142
];
4243

43-
export const getTenantPath = (query: TenantQuery) => {
44-
return createHref(routes.tenant, undefined, query);
44+
export const getTenantPath = (query: TenantQuery, options?: CreateHrefOptions) => {
45+
return createHref(routes.tenant, undefined, query, options);
4546
};

src/routes.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import qs from 'qs';
55
import type {QueryParamConfig} from 'use-query-params';
66
import {StringParam} from 'use-query-params';
77

8-
import {backend, clusterName, webVersion} from './store';
8+
import {backend, basename, clusterName, webVersion} from './store';
99

1010
export const CLUSTERS = 'clusters';
1111
export const CLUSTER = 'cluster';
@@ -55,10 +55,15 @@ const prepareRoute = (route: string) => {
5555

5656
type Query = AnyRecord;
5757

58+
export interface CreateHrefOptions {
59+
withBasename?: boolean;
60+
}
61+
5862
export function createHref(
5963
route: string,
6064
params?: Record<string, string | number | undefined>,
6165
query: Query = {},
66+
options: CreateHrefOptions = {},
6267
) {
6368
let extendedQuery = query;
6469

@@ -78,7 +83,14 @@ export function createHref(
7883

7984
const preparedRoute = prepareRoute(route);
8085

81-
return `${compile(preparedRoute)(params)}${search}`;
86+
const compiledRoute = `${compile(preparedRoute)(params)}${search}`;
87+
88+
if (options.withBasename) {
89+
// For SPA links react-router adds basename itself
90+
// It is needed for external links - <a> or uikit <Link>
91+
return basename + compiledRoute;
92+
}
93+
return compiledRoute;
8294
}
8395

8496
// embedded version could be located in some folder (e.g. host/some_folder/app_router_path)

src/store/getUrlData.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,41 @@ export const getUrlData = ({
77
singleClusterMode: boolean;
88
customBackend?: string;
99
}) => {
10+
// UI could be located in "monitoring" or "ui" folders
11+
const parsedPrefix = window.location.pathname.match(/.*(?=\/(monitoring|ui)\/)/) || [];
12+
const basenamePrefix = parsedPrefix.length > 0 ? parsedPrefix[0] : '';
13+
const folder = parsedPrefix.length > 1 ? parsedPrefix[1] : '';
14+
15+
let basename = '';
16+
17+
if (basenamePrefix || folder) {
18+
basename = basenamePrefix + '/' + folder;
19+
}
20+
21+
const urlSearchParams = new URL(href).searchParams;
22+
const backend = urlSearchParams.get('backend') ?? undefined;
23+
const clusterName = urlSearchParams.get('clusterName') ?? undefined;
24+
1025
if (!singleClusterMode) {
11-
const urlSearchParams = new URL(href).searchParams;
12-
const backend = urlSearchParams.get('backend') ?? undefined;
13-
const clusterName = urlSearchParams.get('clusterName') ?? undefined;
26+
// Multi-cluster version
27+
// Cluster and backend are determined by url params
1428
return {
15-
basename: '/',
29+
basename,
1630
backend,
1731
clusterName,
1832
};
1933
} else if (customBackend) {
20-
const urlSearchParams = new URL(href).searchParams;
21-
const backend = urlSearchParams.get('backend') ?? undefined;
34+
// Single-cluster version
35+
// UI and backend are on different hosts
36+
// There is a backend url param for requests
2237
return {
23-
basename: '/',
38+
basename,
2439
backend: backend ? backend : customBackend,
2540
};
2641
} else {
27-
const parsedPrefix = window.location.pathname.match(/.*(?=\/monitoring)/) || [];
28-
const basenamePrefix = parsedPrefix.length > 0 ? parsedPrefix[0] : '';
29-
const basename = [basenamePrefix, 'monitoring'].filter(Boolean).join('/');
30-
42+
// Single-cluster version
43+
// UI and backend are located on the same host
44+
// We use the the host for backend requests
3145
return {
3246
basename,
3347
backend: basenamePrefix || '',

0 commit comments

Comments
 (0)