mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +00:00
Migrate resource tree to react (#941)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { stringifyNotebook } from "@nteract/commutable";
|
||||
import { FileType, IContent, IContentProvider, IEmptyContent, ServerConfig } from "@nteract/core";
|
||||
import { cloneDeep } from "lodash";
|
||||
import { AjaxResponse } from "rxjs/ajax";
|
||||
import * as StringUtils from "../../Utils/StringUtils";
|
||||
import * as FileSystemUtil from "./FileSystemUtil";
|
||||
@@ -14,7 +15,17 @@ export class NotebookContentClient {
|
||||
* This updates the item and points all the children's parent to this item
|
||||
* @param item
|
||||
*/
|
||||
public updateItemChildren(item: NotebookContentItem): Promise<void> {
|
||||
public async updateItemChildren(item: NotebookContentItem): Promise<NotebookContentItem> {
|
||||
const subItems = await this.fetchNotebookFiles(item.path);
|
||||
const clonedItem = cloneDeep(item);
|
||||
subItems.forEach((subItem) => (subItem.parent = clonedItem));
|
||||
clonedItem.children = subItems;
|
||||
|
||||
return clonedItem;
|
||||
}
|
||||
|
||||
// TODO: Delete this function when ResourceTreeAdapter is removed.
|
||||
public async updateItemChildrenInPlace(item: NotebookContentItem): Promise<void> {
|
||||
return this.fetchNotebookFiles(item.path).then((subItems) => {
|
||||
item.children = subItems;
|
||||
subItems.forEach((subItem) => (subItem.parent = item));
|
||||
@@ -55,18 +66,20 @@ export class NotebookContentClient {
|
||||
});
|
||||
}
|
||||
|
||||
public deleteContentItem(item: NotebookContentItem): Promise<void> {
|
||||
return this.deleteNotebookFile(item.path).then((path: string) => {
|
||||
if (!path || path !== item.path) {
|
||||
throw new Error("No path provided");
|
||||
}
|
||||
public async deleteContentItem(item: NotebookContentItem): Promise<void> {
|
||||
const path = await this.deleteNotebookFile(item.path);
|
||||
useNotebook.getState().deleteNotebookItem(item);
|
||||
|
||||
if (item.parent && item.parent.children) {
|
||||
// Remove deleted child
|
||||
const newChildren = item.parent.children.filter((child) => child.path !== path);
|
||||
item.parent.children = newChildren;
|
||||
}
|
||||
});
|
||||
// TODO: Delete once old resource tree is removed
|
||||
if (!path || path !== item.path) {
|
||||
throw new Error("No path provided");
|
||||
}
|
||||
|
||||
if (item.parent && item.parent.children) {
|
||||
// Remove deleted child
|
||||
const newChildren = item.parent.children.filter((child) => child.path !== path);
|
||||
item.parent.children = newChildren;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { cloneDeep } from "lodash";
|
||||
import create, { UseStore } from "zustand";
|
||||
import { AuthType } from "../../AuthType";
|
||||
import * as Constants from "../../Common/Constants";
|
||||
@@ -5,8 +6,12 @@ import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
|
||||
import * as Logger from "../../Common/Logger";
|
||||
import { configContext } from "../../ConfigContext";
|
||||
import * as DataModels from "../../Contracts/DataModels";
|
||||
import { Action, ActionModifiers } from "../../Shared/Telemetry/TelemetryConstants";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { userContext } from "../../UserContext";
|
||||
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
|
||||
import { NotebookContentItem, NotebookContentItemType } from "./NotebookContentItem";
|
||||
import NotebookManager from "./NotebookManager";
|
||||
|
||||
interface NotebookState {
|
||||
isNotebookEnabled: boolean;
|
||||
@@ -18,6 +23,9 @@ interface NotebookState {
|
||||
isShellEnabled: boolean;
|
||||
notebookBasePath: string;
|
||||
isInitializingNotebooks: boolean;
|
||||
myNotebooksContentRoot: NotebookContentItem;
|
||||
gitHubNotebooksContentRoot: NotebookContentItem;
|
||||
galleryContentRoot: NotebookContentItem;
|
||||
setIsNotebookEnabled: (isNotebookEnabled: boolean) => void;
|
||||
setIsNotebooksEnabledForAccount: (isNotebooksEnabledForAccount: boolean) => void;
|
||||
setNotebookServerInfo: (notebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo) => void;
|
||||
@@ -27,9 +35,13 @@ interface NotebookState {
|
||||
setIsShellEnabled: (isShellEnabled: boolean) => void;
|
||||
setNotebookBasePath: (notebookBasePath: string) => void;
|
||||
refreshNotebooksEnabledStateForAccount: () => Promise<void>;
|
||||
findItem: (root: NotebookContentItem, item: NotebookContentItem) => NotebookContentItem;
|
||||
updateNotebookItem: (item: NotebookContentItem) => void;
|
||||
deleteNotebookItem: (item: NotebookContentItem) => void;
|
||||
initializeNotebooksTree: (notebookManager: NotebookManager) => Promise<void>;
|
||||
}
|
||||
|
||||
export const useNotebook: UseStore<NotebookState> = create((set) => ({
|
||||
export const useNotebook: UseStore<NotebookState> = create((set, get) => ({
|
||||
isNotebookEnabled: false,
|
||||
isNotebooksEnabledForAccount: false,
|
||||
notebookServerInfo: {
|
||||
@@ -46,6 +58,9 @@ export const useNotebook: UseStore<NotebookState> = create((set) => ({
|
||||
isShellEnabled: false,
|
||||
notebookBasePath: Constants.Notebook.defaultBasePath,
|
||||
isInitializingNotebooks: false,
|
||||
myNotebooksContentRoot: undefined,
|
||||
gitHubNotebooksContentRoot: undefined,
|
||||
galleryContentRoot: undefined,
|
||||
setIsNotebookEnabled: (isNotebookEnabled: boolean) => set({ isNotebookEnabled }),
|
||||
setIsNotebooksEnabledForAccount: (isNotebooksEnabledForAccount: boolean) => set({ isNotebooksEnabledForAccount }),
|
||||
setNotebookServerInfo: (notebookServerInfo: DataModels.NotebookWorkspaceConnectionInfo) =>
|
||||
@@ -103,4 +118,92 @@ export const useNotebook: UseStore<NotebookState> = create((set) => ({
|
||||
set({ isNotebooksEnabledForAccount: false });
|
||||
}
|
||||
},
|
||||
findItem: (root: NotebookContentItem, item: NotebookContentItem): NotebookContentItem => {
|
||||
const currentItem = root || get().myNotebooksContentRoot;
|
||||
|
||||
if (currentItem) {
|
||||
if (currentItem.path === item.path && currentItem.name === item.name) {
|
||||
return currentItem;
|
||||
}
|
||||
|
||||
if (currentItem.children) {
|
||||
for (const childItem of currentItem.children) {
|
||||
const result = get().findItem(childItem, item);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
updateNotebookItem: (item: NotebookContentItem): void => {
|
||||
const root = cloneDeep(get().myNotebooksContentRoot);
|
||||
const parentItem = get().findItem(root, item.parent);
|
||||
parentItem.children = parentItem.children.filter((child) => child.path !== item.path);
|
||||
parentItem.children.push(item);
|
||||
item.parent = parentItem;
|
||||
set({ myNotebooksContentRoot: root });
|
||||
},
|
||||
deleteNotebookItem: (item: NotebookContentItem): void => {
|
||||
const root = cloneDeep(get().myNotebooksContentRoot);
|
||||
const parentItem = get().findItem(root, item.parent);
|
||||
parentItem.children = parentItem.children.filter((child) => child.path !== item.path);
|
||||
set({ myNotebooksContentRoot: root });
|
||||
},
|
||||
initializeNotebooksTree: async (notebookManager: NotebookManager): Promise<void> => {
|
||||
set({
|
||||
myNotebooksContentRoot: {
|
||||
name: "My Notebooks",
|
||||
path: get().notebookBasePath,
|
||||
type: NotebookContentItemType.Directory,
|
||||
},
|
||||
galleryContentRoot: {
|
||||
name: "Gallery",
|
||||
path: "Gallery",
|
||||
type: NotebookContentItemType.File,
|
||||
},
|
||||
});
|
||||
|
||||
if (notebookManager?.gitHubOAuthService?.isLoggedIn()) {
|
||||
set({
|
||||
gitHubNotebooksContentRoot: {
|
||||
name: "GitHub repos",
|
||||
path: "PsuedoDir",
|
||||
type: NotebookContentItemType.Directory,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (get().notebookServerInfo?.notebookServerEndpoint) {
|
||||
const updatedRoot = await notebookManager?.notebookContentClient?.updateItemChildren({
|
||||
name: "My Notebooks",
|
||||
path: get().notebookBasePath,
|
||||
type: NotebookContentItemType.Directory,
|
||||
});
|
||||
set({ myNotebooksContentRoot: updatedRoot });
|
||||
|
||||
if (updatedRoot?.children) {
|
||||
// Count 1st generation children (tree is lazy-loaded)
|
||||
const nodeCounts = { files: 0, notebooks: 0, directories: 0 };
|
||||
updatedRoot.children.forEach((notebookItem) => {
|
||||
switch (notebookItem.type) {
|
||||
case NotebookContentItemType.File:
|
||||
nodeCounts.files++;
|
||||
break;
|
||||
case NotebookContentItemType.Directory:
|
||||
nodeCounts.directories++;
|
||||
break;
|
||||
case NotebookContentItemType.Notebook:
|
||||
nodeCounts.notebooks++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
TelemetryProcessor.trace(Action.RefreshResourceTreeMyNotebooks, ActionModifiers.Mark, { ...nodeCounts });
|
||||
}
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user