diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/Folder.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/Folder.cs index 295c6b2..1fcf04f 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/Folder.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/Folder.cs @@ -1,14 +1,22 @@ -namespace SharpIDE.Application.Features.SolutionDiscovery; +using System.Text.Json.Serialization; + +namespace SharpIDE.Application.Features.SolutionDiscovery; public class Folder { - public required string Name { get; set; } - public required string FullName { get; set; } - public required Folder? ParentFolder { get; set; } - public required List Files { get; set; } = []; + public required string Path { get; set; } + public string Name { get; set; } = null!; + public List Folders { get; set; } = []; + public List Files { get; set; } = []; + public bool IsPseudoFolder { get; set; } + public int Depth { get; set; } + + [JsonIgnore] + public bool Expanded { get; set; } } -public class MyFile +public class TreeMapFile { + public required string Path { get; set; } public required string Name { get; set; } } diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/GetNodesInSolution.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/GetNodesInSolution.cs index 638dbf5..de63e58 100644 --- a/src/SharpIDE.Application/Features/SolutionDiscovery/GetNodesInSolution.cs +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/GetNodesInSolution.cs @@ -44,35 +44,7 @@ public static class GetNodesInSolution var rootDirectoryOfProject = new DirectoryInfo(Path.GetDirectoryName(projectPath)!); var grouped = files.GroupBy(s => s.Directory!.FullName); - var folders = grouped.Select(s => new Folder - { - Name = Path.GetFileName(s.Key), - FullName = s.Key, - ParentFolder = null, - Files = s.Select(f => new MyFile - { - Name = f.Name - }).ToList() - }).ToList(); - - foreach (var folder in folders) - { - var directoryInfo = new DirectoryInfo(folder.FullName); - if (directoryInfo.FullName == rootDirectoryOfProject.FullName) continue; - - var parent = directoryInfo.Parent; - try - { - var parentFolder = folders.SingleOrDefault(f => f.FullName == parent!.FullName); - folder.ParentFolder = parentFolder; - } - catch (Exception e) - { - Console.WriteLine(e); - } - } - - return folders; + throw new NotImplementedException(); } } diff --git a/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapper.cs b/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapper.cs new file mode 100644 index 0000000..0429f8f --- /dev/null +++ b/src/SharpIDE.Application/Features/SolutionDiscovery/TreeMapper.cs @@ -0,0 +1,69 @@ +using System.Collections.Concurrent; + +namespace SharpIDE.Application.Features.SolutionDiscovery; + +public static class TreeMapper +{ + public static List GetSubFolders(this Folder folder) + { + var directoryInfo = new DirectoryInfo(folder.Path); + + ConcurrentBag subFolders = []; + + var files = GetFiles(directoryInfo); + if (files.Count is not 0) + { + var pseudoFolder = new Folder + { + Path = folder.Path, + Name = "", + IsPseudoFolder = true, + Files = files, + Depth = folder.Depth + 1 + }; + subFolders.Add(pseudoFolder); + } + + List subFolderInfos; + try + { + subFolderInfos = directoryInfo.EnumerateDirectories("*", new EnumerationOptions { IgnoreInaccessible = false, AttributesToSkip = FileAttributes.ReparsePoint}).ToList(); + } + catch (UnauthorizedAccessException) + { + return subFolders.ToList(); + } + Parallel.ForEach(subFolderInfos, subFolderInfo => + { + var subFolder = new Folder + { + Path = subFolderInfo.FullName, + Name = subFolderInfo.Name, + Depth = folder.Depth + 1 + }; + subFolder.Folders = subFolder.GetSubFolders(); + subFolders.Add(subFolder); + }); + return subFolders.ToList(); + } + + public static List GetFiles(DirectoryInfo directoryInfo) + { + List fileInfos; + try + { + fileInfos = directoryInfo.EnumerateFiles().ToList(); + } + catch (UnauthorizedAccessException) + { + return []; + } + + var files = fileInfos.Select(s => new TreeMapFile + { + Path = s.FullName, + Name = s.Name + }).ToList(); + return files; + } +} diff --git a/src/SharpIDE.Photino/Components/SolutionExplorer.razor b/src/SharpIDE.Photino/Components/SolutionExplorer.razor new file mode 100644 index 0000000..5a9d736 --- /dev/null +++ b/src/SharpIDE.Photino/Components/SolutionExplorer.razor @@ -0,0 +1,80 @@ +@using Microsoft.Build.Construction +@using SharpIDE.Application.Features.SolutionDiscovery + +@if (_solutionFile is null) +{ + return; +} + + + @foreach(var project in _rootNodes) + { + @GetProjectFragment(project) + } + + + +@code { + + private SolutionFile _solutionFile = null!; + private List _rootNodes = []; + private Dictionary _folders = new(); + + private RenderFragment GetProjectFragment(ProjectInSolution project) => + @ + + @foreach(var child in _solutionFile.ProjectsByGuid.Values.Where(s => s.ParentProjectGuid == project.ProjectGuid).OrderBy(s => s.ProjectName)) + { + @GetProjectFragment(child) + } + @if (_folders.GetValueOrDefault(project.ProjectGuid, null) is {} value) + { + @GetFolderFragment(value) + } + + ; + + private RenderFragment GetFolderFragment(Folder folder) => + @ + @foreach (var subFolder in folder.Folders) + { + + @if (subFolder.Expanded) + { + @GetFolderFragment(subFolder) + } + + } + @foreach (var file in folder.Files) + { + + } + ; + + protected override async Task OnInitializedAsync() + { + var solutionFile = GetNodesInSolution.ParseSolutionFileFromPath("D:/matth/Documents/Git/amazon/ClientPortal.sln"); + ArgumentNullException.ThrowIfNull(solutionFile); + _solutionFile = solutionFile; + var rootNodes = solutionFile.ProjectsByGuid.Values.Where(p => p.ParentProjectGuid == null).OrderBy(s => s.ProjectName).ToList(); + _rootNodes = rootNodes; + + var folders2 = _solutionFile.ProjectsByGuid.Values + .Where(s => s.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) + //.Take(2) + .Select(s => + { + var rootFolder = new Folder + { + Name = Path.GetFileNameWithoutExtension(s.AbsolutePath), + Path = Path.GetDirectoryName(s.AbsolutePath)!, + IsPseudoFolder = false + }; + rootFolder.Folders = rootFolder.GetSubFolders(); + return (s, rootFolder); + }) + .ToDictionary(s => s.s.ProjectGuid, s => s.Item2); + _folders = folders2; + } + +} diff --git a/src/SharpIDE.Photino/Layout/MainLayout.razor b/src/SharpIDE.Photino/Layout/MainLayout.razor index b66e5b4..2a46481 100644 --- a/src/SharpIDE.Photino/Layout/MainLayout.razor +++ b/src/SharpIDE.Photino/Layout/MainLayout.razor @@ -9,13 +9,9 @@ - - - - SharpIDE.Photino - - - + + + @* *@ diff --git a/src/SharpIDE.Photino/Layout/NavMenu.razor b/src/SharpIDE.Photino/Layout/NavMenu.razor index 8b2eaf4..e1d7420 100644 --- a/src/SharpIDE.Photino/Layout/NavMenu.razor +++ b/src/SharpIDE.Photino/Layout/NavMenu.razor @@ -1,3 +1,3 @@  - Home + Solution Explorer diff --git a/src/SharpIDE.Photino/Pages/Home.razor b/src/SharpIDE.Photino/Pages/Home.razor index 1326910..857348a 100644 --- a/src/SharpIDE.Photino/Pages/Home.razor +++ b/src/SharpIDE.Photino/Pages/Home.razor @@ -1,71 +1,8 @@ @page "/" -@using Microsoft.Build.Construction -@using Microsoft.Build.Evaluation -@using Microsoft.Build.Execution -@using Microsoft.Build.Globbing -@using Microsoft.Build.Globbing.Extensions -@using SharpIDE.Application.Features.SolutionDiscovery Welcome to a new Photino Blazor app! -@if (_solutionFile is null) +@code { - return; -} - - - @foreach(var project in _rootNodes) - { - @GetProjectFragment(project) - } - - - -@code { - - private SolutionFile _solutionFile = null!; - private List _rootNodes = []; - private Dictionary> _folders = new(); - - private RenderFragment GetProjectFragment(ProjectInSolution project) => - @ - - @foreach(var child in _solutionFile.ProjectsByGuid.Values.Where(s => s.ParentProjectGuid == project.ProjectGuid).OrderBy(s => s.ProjectName)) - { - @GetProjectFragment(child) - } - @GetFolderFragment(_folders.GetValueOrDefault(project.ProjectGuid, [])) - - ; - - private RenderFragment GetFolderFragment(List folders) => - @ - @foreach (var folder in folders.Where(s => s.ParentFolder is null)) - { - - @GetFolderFragment(folders.Where(s => s.ParentFolder == folder).ToList()) - @foreach(var file in folder.Files) - { - - } - - } - ; - - protected override async Task OnInitializedAsync() - { - var solutionFile = GetNodesInSolution.ParseSolutionFileFromPath("D:/matth/Documents/Git/amazon/ClientPortal.sln"); - ArgumentNullException.ThrowIfNull(solutionFile); - _solutionFile = solutionFile; - var rootNodes = solutionFile.ProjectsByGuid.Values.Where(p => p.ParentProjectGuid == null).OrderBy(s => s.ProjectName).ToList(); - _rootNodes = rootNodes; - - var folders2 = _solutionFile.ProjectsByGuid.Values - .Where(s => s.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat) - .Take(2) - .Select(s => (s, GetNodesInSolution.GetFoldersInProject(s.AbsolutePath))) - .ToDictionary(s => s.s.ProjectGuid, s => s.Item2); - _folders = folders2; - } } diff --git a/src/SharpIDE.Photino/SharpIDE.Photino.csproj b/src/SharpIDE.Photino/SharpIDE.Photino.csproj index 88e8098..7f3a4df 100644 --- a/src/SharpIDE.Photino/SharpIDE.Photino.csproj +++ b/src/SharpIDE.Photino/SharpIDE.Photino.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/SharpIDE.Photino/_Imports.razor b/src/SharpIDE.Photino/_Imports.razor index ed016c9..df8c6af 100644 --- a/src/SharpIDE.Photino/_Imports.razor +++ b/src/SharpIDE.Photino/_Imports.razor @@ -9,3 +9,4 @@ @using Microsoft.Extensions.Logging @using MudBlazor @using SharpIDE.Photino.Layout +@using SharpIDE.Photino.Components