Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion extensions/ql-vscode/src/databases/config/db-config-store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { pathExists, writeJSON, readJSON, readJSONSync } from "fs-extra";
import { join } from "path";
import { cloneDbConfig, DbConfig, SelectedDbItem } from "./db-config";
import {
cloneDbConfig,
DbConfig,
ExpandedDbItem,
SelectedDbItem,
} from "./db-config";
import * as chokidar from "chokidar";
import { DisposableObject, DisposeHandler } from "../../pure/disposable-object";
import { DbConfigValidator } from "./db-config-validator";
Expand Down Expand Up @@ -72,6 +77,19 @@ export class DbConfigStore extends DisposableObject {
await this.writeConfig(config);
}

public async updateExpandedState(expandedItems: ExpandedDbItem[]) {
if (!this.config) {
throw Error("Cannot update expansion state if config is not loaded");
}

const config: DbConfig = {
...this.config,
expanded: expandedItems,
};

await this.writeConfig(config);
}

private async writeConfig(config: DbConfig): Promise<void> {
await writeJSON(this.configPath, config, {
spaces: 2,
Expand Down Expand Up @@ -137,6 +155,7 @@ export class DbConfigStore extends DisposableObject {
databases: [],
},
},
expanded: [],
};
}
}
47 changes: 47 additions & 0 deletions extensions/ql-vscode/src/databases/config/db-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

export interface DbConfig {
databases: DbConfigDatabases;
expanded: ExpandedDbItem[];
selected?: SelectedDbItem;
}

Expand Down Expand Up @@ -87,6 +88,37 @@ export interface LocalDatabase {
storagePath: string;
}

export type ExpandedDbItem =
| RootLocalExpandedDbItem
| LocalUserDefinedListExpandedDbItem
| RootRemoteExpandedDbItem
| RemoteUserDefinedListExpandedDbItem;

export enum ExpandedDbItemKind {
RootLocal = "rootLocal",
LocalUserDefinedList = "localUserDefinedList",
RootRemote = "rootRemote",
RemoteUserDefinedList = "remoteUserDefinedList",
}

export interface RootLocalExpandedDbItem {
kind: ExpandedDbItemKind.RootLocal;
}

export interface LocalUserDefinedListExpandedDbItem {
kind: ExpandedDbItemKind.LocalUserDefinedList;
listName: string;
}

export interface RootRemoteExpandedDbItem {
kind: ExpandedDbItemKind.RootRemote;
}

export interface RemoteUserDefinedListExpandedDbItem {
kind: ExpandedDbItemKind.RemoteUserDefinedList;
listName: string;
}

export function cloneDbConfig(config: DbConfig): DbConfig {
return {
databases: {
Expand All @@ -108,6 +140,7 @@ export function cloneDbConfig(config: DbConfig): DbConfig {
databases: config.databases.local.databases.map((db) => ({ ...db })),
},
},
expanded: config.expanded.map(cloneDbConfigExpandedItem),
selected: config.selected
? cloneDbConfigSelectedItem(config.selected)
: undefined,
Expand Down Expand Up @@ -150,3 +183,17 @@ function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
};
}
}

function cloneDbConfigExpandedItem(item: ExpandedDbItem): ExpandedDbItem {
switch (item.kind) {
case ExpandedDbItemKind.RootLocal:
case ExpandedDbItemKind.RootRemote:
return { kind: item.kind };
case ExpandedDbItemKind.LocalUserDefinedList:
case ExpandedDbItemKind.RemoteUserDefinedList:
return {
kind: item.kind,
listName: item.listName,
};
Comment thread
charisk marked this conversation as resolved.
}
}
66 changes: 66 additions & 0 deletions extensions/ql-vscode/src/databases/db-item-expansion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { ExpandedDbItem, ExpandedDbItemKind } from "./config/db-config";
import { DbItem, DbItemKind } from "./db-item";

export function calculateNewExpandedState(
currentExpandedItems: ExpandedDbItem[],
dbItem: DbItem,
itemExpanded: boolean,
): ExpandedDbItem[] {
if (itemExpanded) {
const expandedDbItem = mapDbItemToExpandedDbItem(dbItem);
const expandedItems = [...currentExpandedItems];
if (!expandedItems.some((i) => isDbItemEqualToExpandedDbItem(dbItem, i))) {
expandedItems.push(expandedDbItem);
}
return expandedItems;
} else {
return currentExpandedItems.filter(
(i) => !isDbItemEqualToExpandedDbItem(dbItem, i),
);
}
}

function mapDbItemToExpandedDbItem(dbItem: DbItem): ExpandedDbItem {
switch (dbItem.kind) {
case DbItemKind.RootLocal:
return { kind: ExpandedDbItemKind.RootLocal };
case DbItemKind.LocalList:
return {
kind: ExpandedDbItemKind.LocalUserDefinedList,
listName: dbItem.listName,
};
case DbItemKind.RootRemote:
return { kind: ExpandedDbItemKind.RootRemote };
case DbItemKind.RemoteUserDefinedList:
return {
kind: ExpandedDbItemKind.RemoteUserDefinedList,
listName: dbItem.listName,
};
default:
throw Error(`Unknown db item kind ${dbItem.kind}`);
}
}

function isDbItemEqualToExpandedDbItem(
dbItem: DbItem,
expandedDbItem: ExpandedDbItem,
) {
switch (dbItem.kind) {
case DbItemKind.RootLocal:
return expandedDbItem.kind === ExpandedDbItemKind.RootLocal;
case DbItemKind.LocalList:
return (
expandedDbItem.kind === ExpandedDbItemKind.LocalUserDefinedList &&
expandedDbItem.listName === dbItem.listName
);
case DbItemKind.RootRemote:
return expandedDbItem.kind === ExpandedDbItemKind.RootRemote;
case DbItemKind.RemoteUserDefinedList:
return (
expandedDbItem.kind === ExpandedDbItemKind.RemoteUserDefinedList &&
expandedDbItem.listName === dbItem.listName
);
default:
throw Error(`Unknown db item kind ${dbItem.kind}`);
}
}
4 changes: 4 additions & 0 deletions extensions/ql-vscode/src/databases/db-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@ export enum DbItemKind {

export interface RootLocalDbItem {
kind: DbItemKind.RootLocal;
expanded: boolean;
children: LocalDbItem[];
}

export type LocalDbItem = LocalListDbItem | LocalDatabaseDbItem;

export interface LocalListDbItem {
kind: DbItemKind.LocalList;
expanded: boolean;
selected: boolean;
listName: string;
databases: LocalDatabaseDbItem[];
Expand All @@ -37,6 +39,7 @@ export interface LocalDatabaseDbItem {

export interface RootRemoteDbItem {
kind: DbItemKind.RootRemote;
expanded: boolean;
children: RemoteDbItem[];
}

Expand All @@ -62,6 +65,7 @@ export interface RemoteSystemDefinedListDbItem {

export interface RemoteUserDefinedListDbItem {
kind: DbItemKind.RemoteUserDefinedList;
expanded: boolean;
selected: boolean;
listName: string;
repos: RemoteRepoDbItem[];
Expand Down
19 changes: 19 additions & 0 deletions extensions/ql-vscode/src/databases/db-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AppEvent, AppEventEmitter } from "../common/events";
import { ValueResult } from "../common/value-result";
import { DbConfigStore } from "./config/db-config-store";
import { DbItem } from "./db-item";
import { calculateNewExpandedState } from "./db-item-expansion";
import {
getSelectedDbItem,
mapDbItemToSelectedDbItem,
Expand Down Expand Up @@ -54,4 +55,22 @@ export class DbManager {
await this.dbConfigStore.setSelectedDbItem(selectedDbItem);
}
}

public async updateDbItemExpandedState(
dbItem: DbItem,
itemExpanded: boolean,
): Promise<void> {
const configResult = this.dbConfigStore.getConfig();
if (configResult.isFailure) {
throw Error("Cannot update expanded state if config is not loaded");
}

const newExpandedItems = calculateNewExpandedState(
configResult.value.expanded,
dbItem,
itemExpanded,
);

await this.dbConfigStore.updateExpandedState(newExpandedItems);
}
}
29 changes: 29 additions & 0 deletions extensions/ql-vscode/src/databases/db-tree-creator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
DbConfig,
ExpandedDbItemKind,
LocalDatabase,
LocalList,
RemoteRepositoryList,
Expand Down Expand Up @@ -34,6 +35,10 @@ export function createRemoteTree(dbConfig: DbConfig): RootRemoteDbItem {
createRepoItem(r, dbConfig),
);

const expanded =
dbConfig.expanded &&
dbConfig.expanded.some((e) => e.kind === ExpandedDbItemKind.RootRemote);

return {
kind: DbItemKind.RootRemote,
children: [
Expand All @@ -42,6 +47,7 @@ export function createRemoteTree(dbConfig: DbConfig): RootRemoteDbItem {
...userDefinedRepoLists,
...repos,
],
expanded: !!expanded,
};
}

Expand All @@ -53,9 +59,14 @@ export function createLocalTree(dbConfig: DbConfig): RootLocalDbItem {
createLocalDb(l, dbConfig),
);

const expanded =
dbConfig.expanded &&
dbConfig.expanded.some((e) => e.kind === ExpandedDbItemKind.RootLocal);

return {
kind: DbItemKind.RootLocal,
children: [...localLists, ...localDbs],
expanded: !!expanded,
};
}

Expand Down Expand Up @@ -88,11 +99,20 @@ function createRemoteUserDefinedList(
dbConfig.selected.kind === SelectedDbItemKind.RemoteUserDefinedList &&
dbConfig.selected.listName === list.name;

const expanded =
dbConfig.expanded &&
dbConfig.expanded.some(
(e) =>
e.kind === ExpandedDbItemKind.RemoteUserDefinedList &&
e.listName === list.name,
);

return {
kind: DbItemKind.RemoteUserDefinedList,
listName: list.name,
repos: list.repositories.map((r) => createRepoItem(r, dbConfig, list.name)),
selected: !!selected,
expanded: !!expanded,
};
}

Expand Down Expand Up @@ -134,11 +154,20 @@ function createLocalList(list: LocalList, dbConfig: DbConfig): LocalListDbItem {
dbConfig.selected.kind === SelectedDbItemKind.LocalUserDefinedList &&
dbConfig.selected.listName === list.name;

const expanded =
dbConfig.expanded &&
dbConfig.expanded.some(
(e) =>
e.kind === ExpandedDbItemKind.LocalUserDefinedList &&
e.listName === list.name,
);

return {
kind: DbItemKind.LocalList,
listName: list.name,
databases: list.databases.map((d) => createLocalDb(d, dbConfig, list.name)),
selected: !!selected,
expanded: !!expanded,
};
}

Expand Down
27 changes: 26 additions & 1 deletion extensions/ql-vscode/src/databases/ui/db-panel.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { window, workspace } from "vscode";
import { TreeViewExpansionEvent, window, workspace } from "vscode";
import { commandRunner } from "../../commandRunner";
import { DisposableObject } from "../../pure/disposable-object";
import { DbManager } from "../db-manager";
Expand All @@ -18,6 +18,9 @@ export class DbPanel extends DisposableObject {
canSelectMany: false,
});

treeView.onDidCollapseElement.bind(this.onDidCollapseElement);
treeView.onDidExpandElement.bind(this.onDidExpandElement);

this.push(treeView);
}

Expand Down Expand Up @@ -49,4 +52,26 @@ export class DbPanel extends DisposableObject {
}
await this.dbManager.setSelectedDbItem(treeViewItem.dbItem);
}

private async onDidCollapseElement(
event: TreeViewExpansionEvent<DbTreeViewItem>,
): Promise<void> {
const dbItem = event.element.dbItem;
if (!dbItem) {
throw Error("Expected a database item.");
}

await this.dbManager.updateDbItemExpandedState(event.element.dbItem, false);
}

private async onDidExpandElement(
event: TreeViewExpansionEvent<DbTreeViewItem>,
): Promise<void> {
const dbItem = event.element.dbItem;
if (!dbItem) {
throw Error("Expected a database item.");
}

await this.dbManager.updateDbItemExpandedState(event.element.dbItem, true);
}
}
12 changes: 10 additions & 2 deletions extensions/ql-vscode/src/databases/ui/db-tree-view-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function createDbTreeViewItemRoot(
undefined,
label,
tooltip,
vscode.TreeItemCollapsibleState.Collapsed,
getCollapsibleState(dbItem.expanded),
children,
);
}
Expand Down Expand Up @@ -100,7 +100,7 @@ export function createDbTreeViewItemUserDefinedList(
undefined,
listName,
undefined,
vscode.TreeItemCollapsibleState.Collapsed,
getCollapsibleState(dbItem.expanded),
children,
);
}
Expand Down Expand Up @@ -147,3 +147,11 @@ export function createDbTreeViewItemLocalDatabase(
[],
);
}

function getCollapsibleState(
expanded: boolean,
): vscode.TreeItemCollapsibleState {
return expanded
? vscode.TreeItemCollapsibleState.Expanded
: vscode.TreeItemCollapsibleState.Collapsed;
}
Loading