Skip to content

Commit d310e59

Browse files
app/vmui: properly show tenant info if AccountID and ProjectID headers are set by proxy
1 parent e9d0d7b commit d310e59

File tree

17 files changed

+246
-156
lines changed

17 files changed

+246
-156
lines changed

app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/TenantsFields.tsx

Lines changed: 119 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,17 @@ import TextField from "../../../Main/TextField/TextField";
1313
import useBoolean from "../../../../hooks/useBoolean";
1414
import useStateSearchParams from "../../../../hooks/useStateSearchParams";
1515
import { useSearchParams } from "react-router-dom";
16+
import { useAppState } from "../../../../state/common/StateContext";
1617

1718
const TenantsFields: FC = () => {
19+
const { tenantId } = useAppState();
1820
const appModeEnable = getAppModeEnable();
1921
const { isMobile } = useDeviceDetect();
2022
const timeDispatch = useTimeDispatch();
2123

2224
const [searchParams, setSearchParams] = useSearchParams();
23-
const [accountID, setAccountID] = useStateSearchParams("0", "accountID");
24-
const [projectID, setProjectID] = useStateSearchParams("0", "projectID");
25+
const [accountID, setAccountID] = useStateSearchParams(tenantId?.accountID || "0", "accountID");
26+
const [projectID, setProjectID] = useStateSearchParams(tenantId?.projectID || "0", "projectID");
2527
const formattedTenant = `${accountID}:${projectID}`;
2628

2729
const buttonRef = useRef<HTMLDivElement>(null);
@@ -41,107 +43,134 @@ const TenantsFields: FC = () => {
4143
};
4244

4345
const handleReset = () => {
44-
setAccountID(searchParams.get("accountID") || "0");
45-
setProjectID(searchParams.get("projectID") || "0");
46+
setAccountID(searchParams.get("accountID") || tenantId?.accountID || "0");
47+
setProjectID(searchParams.get("projectID") || tenantId?.projectID || "0");
4648
};
4749

4850
useEffect(() => {
4951
if (openPopup) return;
5052
handleReset();
5153
}, [openPopup]);
5254

55+
const isTenantStatic = !!(tenantId?.accountID || tenantId?.projectID);
56+
const tooltipMessage = isTenantStatic ? "Static tenant for a current user" : "Define Tenant ID if you need request to another storage";
57+
58+
const getTenantLabel = () => {
59+
return (
60+
<div ref={buttonRef}>
61+
<div
62+
className="vm-mobile-option"
63+
onClick={isTenantStatic ? undefined : toggleOpenPopup}
64+
>
65+
<span className="vm-mobile-option__icon"><StorageIcon/></span>
66+
<div className="vm-mobile-option-text">
67+
{isMobile && (
68+
<span className="vm-mobile-option-text__label">Tenant ID</span>
69+
)}
70+
<span className="vm-mobile-option-text__value">{formattedTenant}</span>
71+
</div>
72+
{!isTenantStatic && (
73+
<span className="vm-mobile-option__arrow"><ArrowDownIcon/></span>
74+
)}
75+
</div>
76+
</div>
77+
);
78+
};
79+
5380
return (
54-
<div className="vm-tenant-input">
55-
<Tooltip title="Define Tenant ID if you need request to another storage">
56-
<div ref={buttonRef}>
57-
{isMobile ? (
58-
<div
59-
className="vm-mobile-option"
60-
onClick={toggleOpenPopup}
61-
>
62-
<span className="vm-mobile-option__icon"><StorageIcon/></span>
63-
<div className="vm-mobile-option-text">
64-
<span className="vm-mobile-option-text__label">Tenant ID</span>
65-
<span className="vm-mobile-option-text__value">{formattedTenant}</span>
66-
</div>
67-
<span className="vm-mobile-option__arrow"><ArrowDownIcon/></span>
68-
</div>
81+
<div
82+
className={classNames({
83+
"vm-tenant-input": true,
84+
"vm-tenant-input_disabled": isTenantStatic,
85+
"vm-tenant-input_mobile": isMobile,
86+
})}
87+
>
88+
{isMobile ? (
89+
getTenantLabel()
90+
) : (
91+
<Tooltip title={tooltipMessage}>
92+
{isTenantStatic ? (
93+
getTenantLabel()
6994
) : (
70-
<Button
71-
className={appModeEnable ? "" : "vm-header-button"}
72-
variant="contained"
73-
color="primary"
74-
fullWidth
75-
startIcon={<StorageIcon/>}
76-
endIcon={(
77-
<div
78-
className={classNames({
79-
"vm-execution-controls-buttons__arrow": true,
80-
"vm-execution-controls-buttons__arrow_open": openPopup,
81-
})}
82-
>
83-
<ArrowDownIcon/>
84-
</div>
85-
)}
86-
onClick={toggleOpenPopup}
87-
>
88-
{formattedTenant}
89-
</Button>
95+
<div ref={buttonRef}>
96+
<Button
97+
className={appModeEnable ? "" : "vm-header-button"}
98+
variant="contained"
99+
color="primary"
100+
fullWidth
101+
startIcon={<StorageIcon/>}
102+
endIcon={(
103+
<div
104+
className={classNames({
105+
"vm-execution-controls-buttons__arrow": true,
106+
"vm-execution-controls-buttons__arrow_open": openPopup,
107+
})}
108+
>
109+
<ArrowDownIcon/>
110+
</div>
111+
)}
112+
onClick={toggleOpenPopup}
113+
>
114+
{formattedTenant}
115+
</Button>
116+
</div>
90117
)}
91-
</div>
92-
</Tooltip>
93-
<Popper
94-
open={openPopup}
95-
placement="bottom-right"
96-
onClose={handleClosePopup}
97-
buttonRef={buttonRef}
98-
title={isMobile ? "Define Tenant ID" : undefined}
99-
>
100-
<div
101-
className={classNames({
102-
"vm-list vm-tenant-input-list": true,
103-
"vm-list vm-tenant-input-list_mobile": isMobile,
104-
"vm-tenant-input-list_inline": true,
105-
})}
118+
</Tooltip>
119+
)}
120+
{!isTenantStatic && (
121+
<Popper
122+
open={openPopup}
123+
placement="bottom-right"
124+
onClose={handleClosePopup}
125+
buttonRef={buttonRef}
126+
title={isMobile ? "Define Tenant ID" : undefined}
106127
>
107-
<TextField
108-
autofocus
109-
label="accountID"
110-
value={accountID}
111-
onChange={setAccountID}
112-
type="number"
113-
/>
114-
<TextField
115-
autofocus
116-
label="projectID"
117-
value={projectID}
118-
onChange={setProjectID}
119-
type="number"
120-
/>
121-
<div className="vm-tenant-input-list__buttons">
122-
<Tooltip title="Multitenancy in VictoriaLogs documentation">
123-
<a
124-
href="https://docs.victoriametrics.com/victorialogs/#multitenancy"
125-
target="_blank"
126-
rel="help noreferrer"
128+
<div
129+
className={classNames({
130+
"vm-list vm-tenant-input-list": true,
131+
"vm-list vm-tenant-input-list_mobile": isMobile,
132+
"vm-tenant-input-list_inline": true,
133+
})}
134+
>
135+
<TextField
136+
autofocus
137+
label="accountID"
138+
value={accountID}
139+
onChange={setAccountID}
140+
type="number"
141+
/>
142+
<TextField
143+
autofocus
144+
label="projectID"
145+
value={projectID}
146+
onChange={setProjectID}
147+
type="number"
148+
/>
149+
<div className="vm-tenant-input-list__buttons">
150+
<Tooltip title="Multitenancy in VictoriaLogs documentation">
151+
<a
152+
href="https://docs.victoriametrics.com/victorialogs/#multitenancy"
153+
target="_blank"
154+
rel="help noreferrer"
155+
>
156+
<Button
157+
variant="text"
158+
color="gray"
159+
startIcon={<QuestionIcon/>}
160+
/>
161+
</a>
162+
</Tooltip>
163+
<Button
164+
variant="contained"
165+
color="primary"
166+
onClick={applyChanges}
127167
>
128-
<Button
129-
variant="text"
130-
color="gray"
131-
startIcon={<QuestionIcon/>}
132-
/>
133-
</a>
134-
</Tooltip>
135-
<Button
136-
variant="contained"
137-
color="primary"
138-
onClick={applyChanges}
139-
>
140-
Apply
141-
</Button>
168+
Apply
169+
</Button>
170+
</div>
142171
</div>
143-
</div>
144-
</Popper>
172+
</Popper>
173+
)}
145174
</div>
146175
);
147176
};

app/vmui/packages/vmui/src/components/Configurators/GlobalSettings/TenantsConfiguration/style.scss

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,31 @@
33
.vm-tenant-input {
44
position: relative;
55

6+
&_disabled:not(&_mobile) {
7+
.vm-mobile-option {
8+
&__icon {
9+
color: #fff;
10+
}
11+
&-text {
12+
color: #fff;
13+
&__value {
14+
color: #fff;
15+
}
16+
}
17+
}
18+
}
19+
20+
&_disabled:is(&_mobile) {
21+
.vm-mobile-option {
22+
&__icon {
23+
color: $color-text-disabled;
24+
}
25+
&-text {
26+
color: $color-text-disabled;
27+
}
28+
}
29+
}
30+
631
&-list {
732
max-height: 300px;
833
overflow: auto;

app/vmui/packages/vmui/src/components/Views/JsonView/JsonView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const JsonView: FC<Props> = ({ data }) => {
1212
return s;
1313
}
1414
return JSON.stringify(a);
15-
}).join("\n")
15+
}).join("\n");
1616
}, [data]);
1717
return (
1818
<pre style="line-height: 1.2em">{jsonStr}</pre>

app/vmui/packages/vmui/src/hooks/useFetchAppConfig.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import { useAppDispatch } from "../state/common/StateContext";
1+
import { useAppDispatch, useAppState } from "../state/common/StateContext";
22
import { useEffect, useState } from "preact/compat";
33
import { ErrorTypes } from "../types";
44

55
const useFetchFlags = () => {
6+
const { serverUrl } = useAppState();
67
const dispatch = useAppDispatch();
78

89
const [isLoading, setIsLoading] = useState(false);
@@ -14,17 +15,23 @@ const useFetchFlags = () => {
1415
setIsLoading(true);
1516

1617
try {
17-
const data = await fetch("./config.json");
18+
const data = await fetch(`${serverUrl}/select/vmui/config.json`);
1819
const config = await data.json();
1920
dispatch({ type: "SET_APP_CONFIG", payload: config || {} });
21+
const tenant = {
22+
accountID: data.headers.get("AccountID") || "",
23+
projectID: data.headers.get("ProjectID") || "",
24+
disableTenantInfo: data.headers.get("VL-Disable-Tenant-Controls") == "true",
25+
};
26+
dispatch({ type: "SET_TENANT_ID", payload: tenant });
2027
} catch (e) {
2128
setIsLoading(false);
2229
if (e instanceof Error) setError(`${e.name}: ${e.message}`);
2330
}
2431
};
2532

2633
fetchAppConfig();
27-
}, []);
34+
}, [serverUrl]);
2835

2936
return { isLoading, error };
3037
};

app/vmui/packages/vmui/src/layouts/Footer/Footer.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { FC, memo } from "preact/compat";
22
import { LogoShortIcon } from "../../components/Main/Icons";
33
import "./style.scss";
44
import { footerLinksToLogs } from "../../constants/footerLinks";
5+
import { useAppState } from "../../state/common/StateContext";
56

67
interface Props {
78
links?: {
@@ -13,10 +14,12 @@ interface Props {
1314

1415
const Footer: FC<Props> = memo(({ links = footerLinksToLogs }) => {
1516
const copyrightYears = `2019-${new Date().getFullYear()}`;
17+
const { appConfig } = useAppState();
18+
const version = appConfig?.version;
1619

1720
return <footer className="vm-footer">
1821
<a
19-
className="vm-link vm-footer__website"
22+
className="vm-link vm-footer__link"
2023
target="_blank"
2124
href="https://victoriametrics.com/"
2225
rel="me noreferrer"
@@ -37,7 +40,8 @@ const Footer: FC<Props> = memo(({ links = footerLinksToLogs }) => {
3740
</a>
3841
))}
3942
<div className="vm-footer__copyright">
40-
&copy; {copyrightYears} VictoriaMetrics
43+
&copy; {copyrightYears} VictoriaMetrics.
44+
{version && <span className="vm-footer__version">&nbsp;Version: {version}</span>}
4145
</div>
4246
</footer>;
4347
});

app/vmui/packages/vmui/src/layouts/Header/HeaderControls/HeaderControls.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const HeaderControls: FC<ControlsProps & HeaderProps> = ({
5555
if (isMobile) {
5656
return (
5757
<>
58-
<div>
58+
<div className="vm-header-controls">
5959
<Button
6060
className={classNames({
6161
"vm-header-button": !appModeEnable

0 commit comments

Comments
 (0)