Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/browser/parts/views/viewsViewlet.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { IExtensionService } from '../../../services/extensions/common/extensions.js';
7
import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';
8
import { IViewDescriptor, IViewDescriptorService, IAddedViewDescriptorRef, IView } from '../../../common/views.js';
9
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
10
import { IThemeService } from '../../../../platform/theme/common/themeService.js';
11
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
12
import { IStorageService } from '../../../../platform/storage/common/storage.js';
13
import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js';
14
import { ViewPaneContainer } from './viewPaneContainer.js';
15
import { ViewPane, IViewPaneOptions } from './viewPane.js';
16
import { Event } from '../../../../base/common/event.js';
17
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
18
import { IWorkbenchLayoutService } from '../../../services/layout/browser/layoutService.js';
19
import { ExtensionIdentifier } from '../../../../platform/extensions/common/extensions.js';
20
import { ILogService } from '../../../../platform/log/common/log.js';
21
22
export interface IViewletViewOptions extends IViewPaneOptions {
23
readonly fromExtensionId?: ExtensionIdentifier;
24
}
25
26
export abstract class FilterViewPaneContainer extends ViewPaneContainer {
27
private constantViewDescriptors: Map<string, IViewDescriptor> = new Map();
28
private allViews: Map<string, Map<string, IViewDescriptor>> = new Map();
29
private filterValue: string[] | undefined;
30
31
constructor(
32
viewletId: string,
33
onDidChangeFilterValue: Event<string[]>,
34
@IConfigurationService configurationService: IConfigurationService,
35
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
36
@ITelemetryService telemetryService: ITelemetryService,
37
@IStorageService storageService: IStorageService,
38
@IInstantiationService instantiationService: IInstantiationService,
39
@IThemeService themeService: IThemeService,
40
@IContextMenuService contextMenuService: IContextMenuService,
41
@IExtensionService extensionService: IExtensionService,
42
@IWorkspaceContextService contextService: IWorkspaceContextService,
43
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
44
@ILogService logService: ILogService,
45
) {
46
47
super(viewletId, { mergeViewWithContainerWhenSingleView: false }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService, logService);
48
this._register(onDidChangeFilterValue(newFilterValue => {
49
this.filterValue = newFilterValue;
50
this.onFilterChanged(newFilterValue);
51
}));
52
53
this._register(this.viewContainerModel.onDidChangeActiveViewDescriptors(() => {
54
this.updateAllViews(this.viewContainerModel.activeViewDescriptors);
55
}));
56
}
57
58
private updateAllViews(viewDescriptors: ReadonlyArray<IViewDescriptor>) {
59
viewDescriptors.forEach(descriptor => {
60
const filterOnValue = this.getFilterOn(descriptor);
61
if (!filterOnValue) {
62
return;
63
}
64
if (!this.allViews.has(filterOnValue)) {
65
this.allViews.set(filterOnValue, new Map());
66
}
67
this.allViews.get(filterOnValue)!.set(descriptor.id, descriptor);
68
if (this.filterValue && !this.filterValue.includes(filterOnValue) && this.panes.find(pane => pane.id === descriptor.id)) {
69
this.viewContainerModel.setVisible(descriptor.id, false);
70
}
71
});
72
}
73
74
protected addConstantViewDescriptors(constantViewDescriptors: IViewDescriptor[]) {
75
constantViewDescriptors.forEach(viewDescriptor => this.constantViewDescriptors.set(viewDescriptor.id, viewDescriptor));
76
}
77
78
protected abstract getFilterOn(viewDescriptor: IViewDescriptor): string | undefined;
79
80
protected abstract setFilter(viewDescriptor: IViewDescriptor): void;
81
82
private onFilterChanged(newFilterValue: string[]) {
83
if (this.allViews.size === 0) {
84
this.updateAllViews(this.viewContainerModel.activeViewDescriptors);
85
}
86
this.getViewsNotForTarget(newFilterValue).forEach(item => this.viewContainerModel.setVisible(item.id, false));
87
this.getViewsForTarget(newFilterValue).forEach(item => this.viewContainerModel.setVisible(item.id, true));
88
}
89
90
private getViewsForTarget(target: string[]): IViewDescriptor[] {
91
const views: IViewDescriptor[] = [];
92
for (let i = 0; i < target.length; i++) {
93
if (this.allViews.has(target[i])) {
94
views.push(...Array.from(this.allViews.get(target[i])!.values()));
95
}
96
}
97
98
return views;
99
}
100
101
private getViewsNotForTarget(target: string[]): IViewDescriptor[] {
102
const iterable = this.allViews.keys();
103
let key = iterable.next();
104
let views: IViewDescriptor[] = [];
105
while (!key.done) {
106
let isForTarget: boolean = false;
107
target.forEach(value => {
108
if (key.value === value) {
109
isForTarget = true;
110
}
111
});
112
if (!isForTarget) {
113
views = views.concat(this.getViewsForTarget([key.value]));
114
}
115
116
key = iterable.next();
117
}
118
return views;
119
}
120
121
protected override onDidAddViewDescriptors(added: IAddedViewDescriptorRef[]): ViewPane[] {
122
const panes: ViewPane[] = super.onDidAddViewDescriptors(added);
123
for (let i = 0; i < added.length; i++) {
124
if (this.constantViewDescriptors.has(added[i].viewDescriptor.id)) {
125
panes[i].setExpanded(false);
126
}
127
}
128
// Check that allViews is ready
129
if (this.allViews.size === 0) {
130
this.updateAllViews(this.viewContainerModel.activeViewDescriptors);
131
}
132
return panes;
133
}
134
135
override openView(id: string, focus?: boolean): IView | undefined {
136
const result = super.openView(id, focus);
137
if (result) {
138
const descriptorMap = Array.from(this.allViews.entries()).find(entry => entry[1].has(id));
139
if (descriptorMap && !this.filterValue?.includes(descriptorMap[0])) {
140
this.setFilter(descriptorMap[1].get(id)!);
141
}
142
}
143
return result;
144
}
145
146
abstract override getTitle(): string;
147
148
}
149
150