-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
OpenDialog Plugin API #2398
OpenDialog Plugin API #2398
Conversation
I will review the core part next week. |
[name: string]: string[]; | ||
} | ||
|
||
export class FileDialogTreeFiltersRenderer extends VirtualRenderer { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should not use VirtualRenderer
anymore, please read deprecation note
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Used ReactRenderer
like in LocationListRenderer
const result = await Promise.all( | ||
fileStat.children | ||
.filter(child => { | ||
return this.visible(child); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please get rid of linting warnings in new files
* | ||
* @param fileStat resource to check | ||
*/ | ||
protected visible(fileStat: FileStat): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
method name should start from a verb: visible
-> filter
os isFiltered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to isVisible(..)
@@ -31,13 +32,16 @@ export function createFileDialogContainer(parent: interfaces.Container): Contain | |||
child.unbind(FileTreeWidget); | |||
child.bind(FileDialogWidget).toSelf(); | |||
|
|||
child.bind(FileDialogTree).toSelf(); | |||
child.rebind(Tree).toDynamicValue(ctx => ctx.container.get(FileDialogTree)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
child.rebind(Tree).toService(FileDialogTree);
toService
should be used for transitive bindings, toDynamicValue
is an old workaround
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks!
export function createFileDialog(parent: interfaces.Container, props: FileDialogProps): FileDialog { | ||
const container = createFileDialogContainer(parent); | ||
export function createFileDialog(parent: interfaces.Container, props: FileDialogProps, treeProps?: TreeProps): FileDialog { | ||
const container = createFileDialogContainer(parent, treeProps); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TreeProps
are supposed to be rebound, please revert and rebind them here:
const container = createFileDialogContainer(parent);
container.rebind(TreeProps).toConstantValue({
...defaultTreeProps,
multiSelect: props.canSelectMany
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Thanks!
import { FileTree } from "./file-tree"; | ||
import { FileTreeModel } from './file-tree-model'; | ||
import { FileTreeWidget } from "./file-tree-widget"; | ||
|
||
export function createFileTreeContainer(parent: interfaces.Container): Container { | ||
const child = createTreeContainer(parent); | ||
export function createFileTreeContainer(parent: interfaces.Container, treeProps?: TreeProps): Container { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please revert this file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted
@@ -24,7 +24,7 @@ import { TreeExpansionService, TreeExpansionServiceImpl } from "./tree-expansion | |||
import { TreeNavigationService } from './tree-navigation'; | |||
import { TreeDecoratorService, NoopTreeDecoratorService } from './tree-decorator'; | |||
|
|||
export function createTreeContainer(parent: interfaces.Container): Container { | |||
export function createTreeContainer(parent: interfaces.Container, treeProps?: TreeProps): Container { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please revert this file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted
const name = this.labelProvider.getName(rootUri); | ||
const label = await this.labelProvider.getIcon(root); | ||
const name = this.labelProvider.getName(rootStat); | ||
const label = await this.labelProvider.getIcon(rootStat); | ||
const rootNode = DirNode.createRoot(rootStat, name, label); | ||
const dialog = this.fileDialogFactory({ title: HostedPluginCommands.SELECT_PATH.label! }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we somehow trick ts to return a result of different types depending on incoming dialog parameters? i.e. if multiSelect
is not true, then it should be a single file select dialog that clients don't need to check for other cases. Type guards below are redundant, woud be nice to remove unnecessary code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reworked a little bit. Could you please give a look again?
const result = await dialog.open(); | ||
|
||
// Check the result | ||
if (result) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you seen UriSelection.getUris
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reworked
const node = await dialog.open(); | ||
this.openFile(node); | ||
const result = await dialog.open(); | ||
if (result instanceof Array) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should find a way to get rid it of it. all type checking is redundant here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added FileSelection
return type and wrote a corresponding namespace with set of functions like UriSelection
.
de3a125
to
68e8ef4
Compare
|
||
export type FileSelection = Readonly<FileStatNode> | Readonly<FileStatNode>[] | undefined; | ||
|
||
export namespace FileSelection { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the confusion, I meant you can just use UriSelection
, FileSelection
is redundant, i.e.
const uri = UriSelection.getUri(await dialog.open());
const URIs = UriSelection.getUris(await dialog.open());
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we expect multiple files here? It could be:
if (FileStatNode.is(result)) {
this.open(result);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was a workaround. But it could be working when the dialog will return an array.
I used MaybeArray
for the file dialog
class FileDialog extends AbstractDialog<MaybeArray<FileStatNode>>
Then it gives FileStatNode | FileStatNode[] | undeifned
But FileStatNode.is(..)
receives only node: TreeNode | undefined
and it's not suitable for an array. I think we have to improve FileStatNode
somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feel free to change FileStatNode.is
that it accepts an arg of object | undefined
type: https://github.com/theia-ide/theia/blob/3ef537c96f57cb1c9ebb1b331e8c93bc0fb74db1/packages/filesystem/src/browser/file-tree/file-tree.ts#L96
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it :)
} | ||
|
||
@injectable() | ||
export class FileDialog extends AbstractDialog<Readonly<FileStatNode> | undefined> { | ||
export class FileDialog extends AbstractDialog<FileSelection> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi: AbstractDialog<MaybeArray<FileStatNode>>
c5b882e
to
7b33b0f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Signed-off-by: Vitaliy Gulyy <vgulyy@redhat.com>
9d89ee8
to
840b49f
Compare
Implementation of Open Dialog Plugin API
Issue #2153
Depends on #2401
Signed-off-by: Vitaliy Gulyy vgulyy@redhat.com