@@ -80,46 +80,77 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
80
80
. actionQuery ( sql , [ spec , dir , orderBy , system , flat , notStudio , generated ] )
81
81
. then ( ( data ) => data . result . content || [ ] )
82
82
. then ( ( data ) => {
83
- const results = data . map ( ( item : StudioOpenDialog ) => {
84
- // Handle how query returns web apps
85
- const name = item . Name . split ( "/" ) [ 0 ] ;
86
- const fullName = folder === "" ? name : folder + "/" + name ;
87
- if ( item . Type === "10" || item . Type === "9" ) {
88
- parent . entries . set ( name , new Directory ( name , fullName ) ) ;
89
- return [ name , vscode . FileType . Directory ] ;
90
- } else {
91
- return [ name , vscode . FileType . File ] ;
92
- }
93
- } ) ;
94
- if ( ! csp || results . length ) {
83
+ // If webapp '/' exists it will always list first
84
+ const rootWebAppExists = csp && data [ 0 ] ?. Name === "/" ;
85
+ const results = data
86
+ . filter ( ( item : StudioOpenDialog ) =>
87
+ item . Type === "10" ? csp && item . Name !== "/" : item . Type === "9" ? ! csp : ! rootWebAppExists
88
+ )
89
+ . map ( ( item : StudioOpenDialog ) => {
90
+ // Handle how query returns web apps
91
+ const name = item . Name . split ( "/" ) [ 0 ] ;
92
+ const fullName = folder === "" ? name : csp ? folder + name : folder + "/" + name ;
93
+ if ( item . Type === "10" || item . Type === "9" ) {
94
+ parent . entries . set ( name , new Directory ( name , fullName ) ) ;
95
+ return [ name , vscode . FileType . Directory ] ;
96
+ } else {
97
+ return [ name , vscode . FileType . File ] ;
98
+ }
99
+ } ) ;
100
+ if ( ! csp ) {
95
101
return results ;
96
102
}
97
- //TODO further request(s) to get the next level in CSP app names
98
- // e.g. folder root is isfs://server/?ns=USER&csp
99
- // and USER namespace is the home of /csp/app1 and /csp/app2
100
- // Initial expand showed the csp folder.
101
- // Expand of that came here and asked Studio dialog query for /csp/*
102
- // but this doesn't return app1 and app2 folders.
103
- return api
104
- . actionQuery ( sql , [ "/*.CSPALL" , dir , orderBy , system , flat , notStudio , generated ] )
105
- . then ( ( data ) => data . result . content || [ ] )
106
- . then ( ( data ) => {
107
- return results ;
108
- /*
109
- const results = data.map((item: StudioOpenDialog) => {
110
- // Handle how query returns web apps
111
- const name = item.Name.split("/")[0];
112
- const fullName = folder === "" ? name : folder + "/" + name;
113
- if (item.Type === "10" || item.Type === "9") {
114
- parent.entries.set(name, new Directory(name, fullName));
115
- return [name, vscode.FileType.Directory];
116
- } else {
117
- return [name, vscode.FileType.File];
118
- }
103
+ if ( folder !== "" ) {
104
+ // For CSP-type access at least one folder down, a further root-level request is done to check for next level in CSP app names
105
+ // e.g. folder root is isfs://server/?ns=USER&csp
106
+ // and USER namespace is the home of /csp/app1 and /csp/app2
107
+ // Initial expand showed the csp folder.
108
+ // Expand of that came here and asked Studio dialog query for /csp/*
109
+ // but this doesn't return app1 and app2 folders.
110
+ // Filter out as much as possible on the server side.
111
+ return api
112
+ . actionQuery ( sql , [
113
+ "*,'*.inc,'*.mac,'*.dtl,'*.cls,'*.bpl,'*.int,'*.prj" ,
114
+ dir ,
115
+ orderBy ,
116
+ "0" ,
117
+ "0" ,
118
+ notStudio ,
119
+ "0" ,
120
+ ] )
121
+ . then ( ( data ) => data . result . content || [ ] )
122
+ . then ( ( data ) => {
123
+ const piece = folder . split ( "/" ) . length - 1 ;
124
+ const cspSubdirs : [ string , vscode . FileType ] [ ] = data
125
+ . filter (
126
+ ( item ) =>
127
+ item . Type === "10" && item . Name . startsWith ( folder . slice ( 1 ) ) && item . Name . length >= folder . length
128
+ )
129
+ . map ( ( item ) => {
130
+ const name = item . Name . split ( "/" ) [ piece - 1 ] ;
131
+ parent . entries . set ( name , new Directory ( name , folder + name ) ) ;
132
+ return [ name , vscode . FileType . Directory ] ;
133
+ } ) ;
134
+ return results . concat ( cspSubdirs ) ;
119
135
} ) ;
120
- return results;
121
- */
122
- } ) ;
136
+ } else if ( rootWebAppExists ) {
137
+ // Expanding the root of a CSP-type workspace folder, and earlier we found a '/' root-level webapp
138
+ // so we now enumerate its files.
139
+ return api
140
+ . actionQuery ( sql , [ "/*" , dir , orderBy , "0" , "0" , notStudio , "0" ] )
141
+ . then ( ( data ) => data . result . content || [ ] )
142
+ . then ( ( data ) => {
143
+ const rootAppFiles : [ string , vscode . FileType ] [ ] = data
144
+ . filter ( ( item ) => item . Type === "5" )
145
+ . map ( ( item ) => {
146
+ return [ item . Name , vscode . FileType . File ] ;
147
+ } ) ;
148
+ return results . concat ( rootAppFiles ) ;
149
+ } ) ;
150
+ } else {
151
+ // Nothing else to add.
152
+ return results ;
153
+ }
123
154
} )
124
155
. catch ( ( error ) => {
125
156
error && console . error ( error ) ;
@@ -273,14 +304,18 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
273
304
private async _lookup ( uri : vscode . Uri ) : Promise < Entry > {
274
305
const parts = uri . path . split ( "/" ) ;
275
306
let entry : Entry = this . root ;
276
- for ( const part of parts ) {
307
+ //for (const part of parts) {
308
+ for ( let i = 0 ; i < parts . length ; i ++ ) {
309
+ const part = parts [ i ] ;
277
310
if ( ! part ) {
278
311
continue ;
279
312
}
280
313
let child : Entry | undefined ;
281
314
if ( entry instanceof Directory ) {
282
315
child = entry . entries . get ( part ) ;
283
- if ( ! part . includes ( "." ) ) {
316
+ // If the last element of path is dotted and is one we haven't already cached as a directory
317
+ // then it is assumed to be a file.
318
+ if ( ! part . includes ( "." ) || i + 1 < parts . length ) {
284
319
const fullName = entry . name === "" ? part : entry . fullName + "/" + part ;
285
320
child = new Directory ( part , fullName ) ;
286
321
entry . entries . set ( part , child ) ;
0 commit comments