@@ -80,46 +80,77 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
8080 . actionQuery ( sql , [ spec , dir , orderBy , system , flat , notStudio , generated ] )
8181 . then ( ( data ) => data . result . content || [ ] )
8282 . 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 ) {
95101 return results ;
96102 }
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 ) ;
119135 } ) ;
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+ }
123154 } )
124155 . catch ( ( error ) => {
125156 error && console . error ( error ) ;
@@ -273,14 +304,18 @@ export class FileSystemProvider implements vscode.FileSystemProvider {
273304 private async _lookup ( uri : vscode . Uri ) : Promise < Entry > {
274305 const parts = uri . path . split ( "/" ) ;
275306 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 ] ;
277310 if ( ! part ) {
278311 continue ;
279312 }
280313 let child : Entry | undefined ;
281314 if ( entry instanceof Directory ) {
282315 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 ) {
284319 const fullName = entry . name === "" ? part : entry . fullName + "/" + part ;
285320 child = new Directory ( part , fullName ) ;
286321 entry . entries . set ( part , child ) ;
0 commit comments