Skip to content

Commit 18b14dc

Browse files
committed
feat: IsDatabaseAllower support
1 parent fae206e commit 18b14dc

File tree

33 files changed

+409
-195
lines changed

33 files changed

+409
-195
lines changed

src/components/ErrorBoundary/utils.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async function getBackendVersion() {
2424
// node_id=. returns data about node that fullfills request
2525
// normally this request should be fast (200-300ms with good connection)
2626
// timeout=1000 in order not to wait too much in case everything is broken
27-
const data = await window.api.viewer.getNodeInfo('.', {timeout: 1000});
27+
const data = await window.api.viewer.getNodeInfo({nodeId: '.'}, {timeout: 1000});
2828
return data?.SystemStateInfo?.[0]?.Version;
2929
} catch (error) {
3030
return {error: prepareErrorMessage(error)};

src/components/NodeId/NodeId.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {getDefaultNodePath} from '../../containers/Node/NodePages';
2+
import {useDatabaseFromQuery} from '../../utils/hooks/useDatabaseFromQuery';
3+
import {InternalLink} from '../InternalLink';
4+
5+
interface NodeIdProps {
6+
id: string | number;
7+
}
8+
9+
export function NodeId({id}: NodeIdProps) {
10+
const database = useDatabaseFromQuery();
11+
return <InternalLink to={getDefaultNodePath(id, {database})}>{id}</InternalLink>;
12+
}

src/components/ShardsTable/columns.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import DataTable from '@gravity-ui/react-data-table';
22

3-
import {getDefaultNodePath} from '../../containers/Node/NodePages';
43
import {EMPTY_DATA_PLACEHOLDER} from '../../utils/constants';
54
import {formatNumber, roundToPrecision} from '../../utils/dataFormatters/dataFormatters';
65
import {getUsageSeverity} from '../../utils/generateEvaluator';
7-
import {InternalLink} from '../InternalLink';
86
import {LinkToSchemaObject} from '../LinkToSchemaObject/LinkToSchemaObject';
7+
import {NodeId} from '../NodeId/NodeId';
98
import {TabletNameWrapper} from '../TabletNameWrapper/TabletNameWrapper';
109
import {UsageLabel} from '../UsageLabel/UsageLabel';
1110

@@ -39,7 +38,7 @@ export const getDataSizeColumn: GetShardsColumn = () => {
3938
align: DataTable.RIGHT,
4039
};
4140
};
42-
export const getTabletIdColumn: GetShardsColumn = () => {
41+
export const getTabletIdColumn: GetShardsColumn = ({database}) => {
4342
return {
4443
name: TOP_SHARDS_COLUMNS_IDS.TabletId,
4544
header: TOP_SHARDS_COLUMNS_TITLES.TabletId,
@@ -51,6 +50,7 @@ export const getTabletIdColumn: GetShardsColumn = () => {
5150
<TabletNameWrapper
5251
tabletId={row.TabletId}
5352
followerId={row.FollowerId || undefined}
53+
database={database}
5454
/>
5555
);
5656
},
@@ -65,7 +65,7 @@ export const getNodeIdColumn: GetShardsColumn = () => {
6565
if (!row.NodeId) {
6666
return EMPTY_DATA_PLACEHOLDER;
6767
}
68-
return <InternalLink to={getDefaultNodePath(row.NodeId)}>{row.NodeId}</InternalLink>;
68+
return <NodeId id={row.NodeId} />;
6969
},
7070
align: DataTable.RIGHT,
7171
};

src/components/VDisk/VDisk.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {cn} from '../../utils/cn';
22
import type {PreparedVDisk} from '../../utils/disks/types';
3+
import {useDatabaseFromQuery} from '../../utils/hooks/useDatabaseFromQuery';
34
import {DiskStateProgressBar} from '../DiskStateProgressBar/DiskStateProgressBar';
45
import {HoverPopup} from '../HoverPopup/HoverPopup';
56
import {InternalLink} from '../InternalLink';
@@ -34,7 +35,10 @@ export const VDisk = ({
3435
delayClose,
3536
delayOpen,
3637
}: VDiskProps) => {
37-
const vDiskPath = getVDiskLink(data);
38+
const database = useDatabaseFromQuery();
39+
const vDiskPath = getVDiskLink(data, {
40+
database: database,
41+
});
3842

3943
return (
4044
<HoverPopup

src/components/VDisk/utils.ts

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,15 @@
11
import {getVDiskPagePath} from '../../routes';
2-
import {valueIsDefined} from '../../utils';
32
import type {PreparedVDisk} from '../../utils/disks/types';
43

5-
export function getVDiskLink(data: PreparedVDisk) {
6-
let vDiskPath: string | undefined;
7-
8-
if (
9-
valueIsDefined(data.VDiskSlotId) &&
10-
valueIsDefined(data.PDiskId) &&
11-
valueIsDefined(data.NodeId)
12-
) {
13-
vDiskPath = getVDiskPagePath({
4+
export function getVDiskLink(data: PreparedVDisk, query: {database: string | undefined}) {
5+
return getVDiskPagePath(
6+
{
147
vDiskSlotId: data.VDiskSlotId,
158
pDiskId: data.PDiskId,
169
nodeId: data.NodeId,
10+
groupId: data.VDiskId?.GroupID,
1711
vDiskId: data.StringifiedId,
18-
});
19-
} else if (valueIsDefined(data.StringifiedId)) {
20-
vDiskPath = getVDiskPagePath({
21-
vDiskId: data.StringifiedId,
22-
pDiskId: data.PDiskId,
23-
nodeId: data.NodeId,
24-
});
25-
}
26-
27-
return vDiskPath;
12+
},
13+
query,
14+
);
2815
}

src/components/VDiskInfo/VDiskInfo.tsx

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import {createVDiskDeveloperUILink} from '../../utils/developerUI/developerUI';
1414
import {getSeverityColor} from '../../utils/disks/helpers';
1515
import type {PreparedVDisk} from '../../utils/disks/types';
16+
import {useDatabaseFromQuery} from '../../utils/hooks/useDatabaseFromQuery';
1617
import {useIsUserAllowedToMakeChanges} from '../../utils/hooks/useIsUserAllowedToMakeChanges';
1718
import {bytesToSpeed} from '../../utils/utils';
1819
import {InfoViewer} from '../InfoViewer';
@@ -44,6 +45,7 @@ export function VDiskInfo<T extends PreparedVDisk>({
4445
wrap,
4546
}: VDiskInfoProps<T>) {
4647
const isUserAllowedToMakeChanges = useIsUserAllowedToMakeChanges();
48+
const database = useDatabaseFromQuery();
4749

4850
const {
4951
AllocatedSize,
@@ -66,6 +68,8 @@ export function VDiskInfo<T extends PreparedVDisk>({
6668
ReadThroughput,
6769
WriteThroughput,
6870
PDiskId,
71+
StringifiedId,
72+
VDiskId,
6973
NodeId,
7074
} = data || {};
7175

@@ -194,17 +198,23 @@ export function VDiskInfo<T extends PreparedVDisk>({
194198
NodeId: dNodeId,
195199
PDiskId: dPDiskId,
196200
VDiskSlotId: dVSlotId,
201+
VDiskId: dVdiskId,
197202
} = donor;
198203

199204
if (!id || !dVSlotId || !dNodeId || !dPDiskId) {
200205
return null;
201206
}
202207

203-
const vDiskPath = getVDiskPagePath({
204-
nodeId: dNodeId,
205-
pDiskId: dPDiskId,
206-
vDiskSlotId: dVSlotId,
207-
});
208+
const vDiskPath = getVDiskPagePath(
209+
{
210+
nodeId: dNodeId,
211+
pDiskId: dPDiskId,
212+
vDiskSlotId: dVSlotId,
213+
vDiskId: id,
214+
groupId: dVdiskId?.GroupID,
215+
},
216+
{database},
217+
);
208218

209219
return (
210220
<InternalLink key={index} to={vDiskPath}>
@@ -232,11 +242,16 @@ export function VDiskInfo<T extends PreparedVDisk>({
232242
const links: React.ReactNode[] = [];
233243

234244
if (withVDiskPageLink) {
235-
const vDiskPagePath = getVDiskPagePath({
236-
vDiskSlotId: VDiskSlotId,
237-
pDiskId: PDiskId,
238-
nodeId: NodeId,
239-
});
245+
const vDiskPagePath = getVDiskPagePath(
246+
{
247+
vDiskSlotId: VDiskSlotId,
248+
pDiskId: PDiskId,
249+
nodeId: NodeId,
250+
vDiskId: StringifiedId,
251+
groupId: VDiskId?.GroupID,
252+
},
253+
{database},
254+
);
240255
links.push(
241256
<LinkWithIcon
242257
key={vDiskPagePath}

src/components/VDiskPopup/VDiskPopup.tsx

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {createVDiskDeveloperUILink} from '../../utils/developerUI/developerUI';
1313
import {isFullVDiskData} from '../../utils/disks/helpers';
1414
import type {PreparedVDisk, UnavailableDonor} from '../../utils/disks/types';
1515
import {useTypedSelector} from '../../utils/hooks';
16+
import {useDatabaseFromQuery} from '../../utils/hooks/useDatabaseFromQuery';
1617
import {
1718
useIsUserAllowedToMakeChanges,
1819
useIsViewerUser,
@@ -71,7 +72,11 @@ const prepareUnavailableVDiskData = (data: UnavailableDonor, withDeveloperUILink
7172
};
7273

7374
// eslint-disable-next-line complexity
74-
const prepareVDiskData = (data: PreparedVDisk, withDeveloperUILink?: boolean) => {
75+
const prepareVDiskData = (
76+
data: PreparedVDisk,
77+
withDeveloperUILink: boolean | undefined,
78+
query: {database: string | undefined},
79+
) => {
7580
const {
7681
NodeId,
7782
PDiskId,
@@ -89,6 +94,7 @@ const prepareVDiskData = (data: PreparedVDisk, withDeveloperUILink?: boolean) =>
8994
ReadThroughput,
9095
WriteThroughput,
9196
StoragePoolName,
97+
VDiskId,
9298
} = data;
9399

94100
const vdiskData: InfoViewerItem[] = [
@@ -201,7 +207,10 @@ const prepareVDiskData = (data: PreparedVDisk, withDeveloperUILink?: boolean) =>
201207
})
202208
: undefined;
203209

204-
const vDiskPagePath = getVDiskLink({VDiskSlotId, PDiskId, NodeId, StringifiedId});
210+
const vDiskPagePath = getVDiskLink(
211+
{VDiskSlotId, PDiskId, NodeId, StringifiedId, VDiskId},
212+
query,
213+
);
205214
if (vDiskPagePath) {
206215
vdiskData.push({
207216
label: vDiskPopupKeyset('label_links'),
@@ -238,12 +247,14 @@ export const VDiskPopup = ({data}: VDiskPopupProps) => {
238247

239248
const isUserAllowedToMakeChanges = useIsUserAllowedToMakeChanges();
240249

250+
const database = useDatabaseFromQuery();
251+
241252
const vdiskInfo = React.useMemo(
242253
() =>
243254
isFullData
244-
? prepareVDiskData(data, isUserAllowedToMakeChanges)
255+
? prepareVDiskData(data, isUserAllowedToMakeChanges, {database})
245256
: prepareUnavailableVDiskData(data, isUserAllowedToMakeChanges),
246-
[data, isFullData, isUserAllowedToMakeChanges],
257+
[data, isFullData, isUserAllowedToMakeChanges, database],
247258
);
248259

249260
const nodesMap = useTypedSelector(selectNodesMap);
@@ -262,7 +273,11 @@ export const VDiskPopup = ({data}: VDiskPopupProps) => {
262273
for (const donor of donors) {
263274
donorsInfo.push({
264275
label: vDiskPopupKeyset('label_vdisk'),
265-
value: <InternalLink to={getVDiskLink(donor)}>{donor.StringifiedId}</InternalLink>,
276+
value: (
277+
<InternalLink to={getVDiskLink(donor, {database})}>
278+
{donor.StringifiedId}
279+
</InternalLink>
280+
),
266281
});
267282
}
268283
}

src/containers/App/Content.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ function GetUser({children}: {children: React.ReactNode}) {
201201
}
202202

203203
function GetNodesList() {
204-
nodesListApi.useGetNodesListQuery(undefined);
204+
const database = useDatabaseFromQuery();
205+
nodesListApi.useGetNodesListQuery({database}, undefined);
205206
return null;
206207
}
207208

src/containers/Header/breadcrumbs.tsx

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import {
44
Database as DatabaseIcon,
55
HardDrive as StorageNodeIcon,
66
} from '@gravity-ui/icons';
7+
import {isNil} from 'lodash';
78

89
import {TabletIcon} from '../../components/TabletIcon/TabletIcon';
9-
import routes, {getPDiskPagePath} from '../../routes';
10+
import routes, {getPDiskPagePath, getStorageGroupPath} from '../../routes';
1011
import type {
1112
BreadcrumbsOptions,
1213
ClusterBreadcrumbsOptions,
@@ -38,7 +39,10 @@ export interface RawBreadcrumbItem {
3839
}
3940

4041
interface GetBreadcrumbs<T, U = AnyRecord> {
41-
(options: T & {singleClusterMode: boolean}, query?: U): RawBreadcrumbItem[];
42+
(
43+
options: T & {singleClusterMode: boolean; isViewerUser?: boolean},
44+
query?: U,
45+
): RawBreadcrumbItem[];
4246
}
4347

4448
const getQueryForTenant = (type: 'nodes' | 'tablets') => ({
@@ -133,6 +137,9 @@ function getNodeIcon(nodeRole: 'Storage' | 'Compute' | undefined) {
133137
}
134138

135139
const getPDiskBreadcrumbs: GetBreadcrumbs<PDiskBreadcrumbsOptions> = (options, query = {}) => {
140+
if (!options.isViewerUser) {
141+
return [];
142+
}
136143
const {nodeId, pDiskId, nodeRole} = options;
137144

138145
const breadcrumbs = getNodeBreadcrumbs({
@@ -157,35 +164,42 @@ const getPDiskBreadcrumbs: GetBreadcrumbs<PDiskBreadcrumbsOptions> = (options, q
157164
return breadcrumbs;
158165
};
159166

160-
const getVDiskBreadcrumbs: GetBreadcrumbs<VDiskBreadcrumbsOptions> = (options, query = {}) => {
161-
const {vDiskSlotId} = options;
167+
const getStorageGroupBreadcrumbs: GetBreadcrumbs<StorageGroupBreadcrumbsOptions> = (
168+
options,
169+
query = {},
170+
) => {
171+
const {groupId, isViewerUser, tenantName} = options;
162172

163-
const breadcrumbs = getPDiskBreadcrumbs(options, query);
173+
const breadcrumbs = isViewerUser
174+
? getClusterBreadcrumbs(options, query)
175+
: getTenantBreadcrumbs(options, query);
164176

165-
let text = headerKeyset('breadcrumbs.vDisk');
166-
if (vDiskSlotId) {
167-
text += ` ${vDiskSlotId}`;
177+
let text = headerKeyset('breadcrumbs.storageGroup');
178+
if (groupId) {
179+
text += ` ${groupId}`;
168180
}
169181

170182
const lastItem = {
171183
text,
184+
link: groupId ? getStorageGroupPath(groupId, {database: tenantName}) : undefined,
172185
};
173186
breadcrumbs.push(lastItem);
174187

175188
return breadcrumbs;
176189
};
177190

178-
const getStorageGroupBreadcrumbs: GetBreadcrumbs<StorageGroupBreadcrumbsOptions> = (
179-
options,
180-
query = {},
181-
) => {
182-
const {groupId} = options;
191+
const getVDiskBreadcrumbs: GetBreadcrumbs<VDiskBreadcrumbsOptions> = (options, query = {}) => {
192+
const {vDiskSlotId, groupId} = options;
183193

184-
const breadcrumbs = getClusterBreadcrumbs(options, query);
194+
let breadcrumbs = getPDiskBreadcrumbs(options, query);
185195

186-
let text = headerKeyset('breadcrumbs.storageGroup');
187-
if (groupId) {
188-
text += ` ${groupId}`;
196+
if (breadcrumbs.length === 0 && !isNil(groupId)) {
197+
breadcrumbs = getStorageGroupBreadcrumbs(options, query);
198+
}
199+
200+
let text = headerKeyset('breadcrumbs.vDisk');
201+
if (vDiskSlotId) {
202+
text += ` ${vDiskSlotId}`;
189203
}
190204

191205
const lastItem = {
@@ -226,7 +240,7 @@ const mapPageToGetter = {
226240

227241
export const getBreadcrumbs = (
228242
page: Page,
229-
options: BreadcrumbsOptions & {singleClusterMode: boolean},
243+
options: BreadcrumbsOptions & {singleClusterMode: boolean; isViewerUser?: boolean},
230244
rawBreadcrumbs: RawBreadcrumbItem[] = [],
231245
query = {},
232246
) => {

src/containers/Header/i18n/en.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"breadcrumbs.clusters": "All clusters",
3-
"breadcrumbs.tenant": "Tenant",
3+
"breadcrumbs.tenant": "Database",
44
"breadcrumbs.node": "Node",
55
"breadcrumbs.pDisk": "PDisk",
66
"breadcrumbs.vDisk": "VDisk",

0 commit comments

Comments
 (0)