|
1 | 1 | import { injectable, inject } from "inversify"; |
2 | 2 | import { v4 } from "uuid"; |
3 | | -import { FSNode, FSDocumentNode, FSCollectionNode, FSToolbarNode, FSConnectionNode, FSItemNode, FSSecurityNode, FSUsersNode, FSGroupsNode, FSUserNode, FSGroupNode, FSContainerNode, FSIndexesNode, FSIndexNode, FSRestNode, FSRestURINode, FSRestMethodNode } from "../classes/node"; |
| 3 | +import { FSNode, FSDocumentNode, FSCollectionNode, FSToolbarNode, FSConnectionNode, FSItemNode, FSSecurityNode, FSUsersNode, FSGroupsNode, FSUserNode, FSGroupNode, FSContainerNode, FSIndexesNode, FSIndexNode, FSRestNode, FSRestURINode, FSRestMethodNode, FSLoadEvent } from "../classes/node"; |
4 | 4 | import { open, TreeNode, CompositeTreeNode, ConfirmDialog, SingleTextInputDialog, OpenerService, StatusBar, StatusBarAlignment, WidgetManager } from "@theia/core/lib/browser"; |
5 | 5 | import { WorkspaceService } from "@theia/workspace/lib/browser"; |
6 | 6 | import { OpenFileDialogProps, FileDialogService } from "@theia/filesystem/lib/browser"; |
@@ -65,6 +65,7 @@ export class FSCore { |
65 | 65 | updating = false; |
66 | 66 | renaming = ''; |
67 | 67 | dict: Record<string, FSNode> = {}; |
| 68 | + loadEvents: Record<string, (FSLoadEvent)[]> = {}; |
68 | 69 |
|
69 | 70 | setLabelProvider(labelProvider: FSLabelProviderContribution) { |
70 | 71 | this._labelProvider = labelProvider; |
@@ -192,6 +193,9 @@ export class FSCore { |
192 | 193 | } |
193 | 194 |
|
194 | 195 | protected removeNode(child: FSNode) { |
| 196 | + if (this.loadEvents[child.id]) { |
| 197 | + delete(this.loadEvents[child.id]); |
| 198 | + } |
195 | 199 | const removeNodeId = (node: FSNode) => { |
196 | 200 | delete(this.dict[node.nodeId]); |
197 | 201 | if (CompositeTreeNode.is(node)) { |
@@ -254,8 +258,24 @@ export class FSCore { |
254 | 258 | } |
255 | 259 | } |
256 | 260 |
|
257 | | - public expand(node: CompositeTreeNode) { |
258 | | - this.model && this.model.expandNode(node as any); |
| 261 | + public async expand(node: CompositeTreeNode) { |
| 262 | + this.model && await this.model.expandNode(node as any); |
| 263 | + } |
| 264 | + |
| 265 | + public expandAndWait(node: FSContainerNode) { |
| 266 | + return new Promise(resolve => { |
| 267 | + this.addLoadEvent(node, node => { |
| 268 | + resolve(null); |
| 269 | + return true; |
| 270 | + }); |
| 271 | + this.expand(node); |
| 272 | + }) |
| 273 | + } |
| 274 | + |
| 275 | + public async ensureExpanded(node: FSContainerNode) { |
| 276 | + if (!node.expanded && !node.loaded) { |
| 277 | + await this.expandAndWait(node); |
| 278 | + } |
259 | 279 | } |
260 | 280 |
|
261 | 281 | public getNode(id: string): FSNode | undefined { |
@@ -360,10 +380,54 @@ export class FSCore { |
360 | 380 | return false; |
361 | 381 | } |
362 | 382 |
|
363 | | - protected endLoading(node: TreeNode): void { |
| 383 | + protected async endLoading(node: TreeNode) { |
364 | 384 | if (FSNode.is(node)) { |
365 | 385 | node.loading = false; |
366 | | - this.refresh(); |
| 386 | + await this.refresh(); |
| 387 | + if (this.loadEvents[node.id]) { |
| 388 | + // const a = |
| 389 | + this.loadEvents[node.id] = await (await Promise.all(this.loadEvents[node.id].map(async event => { |
| 390 | + const result = event(node); |
| 391 | + if (!result) { |
| 392 | + return event; |
| 393 | + } |
| 394 | + if (result === true) { |
| 395 | + return null; |
| 396 | + } |
| 397 | + return await result ? null : event |
| 398 | + }))).filter(event => event != null) as FSLoadEvent[]; |
| 399 | + if (this.loadEvents[node.id].length < 1) { |
| 400 | + delete(this.loadEvents[node.id]); |
| 401 | + } |
| 402 | + } |
| 403 | + } |
| 404 | + (window as any).loadEvents = this.loadEvents; |
| 405 | + } |
| 406 | + |
| 407 | + protected addLoadEvent(node: TreeNode, event: FSLoadEvent): void { |
| 408 | + if (FSNode.is(node)) { |
| 409 | + if (!this.loadEvents[node.id]) { |
| 410 | + this.loadEvents[node.id] = [event]; |
| 411 | + } else { |
| 412 | + if (!this.loadEvents[node.id].find(value => value === event)) { |
| 413 | + this.loadEvents[node.id].push(event); |
| 414 | + } |
| 415 | + } |
| 416 | + } |
| 417 | + } |
| 418 | + |
| 419 | + protected removeLoadEvent(node: TreeNode, event?: FSLoadEvent): void { |
| 420 | + if (FSNode.is(node)) { |
| 421 | + if (this.loadEvents[node.id]) { |
| 422 | + if (event) { |
| 423 | + this.loadEvents[node.id] = this.loadEvents[node.id].filter(value => value != event); |
| 424 | + if (this.loadEvents[node.id].length < 1) { |
| 425 | + delete(this.loadEvents[node.id]); |
| 426 | + } |
| 427 | + } else { |
| 428 | + delete(this.loadEvents[node.id]); |
| 429 | + } |
| 430 | + } |
367 | 431 | } |
368 | 432 | } |
369 | 433 |
|
@@ -1450,6 +1514,7 @@ export class FSCore { |
1450 | 1514 | return false; |
1451 | 1515 | } |
1452 | 1516 | const collection = this.node as FSCollectionNode; |
| 1517 | + await this.ensureExpanded(collection); |
1453 | 1518 | const validator = (input: string) => input !== '' && !this.fileExists(input); |
1454 | 1519 | let initialName = this.newName(validator); |
1455 | 1520 | if (extension) { |
@@ -1545,6 +1610,7 @@ export class FSCore { |
1545 | 1610 | } |
1546 | 1611 | } |
1547 | 1612 | if (FSNode.isCollection(collection)) { |
| 1613 | + await this.ensureExpanded(collection); |
1548 | 1614 | const validator = (input: string) => input !== '' && !this.fileExists(input); |
1549 | 1615 | const dialog = new SingleTextInputDialog({ |
1550 | 1616 | initialValue: this.newName(validator), |
|
0 commit comments