Skip to content

Commit 0d70022

Browse files
authored
Merge pull request #2949 from github/koesie10/single-model-editor-per-db
Only allow a single model editor per database
2 parents 7041dd7 + 039b282 commit 0d70022

File tree

5 files changed

+56
-24
lines changed

5 files changed

+56
-24
lines changed

extensions/ql-vscode/src/model-editor/method-modeling/method-modeling-view-provider.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,10 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
144144
return;
145145
}
146146

147-
const views = this.editorViewTracker.getViews(
147+
const view = this.editorViewTracker.getView(
148148
this.databaseItem.databaseUri.toString(),
149149
);
150-
if (views.length === 0) {
151-
return;
152-
}
153-
154-
await Promise.all(views.map((view) => view.revealMethod(method)));
150+
await view?.revealMethod(method);
155151
}
156152

157153
private registerToModelingStoreEvents(): void {

extensions/ql-vscode/src/model-editor/model-editor-module.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,15 @@ export class ModelEditorModule extends DisposableObject {
128128
return;
129129
}
130130

131+
const existingView = this.editorViewTracker.getView(
132+
db.databaseUri.toString(),
133+
);
134+
if (existingView) {
135+
await existingView.focusView();
136+
137+
return;
138+
}
139+
131140
return withProgress(
132141
async (progress) => {
133142
const maxStep = 4;
@@ -192,6 +201,17 @@ export class ModelEditorModule extends DisposableObject {
192201
maxStep,
193202
});
194203

204+
// Check again just before opening the editor to ensure no model editor has been opened between
205+
// our first check and now.
206+
const existingView = this.editorViewTracker.getView(
207+
db.databaseUri.toString(),
208+
);
209+
if (existingView) {
210+
await existingView.focusView();
211+
212+
return;
213+
}
214+
195215
const view = new ModelEditorView(
196216
this.app,
197217
this.modelingStore,

extensions/ql-vscode/src/model-editor/model-editor-view-tracker.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,25 @@ interface ModelEditorViewInterface {
99
export class ModelEditorViewTracker<
1010
T extends ModelEditorViewInterface = ModelEditorViewInterface,
1111
> {
12-
private readonly views = new Map<string, T[]>();
12+
private readonly views = new Map<string, T>();
1313

1414
constructor() {}
1515

1616
public registerView(view: T): void {
1717
const databaseUri = view.databaseUri;
1818

19-
if (!this.views.has(databaseUri)) {
20-
this.views.set(databaseUri, []);
19+
if (this.views.has(databaseUri)) {
20+
throw new Error(`View for database ${databaseUri} already registered`);
2121
}
2222

23-
this.views.get(databaseUri)?.push(view);
23+
this.views.set(databaseUri, view);
2424
}
2525

2626
public unregisterView(view: T): void {
27-
const views = this.views.get(view.databaseUri);
28-
if (!views) {
29-
return;
30-
}
31-
32-
const index = views.indexOf(view);
33-
if (index !== -1) {
34-
views.splice(index, 1);
35-
}
27+
this.views.delete(view.databaseUri);
3628
}
3729

38-
public getViews(databaseUri: string): T[] {
39-
return this.views.get(databaseUri) ?? [];
30+
public getView(databaseUri: string): T | undefined {
31+
return this.views.get(databaseUri);
4032
}
4133
}

extensions/ql-vscode/src/model-editor/model-editor-view.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,10 @@ export class ModelEditorView extends AbstractWebview<
349349
return this.databaseItem.databaseUri.toString();
350350
}
351351

352+
public async focusView(): Promise<void> {
353+
this.panel?.reveal();
354+
}
355+
352356
public async revealMethod(method: Method): Promise<void> {
353357
this.panel?.reveal();
354358

@@ -521,6 +525,15 @@ export class ModelEditorView extends AbstractWebview<
521525
return;
522526
}
523527

528+
let existingView = this.viewTracker.getView(
529+
addedDatabase.databaseUri.toString(),
530+
);
531+
if (existingView) {
532+
await existingView.focusView();
533+
534+
return;
535+
}
536+
524537
const modelFile = await pickExtensionPack(
525538
this.cliServer,
526539
addedDatabase,
@@ -533,6 +546,17 @@ export class ModelEditorView extends AbstractWebview<
533546
return;
534547
}
535548

549+
// Check again just before opening the editor to ensure no model editor has been opened between
550+
// our first check and now.
551+
existingView = this.viewTracker.getView(
552+
addedDatabase.databaseUri.toString(),
553+
);
554+
if (existingView) {
555+
await existingView.focusView();
556+
557+
return;
558+
}
559+
536560
const view = new ModelEditorView(
537561
this.app,
538562
this.modelingStore,

extensions/ql-vscode/test/__mocks__/model-editor/modelEditorViewTrackerMock.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ import { ModelEditorView } from "../../../src/model-editor/model-editor-view";
55
export function createMockModelEditorViewTracker({
66
registerView = jest.fn(),
77
unregisterView = jest.fn(),
8-
getViews = jest.fn(),
8+
getView = jest.fn(),
99
}: {
1010
registerView?: ModelEditorViewTracker["registerView"];
1111
unregisterView?: ModelEditorViewTracker["unregisterView"];
12-
getViews?: ModelEditorViewTracker["getViews"];
12+
getView?: ModelEditorViewTracker["getView"];
1313
} = {}): ModelEditorViewTracker<ModelEditorView> {
1414
return mockedObject<ModelEditorViewTracker<ModelEditorView>>({
1515
registerView,
1616
unregisterView,
17-
getViews,
17+
getView,
1818
});
1919
}

0 commit comments

Comments
 (0)