Replace subscriptions in resource tree with useDatabases hook (#904)

This commit is contained in:
victor-meng 2021-06-23 11:45:29 -07:00 committed by GitHub
parent b392bed1b0
commit 738a02a0f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 16 additions and 122 deletions

View File

@ -53,9 +53,6 @@ exports[`SettingsComponent renders 1`] = `
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"databaseCollectionIdMap": Map {},
"koSubsCollectionIdMap": Map {},
"koSubsDatabaseIdMap": Map {},
"parameters": [Function],
},
"resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken {
@ -145,9 +142,6 @@ exports[`SettingsComponent renders 1`] = `
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"databaseCollectionIdMap": Map {},
"koSubsCollectionIdMap": Map {},
"koSubsDatabaseIdMap": Map {},
"parameters": [Function],
},
"resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken {

View File

@ -42,9 +42,6 @@ exports[`GitHub Repos Panel should render Default properly 1`] = `
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"databaseCollectionIdMap": Map {},
"koSubsCollectionIdMap": Map {},
"koSubsDatabaseIdMap": Map {},
"parameters": [Function],
},
"resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken {

View File

@ -32,9 +32,6 @@ exports[`StringInput Pane should render Create new directory properly 1`] = `
"resourceTree": ResourceTreeAdapter {
"container": [Circular],
"copyNotebook": [Function],
"databaseCollectionIdMap": Map {},
"koSubsCollectionIdMap": Map {},
"koSubsDatabaseIdMap": Map {},
"parameters": [Function],
},
"resourceTreeForResourceToken": ResourceTreeAdapterForResourceToken {

View File

@ -175,6 +175,19 @@ export default class Collection implements ViewModels.Collection {
});
this.children = ko.observableArray<ViewModels.TreeNode>([]);
this.children.subscribe(() => {
// update the database in zustand store
const database = this.getDatabase();
database.collections(
database.collections()?.map((collection) => {
if (collection.id() === this.id()) {
return this;
}
return collection;
})
);
useDatabases.getState().updateDatabase(database);
});
this.storedProcedures = ko.computed(() => {
return this.children()

View File

@ -17,6 +17,7 @@ import { isServerlessAccount } from "../../Utils/CapabilityUtils";
import { logConsoleError } from "../../Utils/NotificationConsoleUtils";
import Explorer from "../Explorer";
import { DatabaseSettingsTabV2 } from "../Tabs/SettingsTabV2";
import { useDatabases } from "../useDatabases";
import Collection from "./Collection";
export default class Database implements ViewModels.Database {
@ -41,6 +42,7 @@ export default class Database implements ViewModels.Database {
this.id = ko.observable(data.id);
this.offer = ko.observable();
this.collections = ko.observableArray<Collection>();
this.collections.subscribe(() => useDatabases.getState().updateDatabase(this));
this.isDatabaseExpanded = ko.observable<boolean>(false);
this.selectedSubnodeKind = ko.observable<ViewModels.CollectionTabKind>();
this.isDatabaseShared = ko.pureComputed(() => {

View File

@ -12,7 +12,6 @@ import PublishIcon from "../../../images/notebook/publish_content.svg";
import RefreshIcon from "../../../images/refresh-cosmos.svg";
import CollectionIcon from "../../../images/tree-collection.svg";
import { ReactAdapter } from "../../Bindings/ReactBindingHandler";
import { ArrayHashMap } from "../../Common/ArrayHashMap";
import { Areas } from "../../Common/Constants";
import { isPublicInternetAccessAllowed } from "../../Common/DatabaseAccountUtility";
import * as DataModels from "../../Contracts/DataModels";
@ -52,10 +51,6 @@ export class ResourceTreeAdapter implements ReactAdapter {
public myNotebooksContentRoot: NotebookContentItem;
public gitHubNotebooksContentRoot: NotebookContentItem;
private koSubsDatabaseIdMap: ArrayHashMap<ko.Subscription>; // database id -> ko subs
private koSubsCollectionIdMap: ArrayHashMap<ko.Subscription>; // collection id -> ko subs
private databaseCollectionIdMap: ArrayHashMap<string>; // database id -> collection ids
public constructor(private container: Explorer) {
this.parameters = ko.observable(Date.now());
@ -63,22 +58,7 @@ export class ResourceTreeAdapter implements ReactAdapter {
this.container.tabsManager.activeTab.subscribe((newValue: TabsBase) => this.triggerRender());
this.container.isNotebookEnabled.subscribe((newValue) => this.triggerRender());
this.koSubsDatabaseIdMap = new ArrayHashMap();
this.koSubsCollectionIdMap = new ArrayHashMap();
this.databaseCollectionIdMap = new ArrayHashMap();
useDatabases.subscribe(
(databases: ViewModels.Database[]) => {
// Clean up old databases
this.cleanupDatabasesKoSubs();
databases.forEach((database: ViewModels.Database) => this.watchDatabase(database));
this.triggerRender();
},
(state) => state.databases
);
useDatabases.getState().databases.forEach((database: ViewModels.Database) => this.watchDatabase(database));
useDatabases.subscribe(() => this.triggerRender());
this.triggerRender();
}
@ -878,93 +858,4 @@ export class ResourceTreeAdapter implements ReactAdapter {
subnodeKinds.includes(selectedSubnodeKind)
);
}
// *************** watch all nested ko's inside database
// TODO Simplify so we don't have to do this
private watchCollection(databaseId: string, collection: ViewModels.Collection) {
this.addKoSubToCollectionId(
databaseId,
collection.id(),
collection.storedProcedures?.subscribe(() => {
this.triggerRender();
})
);
this.addKoSubToCollectionId(
databaseId,
collection.id(),
collection.isCollectionExpanded?.subscribe(() => {
this.triggerRender();
})
);
this.addKoSubToCollectionId(
databaseId,
collection.id(),
collection.isStoredProceduresExpanded?.subscribe(() => {
this.triggerRender();
})
);
}
private watchDatabase(database: ViewModels.Database) {
const databaseId = database.id();
const koSub = database.collections.subscribe((collections: ViewModels.Collection[]) => {
this.cleanupCollectionsKoSubs(
databaseId,
collections.map((collection: ViewModels.Collection) => collection.id())
);
collections.forEach((collection: ViewModels.Collection) => this.watchCollection(databaseId, collection));
this.triggerRender();
});
this.addKoSubToDatabaseId(databaseId, koSub);
database.collections().forEach((collection: ViewModels.Collection) => this.watchCollection(databaseId, collection));
}
private addKoSubToDatabaseId(databaseId: string, sub: ko.Subscription): void {
this.koSubsDatabaseIdMap.push(databaseId, sub);
}
private addKoSubToCollectionId(databaseId: string, collectionId: string, sub: ko.Subscription): void {
this.databaseCollectionIdMap.push(databaseId, collectionId);
this.koSubsCollectionIdMap.push(collectionId, sub);
}
private cleanupDatabasesKoSubs(): void {
for (const databaseId of this.koSubsDatabaseIdMap.keys()) {
this.koSubsDatabaseIdMap.get(databaseId).forEach((sub: ko.Subscription) => sub.dispose());
this.koSubsDatabaseIdMap.delete(databaseId);
if (this.databaseCollectionIdMap.has(databaseId)) {
this.databaseCollectionIdMap
.get(databaseId)
.forEach((collectionId: string) => this.cleanupKoSubsForCollection(databaseId, collectionId));
}
}
}
private cleanupCollectionsKoSubs(databaseId: string, existingCollectionIds: string[]): void {
if (!this.databaseCollectionIdMap.has(databaseId)) {
return;
}
const collectionIdsToRemove = this.databaseCollectionIdMap
.get(databaseId)
.filter((id: string) => existingCollectionIds.indexOf(id) === -1);
collectionIdsToRemove.forEach((id: string) => this.cleanupKoSubsForCollection(databaseId, id));
}
private cleanupKoSubsForCollection(databaseId: string, collectionId: string) {
if (!this.koSubsCollectionIdMap.has(collectionId)) {
return;
}
this.koSubsCollectionIdMap.get(collectionId).forEach((sub: ko.Subscription) => sub.dispose());
this.koSubsCollectionIdMap.delete(collectionId);
this.databaseCollectionIdMap.remove(databaseId, collectionId);
}
}