The FileManager TreeView does not expand automatically in some scenarios, which can cause the TreeView and ListView UI to be inconsistent:
Here is a test page and steps to reproduce.
<p>/folder-16/folder-17</p>
<TelerikTextBox @bind-Value="@DirectoryPath" Width="max-content" OnChange="@(() => FileManagerRef!.Rebind())" />
<TelerikFileManager @ref="@FileManagerRef"
Data="@FileManagerData"
@bind-Path="@DirectoryPath"
View="@FileManagerViewType.ListView"
EnableLoaderContainer="false"
OnDownload="@OnDownloadHandler"
NameField="@(nameof(FlatFileEntry.Name))"
SizeField="@(nameof(FlatFileEntry.Size))"
PathField="@(nameof(FlatFileEntry.Path))"
ExtensionField="@(nameof(FlatFileEntry.Extension))"
IsDirectoryField="@(nameof(FlatFileEntry.IsDirectory))"
HasDirectoriesField="@(nameof(FlatFileEntry.HasDirectories))"
IdField="@(nameof(FlatFileEntry.Id))"
ParentIdField="@(nameof(FlatFileEntry.ParentId))"
DateCreatedField="@(nameof(FlatFileEntry.DateCreated))"
DateCreatedUtcField="@(nameof(FlatFileEntry.DateCreatedUtc))"
DateModifiedField="@(nameof(FlatFileEntry.DateModified))"
DateModifiedUtcField="@(nameof(FlatFileEntry.DateModifiedUtc))"
Class="my-filemanager">
</TelerikFileManager>
@code {
private TelerikFileManager<FlatFileEntry>? FileManagerRef { get; set; }
private List<FlatFileEntry>? FileManagerData { get; set; }
public string? DirectoryPath { get; set; } = string.Empty;
private readonly string RootPath = string.Empty;
public async Task<bool> OnDownloadHandler(FileManagerDownloadEventArgs args)
{
await Task.Delay(1);
return true;
}
private int FolderLevelCount { get; set; } = 5;
private int FilesInFolderCount { get; set; } = 5;
private int FoldersInFolderCount { get; set; } = 2;
private int FolderNameCounter { get; set; }
private readonly List<string> FileExtensions = new() {
".txt", ".pdf", ".docx", ".xlsx", ".png", ".jpg", ".gif", ".zip", ".css", ".html", ".mp3", ".mpg"
};
protected override async Task OnInitializedAsync()
{
await Task.CompletedTask;
DirectoryPath = RootPath;
FileManagerData = LoadFlatDataAsync();
await base.OnInitializedAsync();
}
private List<FlatFileEntry> LoadFlatDataAsync()
{
List<FlatFileEntry> data = new List<FlatFileEntry>();
string rootDataPath = string.IsNullOrEmpty(RootPath) ? "/" : RootPath;
PopulateChildren(data, null, rootDataPath, 1);
return data;
}
private void PopulateChildren(List<FlatFileEntry> data, string? parentId, string parentPath, int level)
{
var rnd = Random.Shared;
for (int i = 1; i <= FilesInFolderCount; i++)
{
string itemId = Guid.NewGuid().ToString();
string itemExtension = FileExtensions[rnd.Next(0, FileExtensions.Count)];
string itemName = $"{itemExtension.Substring(1)}-file-{(FolderNameCounter != default ? string.Concat(FolderNameCounter, "-") : string.Empty)}{i}";
string itemPath = Path.Combine(parentPath, string.Concat(itemName, itemExtension));
data.Add(new FlatFileEntry()
{
Id = itemId,
ParentId = parentId,
Name = itemName,
IsDirectory = false,
HasDirectories = false,
DateCreated = DateTime.Now,
DateCreatedUtc = DateTime.Now.ToUniversalTime(),
DateModified = DateTime.Now,
DateModifiedUtc = DateTime.Now.ToUniversalTime(),
Path = itemPath,
Extension = itemExtension,
Size = rnd.Next(1_000, 3_000_000)
});
}
if (level < FolderLevelCount)
{
for (int i = 1; i <= FoldersInFolderCount; i++)
{
var itemId = Guid.NewGuid().ToString();
var itemName = $"folder-{++FolderNameCounter}";
var itemPath = Path.Combine(parentPath, itemName);
data.Add(new FlatFileEntry()
{
Id = itemId,
ParentId = parentId,
Name = itemName,
IsDirectory = true,
HasDirectories = level < FolderLevelCount - 1,
DateCreated = DateTime.Now,
DateCreatedUtc = DateTime.Now.ToUniversalTime(),
DateModified = DateTime.Now,
DateModifiedUtc = DateTime.Now.ToUniversalTime(),
Path = itemPath,
Size = rnd.Next(100_000, 10_000_000)
});
PopulateChildren(data, itemId, itemPath, level + 1);
}
}
}
public class FlatFileEntry : FileEntry
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public string ParentId { get; set; }
}
public class FileEntry
{
public string Name { get; set; }
public long Size { get; set; }
public string Path { get; set; }
public string Extension { get; set; }
public bool IsDirectory { get; set; }
public bool HasDirectories { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateCreatedUtc { get; set; }
public DateTime DateModified { get; set; }
public DateTime DateModifiedUtc { get; set; }
}
}
I want to use the built-in FileManagerToolBarSortTool but I want to remove the "Date Modified" option from the "Sort BY" menu.
===
ADMIN EDIT
===
For the time being, a possible option is to create a custom tool for sorting. You can use the SplitButton component to simulate the built-in UI. Upon selecting option from the dropdown, you may sort your data collection based on the selected custom sort option. Call the Rebind method to refresh the data after updating it.
Currently, only the "Download" option has an icon and this is not consistent:
Greetings.
I was using the FileManager recently and wanted to make sure the user could only select a single file. I was expecting a parameter to configure that but I didn't find any. I was able to bypass the issue by acting on the value reported by the component but I found it a bit inconvenient.
I think it might be interesting if we could:
What do you think?
Would like to be able to change / recall State of expanded / collapsed items in FileManager, similar to how we can with the Grid component using Groups.
We would also like the ability to set the Splitter collapsed on initial load to hide the tree.
On refreshing data from the database, the entire File Manager reverts to all items collapsed, which will be annoying for end users.
State management could also deal with the default view (Details vs Icons) as requested elsewhere for this component.
For true load on demand, the OnRead event should be triggered for:
Possible to add in the FileManager preview pane, a preview of the actual file, if the file type is simple; i.e. image or video (or pdf); or provide functionality to add preview.
Cheers
Phil