Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expand a collapsed collection when creating items #432

Merged
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
85 changes: 78 additions & 7 deletions fusion-studio-extension/src/browser/core.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { injectable, inject } from "inversify";
import { v4 } from "uuid";
import { FSNode, FSDocumentNode, FSCollectionNode, FSToolbarNode, FSConnectionNode, FSItemNode, FSSecurityNode, FSUsersNode, FSGroupsNode, FSUserNode, FSGroupNode, FSContainerNode, FSIndexesNode, FSIndexNode, FSRestNode, FSRestURINode, FSRestMethodNode } from "../classes/node";
import { FSNode, FSDocumentNode, FSCollectionNode, FSToolbarNode, FSConnectionNode, FSItemNode, FSSecurityNode, FSUsersNode, FSGroupsNode, FSUserNode, FSGroupNode, FSContainerNode, FSIndexesNode, FSIndexNode, FSRestNode, FSRestURINode, FSRestMethodNode, FSLoadEvent } from "../classes/node";
import { open, TreeNode, CompositeTreeNode, ConfirmDialog, SingleTextInputDialog, OpenerService, StatusBar, StatusBarAlignment, WidgetManager } from "@theia/core/lib/browser";
import { WorkspaceService } from "@theia/workspace/lib/browser";
import { OpenFileDialogProps, FileDialogService } from "@theia/filesystem/lib/browser";
Expand Down Expand Up @@ -66,6 +66,7 @@ export class FSCore {
updating = false;
renaming = '';
dict: Record<string, FSNode> = {};
loadEvents: Record<string, (FSLoadEvent)[]> = {};

setLabelProvider(labelProvider: FSLabelProviderContribution) {
this._labelProvider = labelProvider;
Expand Down Expand Up @@ -193,6 +194,9 @@ export class FSCore {
}

protected removeNode(child: FSNode) {
if (this.loadEvents[child.id]) {
delete(this.loadEvents[child.id]);
}
const removeNodeId = (node: FSNode) => {
delete(this.dict[node.nodeId]);
if (CompositeTreeNode.is(node)) {
Expand Down Expand Up @@ -255,8 +259,29 @@ export class FSCore {
}
}

public expand(node: CompositeTreeNode) {
this.model && this.model.expandNode(node as any);
public async expand(node: CompositeTreeNode) {
this.model && await this.model.expandNode(node as any);
}

public expandAndWait(node: FSContainerNode) {
return new Promise(resolve => {
if (node.loaded) {
this.expand(node);
resolve(null);
} else {
this.addLoadEvent(node, node => {
resolve(null);
return true;
});
this.expand(node);
}
})
}

public async ensureExpanded(node: FSContainerNode) {
if (!node.expanded) {
await this.expandAndWait(node);
}
}

public getNode(id: string): FSNode | undefined {
Expand Down Expand Up @@ -361,10 +386,54 @@ export class FSCore {
return false;
}

protected endLoading(node: TreeNode): void {
protected async endLoading(node: TreeNode) {
if (FSNode.is(node)) {
node.loading = false;
this.refresh();
await this.refresh();
if (this.loadEvents[node.id]) {
// const a =
this.loadEvents[node.id] = await (await Promise.all(this.loadEvents[node.id].map(async event => {
const result = event(node);
if (!result) {
return event;
}
if (result === true) {
return null;
}
return await result ? null : event
}))).filter(event => event != null) as FSLoadEvent[];
if (this.loadEvents[node.id].length < 1) {
delete(this.loadEvents[node.id]);
}
}
}
(window as any).loadEvents = this.loadEvents;
}

protected addLoadEvent(node: TreeNode, event: FSLoadEvent): void {
if (FSNode.is(node)) {
if (!this.loadEvents[node.id]) {
this.loadEvents[node.id] = [event];
} else {
if (!this.loadEvents[node.id].find(value => value === event)) {
this.loadEvents[node.id].push(event);
}
}
}
}

protected removeLoadEvent(node: TreeNode, event?: FSLoadEvent): void {
if (FSNode.is(node)) {
if (this.loadEvents[node.id]) {
if (event) {
this.loadEvents[node.id] = this.loadEvents[node.id].filter(value => value != event);
if (this.loadEvents[node.id].length < 1) {
delete(this.loadEvents[node.id]);
}
} else {
delete(this.loadEvents[node.id]);
}
}
}
}

Expand All @@ -374,7 +443,7 @@ export class FSCore {
if (FSItem.isCollection(result)) {
const collection = result;
// refresh collections
let collectionsOld = node.children.filter(child => FSNode.isCollection(child)) as FSCollectionNode[];
let collectionsOld = node.children.filter(child => FSNode.isCollection(child) && !child.isNew) as FSCollectionNode[];
const collectionsNew = collection.collections.filter(subCollection => {
const collectionNode = this.getNode(this.itemID(node.connectionNode.connection, subCollection));
if (FSNode.isCollection(collectionNode) && collectionNode.parent === node) {
Expand All @@ -387,7 +456,7 @@ export class FSCore {
collectionsOld.forEach(node => this.removeNode(node));
collectionsNew.forEach(collection => this.addCollection(node, collection));
// refresh documents
let documentsOld = node.children.filter(child => FSNode.isDocument(child)) as FSDocumentNode[];
let documentsOld = node.children.filter(child => FSNode.isDocument(child) && !child.isNew) as FSDocumentNode[];
const documentsNew = collection.documents.filter(subDocument => {
const documentNode = this.getNode(this.itemID(node.connectionNode.connection, subDocument));
if (FSNode.isDocument(documentNode) && documentNode.parent === node) {
Expand Down Expand Up @@ -1449,6 +1518,7 @@ export class FSCore {
return false;
}
const collection = this.node as FSCollectionNode;
await this.ensureExpanded(collection);
const validator = (input: string) => input !== '' && !this.fileExists(input);
let initialName = this.newName(validator);
if (extension) {
Expand Down Expand Up @@ -1544,6 +1614,7 @@ export class FSCore {
}
}
if (FSNode.isCollection(collection)) {
await this.ensureExpanded(collection);
const validator = (input: string) => input !== '' && !this.fileExists(input);
const dialog = new SingleTextInputDialog({
initialValue: this.newName(validator),
Expand Down
2 changes: 2 additions & 0 deletions fusion-studio-extension/src/classes/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { FSRestURI, FSRestMethod } from "./rest";


export type FSNodeType = 'connection' | 'toolbar' | 'item' | 'users' | 'groups' | 'user' | 'group' | 'security' | 'indexes' | 'index' | 'rest' | 'rest-uri' | 'rest-method';
export type FSLoadEvent = (mode: FSNode) => void | true | Promise<void | true>;

export interface FSNode extends TreeNode {
type: FSNodeType;
connectionNode: FSConnectionNode;
Expand Down