-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit adds the base components for the v2 tables overview page. The current route is under `/v2/databases/:dbID`. We've also changed the v2 db page to route to this page when clicking the link on the db name column. Epic: CRDB-37558 Fixes: #130675 Release note: None
- Loading branch information
Showing
9 changed files
with
325 additions
and
4 deletions.
There are no files selected for viewing
20 changes: 20 additions & 0 deletions
20
pkg/ui/workspaces/cluster-ui/src/databaseDetailsV2/constants.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// Copyright 2024 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
export enum TableColName { | ||
NAME = "Name", | ||
REPLICATION_SIZE = "Replication Size", | ||
RANGE_COUNT = "Ranges", | ||
COLUMN_COUNT = "Columns", | ||
NODE_REGIONS = "Regions / Nodes", | ||
LIVE_DATA_PERCENTAGE = "% of Live data", | ||
AUTO_STATS_COLLECTION = "Table auto stats collection", | ||
STATS_LAST_UPDATED = "Stats last updated", | ||
} |
46 changes: 46 additions & 0 deletions
46
pkg/ui/workspaces/cluster-ui/src/databaseDetailsV2/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2024 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
import { Tabs } from "antd"; | ||
import React, { useState } from "react"; | ||
|
||
import { commonStyles } from "src/common"; | ||
import { PageLayout } from "src/layouts"; | ||
import { PageHeader } from "src/sharedFromCloud/pageHeader"; | ||
|
||
import { TablesPageV2 } from "./tablesView"; | ||
|
||
const { TabPane } = Tabs; | ||
|
||
enum TabKeys { | ||
TABLES = "tables", | ||
GRANTS = "grants", | ||
} | ||
export const DatabaseDetailsPageV2 = () => { | ||
const [currentTab, setCurrentTab] = useState(TabKeys.TABLES); | ||
|
||
return ( | ||
<PageLayout> | ||
<PageHeader title="myDB" /> | ||
<Tabs | ||
defaultActiveKey={TabKeys.TABLES} | ||
className={commonStyles("cockroach--tabs")} | ||
onChange={setCurrentTab} | ||
activeKey={currentTab} | ||
destroyInactiveTabPane | ||
> | ||
<TabPane tab="Tables" key={TabKeys.TABLES}> | ||
<TablesPageV2 /> | ||
</TabPane> | ||
<TabPane tab="Grants" key={TabKeys.GRANTS}></TabPane> | ||
</Tabs> | ||
</PageLayout> | ||
); | ||
}; |
219 changes: 219 additions & 0 deletions
219
pkg/ui/workspaces/cluster-ui/src/databaseDetailsV2/tablesView.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
// Copyright 2024 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
import { Badge, BadgeIntent } from "@cockroachlabs/ui-components"; | ||
import moment from "moment-timezone"; | ||
import React, { useState } from "react"; | ||
import { Link } from "react-router-dom"; | ||
import Select, { OptionsType } from "react-select"; | ||
|
||
import { RegionNodesLabel } from "src/components/regionNodesLabel"; | ||
import { PageSection } from "src/layouts"; | ||
import { PageConfig, PageConfigItem } from "src/pageConfig"; | ||
import PageCount from "src/sharedFromCloud/pageCount"; | ||
import { Search } from "src/sharedFromCloud/search"; | ||
import { Table, TableColumnProps } from "src/sharedFromCloud/table"; | ||
import useTable from "src/sharedFromCloud/useTable"; | ||
import { ReactSelectOption } from "src/types/selectTypes"; | ||
import { Bytes, EncodeDatabaseTableUri } from "src/util"; | ||
|
||
import { TableColName } from "./constants"; | ||
import { TableRow } from "./types"; | ||
|
||
const mockRegionOptions = [ | ||
{ label: "US East (N. Virginia)", value: "us-east-1" }, | ||
{ label: "US East (Ohio)", value: "us-east-2" }, | ||
]; | ||
|
||
const mockLastUpdated = moment.utc(); | ||
const mockData: TableRow[] = new Array(20).fill(1).map((_, i) => ({ | ||
name: `myDB-${i}`, | ||
qualifiedNameWithSchema: `public.table-${i}`, | ||
dbName: `myDB-${i}`, | ||
dbID: i, | ||
replicationSizeBytes: i * 100, | ||
rangeCount: i, | ||
columnCount: i, | ||
nodesByRegion: | ||
i % 2 === 0 | ||
? { | ||
[mockRegionOptions[0].value]: [1, 2], | ||
[mockRegionOptions[1].value]: [3], | ||
} | ||
: null, | ||
liveDataPercentage: 1, | ||
liveDataBytes: i * 100, | ||
totalDataBytes: i * 100, | ||
autoStatsCollectionEnabled: i % 2 === 0, | ||
statsLastUpdated: mockLastUpdated, | ||
key: i.toString(), | ||
})); | ||
|
||
const filters = {}; | ||
|
||
const initialParams = { | ||
filters, | ||
pagination: { | ||
page: 1, | ||
pageSize: 10, | ||
}, | ||
search: "", | ||
sort: { | ||
field: "name", | ||
order: "asc" as const, | ||
}, | ||
}; | ||
|
||
const columns: TableColumnProps<TableRow>[] = [ | ||
{ | ||
title: TableColName.NAME, | ||
width: "15%", | ||
sorter: true, | ||
render: (t: TableRow) => { | ||
// This linking is just temporary. We'll need to update it to the correct path | ||
// using db ID and table ID once we have the table details page. | ||
const encodedDBPath = EncodeDatabaseTableUri(t.dbName, t.name); | ||
return <Link to={encodedDBPath}>{t.qualifiedNameWithSchema}</Link>; | ||
}, | ||
}, | ||
{ | ||
title: TableColName.REPLICATION_SIZE, | ||
width: "fit-content", | ||
sorter: true, | ||
render: (t: TableRow) => { | ||
return Bytes(t.replicationSizeBytes); | ||
}, | ||
}, | ||
{ | ||
title: TableColName.RANGE_COUNT, | ||
width: "fit-content", | ||
sorter: true, | ||
render: (t: TableRow) => { | ||
return t.rangeCount; | ||
}, | ||
}, | ||
{ | ||
title: TableColName.COLUMN_COUNT, | ||
width: "fit-content", | ||
sorter: true, | ||
render: (t: TableRow) => { | ||
return t.columnCount; | ||
}, | ||
}, | ||
{ | ||
title: TableColName.NODE_REGIONS, | ||
width: "20%", | ||
render: (t: TableRow) => ( | ||
<div> | ||
{Object.entries(t.nodesByRegion ?? {}).map(([region, nodes]) => ( | ||
<RegionNodesLabel | ||
key={region} | ||
nodes={nodes} | ||
region={{ label: region, code: region }} | ||
/> | ||
))} | ||
</div> | ||
), | ||
}, | ||
{ | ||
title: TableColName.LIVE_DATA_PERCENTAGE, | ||
sorter: true, | ||
render: (t: TableRow) => { | ||
return ( | ||
<div> | ||
<div>{t.liveDataPercentage * 100}%</div> | ||
<div> | ||
{Bytes(t.liveDataBytes)} / {Bytes(t.totalDataBytes)} | ||
</div> | ||
</div> | ||
); | ||
}, | ||
}, | ||
{ | ||
title: TableColName.AUTO_STATS_COLLECTION, | ||
sorter: true, | ||
render: (t: TableRow) => { | ||
let intent: BadgeIntent = "success"; | ||
let text = "Enabled"; | ||
if (!t.autoStatsCollectionEnabled) { | ||
intent = "warning"; | ||
text = "Disabled"; | ||
} | ||
return ( | ||
<Badge intent={intent} transformCase={"uppercase"}> | ||
{text} | ||
</Badge> | ||
); | ||
}, | ||
}, | ||
{ | ||
title: TableColName.STATS_LAST_UPDATED, | ||
sorter: true, | ||
render: (t: TableRow) => { | ||
return t.statsLastUpdated.format("YYYY-MM-DD HH:mm:ss"); | ||
}, | ||
}, | ||
]; | ||
|
||
export const TablesPageV2 = () => { | ||
const { params, setSearch } = useTable({ | ||
initial: initialParams, | ||
}); | ||
const data = mockData; | ||
|
||
const [nodeRegions, setNodeRegions] = useState<ReactSelectOption[]>([]); | ||
const onNodeRegionsChange = (selected: OptionsType<ReactSelectOption>) => { | ||
setNodeRegions((selected ?? []).map(v => v)); | ||
}; | ||
|
||
return ( | ||
<> | ||
<PageSection> | ||
<PageConfig> | ||
<PageConfigItem> | ||
<Search placeholder="Search tables" onSubmit={setSearch} /> | ||
</PageConfigItem> | ||
<PageConfigItem minWidth={"200px"}> | ||
<Select | ||
placeholder={"Regions"} | ||
name="nodeRegions" | ||
options={mockRegionOptions} | ||
clearable={true} | ||
isMulti | ||
value={nodeRegions} | ||
onChange={onNodeRegionsChange} | ||
/> | ||
</PageConfigItem> | ||
</PageConfig> | ||
</PageSection> | ||
<PageSection> | ||
<PageCount | ||
page={1} | ||
pageSize={params.pagination.pageSize} | ||
total={data.length} | ||
entity="tables" | ||
/> | ||
<Table | ||
columns={columns} | ||
dataSource={data} | ||
pagination={{ | ||
size: "small", | ||
current: params.pagination.page, | ||
pageSize: params.pagination.pageSize, | ||
showSizeChanger: false, | ||
position: ["bottomCenter"], | ||
total: data.length, | ||
}} | ||
onChange={(_pagination, _sorter) => {}} | ||
/> | ||
</PageSection> | ||
</> | ||
); | ||
}; |
28 changes: 28 additions & 0 deletions
28
pkg/ui/workspaces/cluster-ui/src/databaseDetailsV2/types.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright 2024 The Cockroach Authors. | ||
// | ||
// Use of this software is governed by the Business Source License | ||
// included in the file licenses/BSL.txt. | ||
// | ||
// As of the Change Date specified in that file, in accordance with | ||
// the Business Source License, use of this software will be governed | ||
// by the Apache License, Version 2.0, included in the file | ||
// licenses/APL.txt. | ||
|
||
import { Moment } from "moment-timezone"; | ||
|
||
export type TableRow = { | ||
qualifiedNameWithSchema: string; | ||
name: string; | ||
dbName: string; | ||
dbID: number; | ||
replicationSizeBytes: number; | ||
rangeCount: number; | ||
columnCount: number; | ||
nodesByRegion: Record<string, number[]>; | ||
liveDataPercentage: number; | ||
liveDataBytes: number; | ||
totalDataBytes: number; | ||
autoStatsCollectionEnabled: boolean; | ||
statsLastUpdated: Moment; | ||
key: string; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters