Skip to content

Commit 8a4a72f

Browse files
committed
Group clusters by provider in the explorer
Signed-off-by: azerr <[email protected]>
1 parent 446695b commit 8a4a72f

File tree

5 files changed

+90
-29
lines changed

5 files changed

+90
-29
lines changed

src/client/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export class ClientAccessor implements Disposable {
1515
}
1616

1717
public get(clusterId: string): Client {
18-
if (!this.clientsById.hasOwnProperty(clusterId)) {
18+
if (!this.has(clusterId)) {
1919
const cluster = this.clusterSettings.get(clusterId);
2020

2121
if (!cluster) {
@@ -28,6 +28,10 @@ export class ClientAccessor implements Disposable {
2828
return this.clientsById[clusterId];
2929
}
3030

31+
public has(clusterId: string): boolean {
32+
return this.clientsById.hasOwnProperty(clusterId);
33+
}
34+
3135
public getSelectedClusterClient(): Client | undefined {
3236
const selectedCluster = this.clusterSettings.selected;
3337

@@ -39,7 +43,7 @@ export class ClientAccessor implements Disposable {
3943
}
4044

4145
public remove(clusterId: string): void {
42-
if (!this.clientsById.hasOwnProperty(clusterId)) {
46+
if (!this.has(clusterId)) {
4347
return;
4448
}
4549

src/explorer/kafkaExplorer.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ export class KafkaExplorer implements vscode.Disposable, vscode.TreeDataProvider
9494
if (!clusterItem) {
9595
return;
9696
}
97-
this.selectItem(clusterItem);
97+
await this.selectItem(clusterItem);
9898
}
9999

100100
/**
@@ -112,11 +112,24 @@ export class KafkaExplorer implements vscode.Disposable, vscode.TreeDataProvider
112112
if (!topicItem) {
113113
return;
114114
}
115-
this.selectItem(topicItem);
115+
await this.selectItem(topicItem);
116116
}
117117

118-
private selectItem(item: NodeBase): void {
119-
this.tree?.reveal(item, {
118+
private async selectItem(item: NodeBase): Promise<void> {
119+
// Expand all parent items
120+
let parent = item.getParent();
121+
const children = [];
122+
while(parent && !(parent instanceof KafkaModel)) {
123+
children.unshift(parent);
124+
parent = parent.getParent();
125+
}
126+
for (const child of children) {
127+
await this.tree?.reveal(child, {
128+
expand: true,
129+
});
130+
}
131+
// select the item
132+
await this.tree?.reveal(item, {
120133
select: true,
121134
expand: true,
122135
focus: true

src/explorer/models/cluster.ts

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,45 @@ import { ConsumerGroupsItem } from "./consumerGroups";
99
import { KafkaModel } from "./kafka";
1010
import { Disposable } from "vscode";
1111
import { GlyphChars } from "../../constants";
12+
import { ClusterProvider, defaultClusterProviderId } from "../../kafka-extensions/registry";
13+
import { ClusterSettings } from "../../settings/clusters";
1214

1315
const TOPIC_INDEX = 1;
1416

17+
export class ClusterProviderItem extends NodeBase implements Disposable {
18+
19+
public contextValue = "clusterProvider";
20+
public collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
21+
22+
constructor(private clientAccessor: ClientAccessor, public readonly clusterProvider: ClusterProvider, parent: KafkaModel) {
23+
super(parent);
24+
this.label = clusterProvider.name;
25+
}
26+
27+
async computeChildren(): Promise<NodeBase[]> {
28+
const clusters = this.getParent().clusterSettings.getAll();
29+
return clusters
30+
.filter((c) => c.clusterProviderId === this.clusterProvider.id || (c.clusterProviderId === undefined && this.clusterProvider.id === defaultClusterProviderId))
31+
.map((c) => {
32+
return new ClusterItem(this.getParent().clusterSettings, this.clientAccessor, c, this);
33+
});
34+
}
35+
36+
getParent(): KafkaModel {
37+
return <KafkaModel>super.getParent();
38+
}
39+
40+
public dispose(): void {
41+
this.children?.forEach(child => (<ClusterItem>child).dispose());
42+
}
43+
44+
}
45+
1546
export class ClusterItem extends NodeBase implements Disposable {
1647
public contextValue = "cluster";
1748
public collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
1849

19-
constructor(private clientAccessor: ClientAccessor, public readonly cluster: Cluster, parent: KafkaModel) {
50+
constructor(private clusterSettings: ClusterSettings, private clientAccessor: ClientAccessor, public readonly cluster: Cluster, parent: KafkaModel | ClusterProviderItem) {
2051
super(parent);
2152
this.label = cluster.name;
2253
this.description = cluster.bootstrap;
@@ -33,10 +64,6 @@ export class ClusterItem extends NodeBase implements Disposable {
3364
new ConsumerGroupsItem(this)];
3465
}
3566

36-
getParent(): KafkaModel {
37-
return <KafkaModel>super.getParent();
38-
}
39-
4067
getTreeItem(): vscode.TreeItem {
4168
const treeItem = super.getTreeItem();
4269
// to prevent from tree expansion after a refresh, we need to force the id to a static value
@@ -53,11 +80,11 @@ export class ClusterItem extends NodeBase implements Disposable {
5380
}
5481

5582
public get selected(): boolean {
56-
return (this.getParent().clusterSettings.selected?.name === this.cluster.name);
83+
return (this.clusterSettings.selected?.name === this.cluster.name);
5784
}
5885

5986
public dispose(): void {
60-
this.client.dispose();
87+
this.clientAccessor.remove(this.cluster.id);
6188
}
6289

6390
async findTopictemByName(topicName: string): Promise<NodeBase | TopicItem | undefined> {

src/explorer/models/kafka.ts

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,59 @@
11
import { Disposable, TreeItemCollapsibleState } from "vscode";
2-
import { ClientAccessor } from "../../client";
2+
import { ClientAccessor, Cluster } from "../../client";
3+
import { getClusterProviders } from "../../kafka-extensions/registry";
34
import { ClusterSettings } from "../../settings";
4-
import { ClusterItem } from "./cluster";
5+
import { ClusterItem, ClusterProviderItem } from "./cluster";
56
import { NodeBase } from "./nodeBase";
67

78
export class KafkaModel extends NodeBase implements Disposable {
89

910
public contextValue = "";
1011
public collapsibleState = TreeItemCollapsibleState.Collapsed;
1112

13+
private clusterProviders = getClusterProviders();
1214
constructor(
1315
public readonly clusterSettings: ClusterSettings,
1416
protected clientAccessor: ClientAccessor) {
1517
super(undefined);
1618
}
1719

1820
public async computeChildren(): Promise<NodeBase[]> {
19-
const clusters = this.clusterSettings.getAll();
20-
return clusters.map((c) => {
21-
return new ClusterItem(this.clientAccessor, c, this);
22-
});
21+
if (this.clusterProviders.length <= 1) {
22+
const clusters = this.clusterSettings.getAll();
23+
return clusters.map((c) => {
24+
return new ClusterItem(this.clusterSettings, this.clientAccessor, c, this);
25+
});
26+
} else {
27+
return this.clusterProviders.map((p) => {
28+
return new ClusterProviderItem(this.clientAccessor, p, this);
29+
});
30+
}
2331
}
2432

2533
public dispose(): void {
26-
this.children?.forEach(child => (<ClusterItem>child).dispose());
34+
this.children?.forEach(child => (<Disposable><unknown>child).dispose());
2735
}
2836

2937
async findClusterItemByName(clusterName: string): Promise<NodeBase | ClusterItem | undefined> {
30-
return this.getChildren()
31-
.then(clusters =>
32-
clusters.find(child => (<ClusterItem>child).cluster.name === clusterName)
33-
);
38+
return this.findClusterItemBy((cluster) => (cluster.name === clusterName));
3439
}
3540

3641
async findClusterItemById(clusterId: string): Promise<NodeBase | ClusterItem | undefined> {
37-
return this.getChildren()
38-
.then(clusters =>
39-
clusters.find(child => (<ClusterItem>child).cluster.id === clusterId)
40-
);
42+
return this.findClusterItemBy((cluster) => (cluster.id === clusterId));
4143
}
44+
45+
async findClusterItemBy(predicate: (cluster: Cluster) => boolean): Promise<NodeBase | ClusterItem | undefined> {
46+
const children = await this.getChildren();
47+
if (this.clusterProviders.length <= 1) {
48+
return children.find(child => predicate((<ClusterItem>child).cluster));
49+
}
50+
for (const child of children) {
51+
const clusters = await (<ClusterProviderItem>child).getChildren();
52+
const cluster = clusters.find(c => predicate((<ClusterItem>c).cluster));
53+
if (cluster) {
54+
return cluster;
55+
}
56+
}
57+
}
58+
4259
}

src/kafka-extensions/registry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ function isKafkaExtensionParticipant(arg: any): boolean {
9292
return (arg as KafkaExtensionParticipant).getClusterProviderParticipant !== undefined;
9393
}
9494

95-
const defaultClusterProviderId = 'vscode-kafka.manual';
95+
export const defaultClusterProviderId = 'vscode-kafka.manual';
9696

9797
let providers: Map<string, ClusterProvider> = new Map();
9898

0 commit comments

Comments
 (0)