|
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"; |
@@ -66,6 +66,7 @@ export class FSCore { |
66 | 66 | updating = false; |
67 | 67 | renaming = ''; |
68 | 68 | dict: Record<string, FSNode> = {}; |
| 69 | + loadEvents: Record<string, (FSLoadEvent)[]> = {}; |
69 | 70 |
|
70 | 71 | setLabelProvider(labelProvider: FSLabelProviderContribution) { |
71 | 72 | this._labelProvider = labelProvider; |
@@ -193,6 +194,9 @@ export class FSCore { |
193 | 194 | } |
194 | 195 |
|
195 | 196 | protected removeNode(child: FSNode) { |
| 197 | + if (this.loadEvents[child.id]) { |
| 198 | + delete(this.loadEvents[child.id]); |
| 199 | + } |
196 | 200 | const removeNodeId = (node: FSNode) => { |
197 | 201 | delete(this.dict[node.nodeId]); |
198 | 202 | if (CompositeTreeNode.is(node)) { |
@@ -255,8 +259,24 @@ export class FSCore { |
255 | 259 | } |
256 | 260 | } |
257 | 261 |
|
258 | | - public expand(node: CompositeTreeNode) { |
259 | | - this.model && this.model.expandNode(node as any); |
| 262 | + public async expand(node: CompositeTreeNode) { |
| 263 | + this.model && await this.model.expandNode(node as any); |
| 264 | + } |
| 265 | + |
| 266 | + public expandAndWait(node: FSContainerNode) { |
| 267 | + return new Promise(resolve => { |
| 268 | + this.addLoadEvent(node, node => { |
| 269 | + resolve(null); |
| 270 | + return true; |
| 271 | + }); |
| 272 | + this.expand(node); |
| 273 | + }) |
| 274 | + } |
| 275 | + |
| 276 | + public async ensureExpanded(node: FSContainerNode) { |
| 277 | + if (!node.expanded && !node.loaded) { |
| 278 | + await this.expandAndWait(node); |
| 279 | + } |
260 | 280 | } |
261 | 281 |
|
262 | 282 | public getNode(id: string): FSNode | undefined { |
@@ -361,10 +381,54 @@ export class FSCore { |
361 | 381 | return false; |
362 | 382 | } |
363 | 383 |
|
364 | | - protected endLoading(node: TreeNode): void { |
| 384 | + protected async endLoading(node: TreeNode) { |
365 | 385 | if (FSNode.is(node)) { |
366 | 386 | node.loading = false; |
367 | | - this.refresh(); |
| 387 | + await this.refresh(); |
| 388 | + if (this.loadEvents[node.id]) { |
| 389 | + // const a = |
| 390 | + this.loadEvents[node.id] = await (await Promise.all(this.loadEvents[node.id].map(async event => { |
| 391 | + const result = event(node); |
| 392 | + if (!result) { |
| 393 | + return event; |
| 394 | + } |
| 395 | + if (result === true) { |
| 396 | + return null; |
| 397 | + } |
| 398 | + return await result ? null : event |
| 399 | + }))).filter(event => event != null) as FSLoadEvent[]; |
| 400 | + if (this.loadEvents[node.id].length < 1) { |
| 401 | + delete(this.loadEvents[node.id]); |
| 402 | + } |
| 403 | + } |
| 404 | + } |
| 405 | + (window as any).loadEvents = this.loadEvents; |
| 406 | + } |
| 407 | + |
| 408 | + protected addLoadEvent(node: TreeNode, event: FSLoadEvent): void { |
| 409 | + if (FSNode.is(node)) { |
| 410 | + if (!this.loadEvents[node.id]) { |
| 411 | + this.loadEvents[node.id] = [event]; |
| 412 | + } else { |
| 413 | + if (!this.loadEvents[node.id].find(value => value === event)) { |
| 414 | + this.loadEvents[node.id].push(event); |
| 415 | + } |
| 416 | + } |
| 417 | + } |
| 418 | + } |
| 419 | + |
| 420 | + protected removeLoadEvent(node: TreeNode, event?: FSLoadEvent): void { |
| 421 | + if (FSNode.is(node)) { |
| 422 | + if (this.loadEvents[node.id]) { |
| 423 | + if (event) { |
| 424 | + this.loadEvents[node.id] = this.loadEvents[node.id].filter(value => value != event); |
| 425 | + if (this.loadEvents[node.id].length < 1) { |
| 426 | + delete(this.loadEvents[node.id]); |
| 427 | + } |
| 428 | + } else { |
| 429 | + delete(this.loadEvents[node.id]); |
| 430 | + } |
| 431 | + } |
368 | 432 | } |
369 | 433 | } |
370 | 434 |
|
@@ -1449,6 +1513,7 @@ export class FSCore { |
1449 | 1513 | return false; |
1450 | 1514 | } |
1451 | 1515 | const collection = this.node as FSCollectionNode; |
| 1516 | + await this.ensureExpanded(collection); |
1452 | 1517 | const validator = (input: string) => input !== '' && !this.fileExists(input); |
1453 | 1518 | let initialName = this.newName(validator); |
1454 | 1519 | if (extension) { |
@@ -1544,6 +1609,7 @@ export class FSCore { |
1544 | 1609 | } |
1545 | 1610 | } |
1546 | 1611 | if (FSNode.isCollection(collection)) { |
| 1612 | + await this.ensureExpanded(collection); |
1547 | 1613 | const validator = (input: string) => input !== '' && !this.fileExists(input); |
1548 | 1614 | const dialog = new SingleTextInputDialog({ |
1549 | 1615 | initialValue: this.newName(validator), |
|
0 commit comments