working
This commit is contained in:
@@ -1,14 +1,22 @@
|
|||||||
namespace SharpIDE.Application.Features.SolutionDiscovery;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace SharpIDE.Application.Features.SolutionDiscovery;
|
||||||
|
|
||||||
public class Folder
|
public class Folder
|
||||||
{
|
{
|
||||||
public required string Name { get; set; }
|
public required string Path { get; set; }
|
||||||
public required string FullName { get; set; }
|
public string Name { get; set; } = null!;
|
||||||
public required Folder? ParentFolder { get; set; }
|
public List<Folder> Folders { get; set; } = [];
|
||||||
public required List<MyFile> Files { get; set; } = [];
|
public List<TreeMapFile> 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; }
|
public required string Name { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,35 +44,7 @@ public static class GetNodesInSolution
|
|||||||
var rootDirectoryOfProject = new DirectoryInfo(Path.GetDirectoryName(projectPath)!);
|
var rootDirectoryOfProject = new DirectoryInfo(Path.GetDirectoryName(projectPath)!);
|
||||||
|
|
||||||
var grouped = files.GroupBy(s => s.Directory!.FullName);
|
var grouped = files.GroupBy(s => s.Directory!.FullName);
|
||||||
var folders = grouped.Select(s => new Folder
|
throw new NotImplementedException();
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace SharpIDE.Application.Features.SolutionDiscovery;
|
||||||
|
|
||||||
|
public static class TreeMapper
|
||||||
|
{
|
||||||
|
public static List<Folder> GetSubFolders(this Folder folder)
|
||||||
|
{
|
||||||
|
var directoryInfo = new DirectoryInfo(folder.Path);
|
||||||
|
|
||||||
|
ConcurrentBag<Folder> subFolders = [];
|
||||||
|
|
||||||
|
var files = GetFiles(directoryInfo);
|
||||||
|
if (files.Count is not 0)
|
||||||
|
{
|
||||||
|
var pseudoFolder = new Folder
|
||||||
|
{
|
||||||
|
Path = folder.Path,
|
||||||
|
Name = "<Files>",
|
||||||
|
IsPseudoFolder = true,
|
||||||
|
Files = files,
|
||||||
|
Depth = folder.Depth + 1
|
||||||
|
};
|
||||||
|
subFolders.Add(pseudoFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<DirectoryInfo> 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<TreeMapFile> GetFiles(DirectoryInfo directoryInfo)
|
||||||
|
{
|
||||||
|
List<FileInfo> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
80
src/SharpIDE.Photino/Components/SolutionExplorer.razor
Normal file
80
src/SharpIDE.Photino/Components/SolutionExplorer.razor
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
@using Microsoft.Build.Construction
|
||||||
|
@using SharpIDE.Application.Features.SolutionDiscovery
|
||||||
|
|
||||||
|
@if (_solutionFile is null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
<MudTreeView T="ProjectInSolution" Dense="true">
|
||||||
|
@foreach(var project in _rootNodes)
|
||||||
|
{
|
||||||
|
@GetProjectFragment(project)
|
||||||
|
}
|
||||||
|
</MudTreeView>
|
||||||
|
|
||||||
|
|
||||||
|
@code {
|
||||||
|
|
||||||
|
private SolutionFile _solutionFile = null!;
|
||||||
|
private List<ProjectInSolution> _rootNodes = [];
|
||||||
|
private Dictionary<string, Folder> _folders = new();
|
||||||
|
|
||||||
|
private RenderFragment GetProjectFragment(ProjectInSolution project) =>
|
||||||
|
@<text>
|
||||||
|
<MudTreeViewItem Value="project" Text="@project.ProjectName">
|
||||||
|
@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)
|
||||||
|
}
|
||||||
|
</MudTreeViewItem>
|
||||||
|
</text>;
|
||||||
|
|
||||||
|
private RenderFragment GetFolderFragment(Folder folder) =>
|
||||||
|
@<text>
|
||||||
|
@foreach (var subFolder in folder.Folders)
|
||||||
|
{
|
||||||
|
<MudTreeViewItem @bind-Expanded="subFolder.Expanded" T="ProjectInSolution" Text="@subFolder.Name">
|
||||||
|
@if (subFolder.Expanded)
|
||||||
|
{
|
||||||
|
@GetFolderFragment(subFolder)
|
||||||
|
}
|
||||||
|
</MudTreeViewItem>
|
||||||
|
}
|
||||||
|
@foreach (var file in folder.Files)
|
||||||
|
{
|
||||||
|
<MudTreeViewItem T="ProjectInSolution" Text="@file.Name" />
|
||||||
|
}
|
||||||
|
</text>;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -9,13 +9,9 @@
|
|||||||
<MudAppBar Dense="true">
|
<MudAppBar Dense="true">
|
||||||
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
|
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@((e) => DrawerToggle())" />
|
||||||
</MudAppBar>
|
</MudAppBar>
|
||||||
<MudDrawer @bind-Open="@_drawerOpen">
|
<MudDrawer @bind-Open="@_drawerOpen" ClipMode="DrawerClipMode.Always">
|
||||||
<MudDrawerHeader>
|
<SolutionExplorer />
|
||||||
<MudStack Row="false" Justify="Justify.Center">
|
@* <NavMenu/> *@
|
||||||
<MudText Typo="Typo.h5">SharpIDE.Photino</MudText>
|
|
||||||
</MudStack>
|
|
||||||
</MudDrawerHeader>
|
|
||||||
<NavMenu/>
|
|
||||||
</MudDrawer>
|
</MudDrawer>
|
||||||
<MudMainContent>
|
<MudMainContent>
|
||||||
<MudContainer Class="px-8 py-6">
|
<MudContainer Class="px-8 py-6">
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<MudNavMenu>
|
<MudNavMenu>
|
||||||
<MudNavLink Href="/" Icon="@Icons.Material.Filled.Home" Match="NavLinkMatch.All">Home</MudNavLink>
|
<MudNavLink Href="/" Icon="@Icons.Material.Filled.Home" Match="NavLinkMatch.All">Solution Explorer</MudNavLink>
|
||||||
</MudNavMenu>
|
</MudNavMenu>
|
||||||
|
|||||||
@@ -1,71 +1,8 @@
|
|||||||
@page "/"
|
@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
|
|
||||||
|
|
||||||
<MudText>Welcome to a new Photino Blazor app!</MudText>
|
<MudText>Welcome to a new Photino Blazor app!</MudText>
|
||||||
|
|
||||||
@if (_solutionFile is null)
|
@code
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
<MudTreeView T="ProjectInSolution" Dense="true">
|
|
||||||
@foreach(var project in _rootNodes)
|
|
||||||
{
|
|
||||||
@GetProjectFragment(project)
|
|
||||||
}
|
|
||||||
</MudTreeView>
|
|
||||||
|
|
||||||
|
|
||||||
@code {
|
|
||||||
|
|
||||||
private SolutionFile _solutionFile = null!;
|
|
||||||
private List<ProjectInSolution> _rootNodes = [];
|
|
||||||
private Dictionary<string, List<Folder>> _folders = new();
|
|
||||||
|
|
||||||
private RenderFragment GetProjectFragment(ProjectInSolution project) =>
|
|
||||||
@<text>
|
|
||||||
<MudTreeViewItem Value="project" Text="@project.ProjectName">
|
|
||||||
@foreach(var child in _solutionFile.ProjectsByGuid.Values.Where(s => s.ParentProjectGuid == project.ProjectGuid).OrderBy(s => s.ProjectName))
|
|
||||||
{
|
|
||||||
@GetProjectFragment(child)
|
|
||||||
}
|
|
||||||
@GetFolderFragment(_folders.GetValueOrDefault(project.ProjectGuid, []))
|
|
||||||
</MudTreeViewItem>
|
|
||||||
</text>;
|
|
||||||
|
|
||||||
private RenderFragment GetFolderFragment(List<Folder> folders) =>
|
|
||||||
@<text>
|
|
||||||
@foreach (var folder in folders.Where(s => s.ParentFolder is null))
|
|
||||||
{
|
|
||||||
<MudTreeViewItem T="ProjectInSolution" Text="@folder.Name">
|
|
||||||
@GetFolderFragment(folders.Where(s => s.ParentFolder == folder).ToList())
|
|
||||||
@foreach(var file in folder.Files)
|
|
||||||
{
|
|
||||||
<MudTreeViewItem T="ProjectInSolution" Text="@file.Name" />
|
|
||||||
}
|
|
||||||
</MudTreeViewItem>
|
|
||||||
}
|
|
||||||
</text>;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components" Version="9.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Components" Version="9.0.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView" Version="9.0.0" />
|
<PackageReference Include="Microsoft.AspNetCore.Components.WebView" Version="9.0.0" />
|
||||||
<PackageReference Include="MudBlazor" Version="8.0.0-preview.5" />
|
<PackageReference Include="MudBlazor" Version="8.0.0-rc.2" />
|
||||||
<PackageReference Include="Photino.Blazor" Version="3.2.0" />
|
<PackageReference Include="Photino.Blazor" Version="3.2.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -9,3 +9,4 @@
|
|||||||
@using Microsoft.Extensions.Logging
|
@using Microsoft.Extensions.Logging
|
||||||
@using MudBlazor
|
@using MudBlazor
|
||||||
@using SharpIDE.Photino.Layout
|
@using SharpIDE.Photino.Layout
|
||||||
|
@using SharpIDE.Photino.Components
|
||||||
|
|||||||
Reference in New Issue
Block a user