chore: release v2.4
- Add theme system (Dark/Light palettes, ModernTheme, ThemeManager) - Add InputDialog, Spinner common view - Add DuplicatesCsvExportService - Refresh views, dialogs, and view models across tabs - Update localization strings (en/fr) - Tweak services (transfer, permissions, search, user access, ownership elevation, bulk operations) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -5,4 +5,5 @@ public class AppSettings
|
||||
public string DataFolder { get; set; } = string.Empty;
|
||||
public string Lang { get; set; } = "en";
|
||||
public bool AutoTakeOwnership { get; set; } = false;
|
||||
public string Theme { get; set; } = "System"; // System | Light | Dark
|
||||
}
|
||||
|
||||
@@ -10,4 +10,8 @@ public class DuplicateItem
|
||||
public DateTime? Modified { get; set; }
|
||||
public int? FolderCount { get; set; }
|
||||
public int? FileCount { get; set; }
|
||||
/// <summary>URL of the site the item was collected from.</summary>
|
||||
public string SiteUrl { get; set; } = string.Empty;
|
||||
/// <summary>Friendly site title; falls back to a derived label when unknown.</summary>
|
||||
public string SiteTitle { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace SharepointToolbox.Core.Models;
|
||||
|
||||
public record OperationProgress(int Current, int Total, string Message)
|
||||
public record OperationProgress(int Current, int Total, string Message, bool IsIndeterminate = false)
|
||||
{
|
||||
public static OperationProgress Indeterminate(string message) =>
|
||||
new(0, 0, message);
|
||||
new(0, 0, message, IsIndeterminate: true);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,42 @@
|
||||
namespace SharepointToolbox.Core.Models;
|
||||
|
||||
public record SiteInfo(string Url, string Title);
|
||||
public record SiteInfo(string Url, string Title)
|
||||
{
|
||||
public long StorageUsedMb { get; init; }
|
||||
public long StorageQuotaMb { get; init; }
|
||||
public string Template { get; init; } = string.Empty;
|
||||
|
||||
public SiteKind Kind => SiteKindHelper.FromTemplate(Template);
|
||||
}
|
||||
|
||||
public enum SiteKind
|
||||
{
|
||||
Unknown,
|
||||
TeamSite,
|
||||
CommunicationSite,
|
||||
Classic
|
||||
}
|
||||
|
||||
public static class SiteKindHelper
|
||||
{
|
||||
public static SiteKind FromTemplate(string template)
|
||||
{
|
||||
if (string.IsNullOrEmpty(template)) return SiteKind.Unknown;
|
||||
if (template.StartsWith("GROUP#", StringComparison.OrdinalIgnoreCase)) return SiteKind.TeamSite;
|
||||
if (template.StartsWith("SITEPAGEPUBLISHING#", StringComparison.OrdinalIgnoreCase)) return SiteKind.CommunicationSite;
|
||||
if (template.StartsWith("STS#", StringComparison.OrdinalIgnoreCase)) return SiteKind.Classic;
|
||||
return SiteKind.Unknown;
|
||||
}
|
||||
|
||||
public static string DisplayName(SiteKind kind)
|
||||
{
|
||||
var key = kind switch
|
||||
{
|
||||
SiteKind.TeamSite => "sitepicker.kind.teamsite",
|
||||
SiteKind.CommunicationSite => "sitepicker.kind.communication",
|
||||
SiteKind.Classic => "sitepicker.kind.classic",
|
||||
_ => "sitepicker.kind.other"
|
||||
};
|
||||
return Localization.TranslationSource.Instance[key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,4 +10,24 @@ public class TransferJob
|
||||
public string DestinationFolderPath { get; set; } = string.Empty;
|
||||
public TransferMode Mode { get; set; } = TransferMode.Copy;
|
||||
public ConflictPolicy ConflictPolicy { get; set; } = ConflictPolicy.Skip;
|
||||
|
||||
/// <summary>
|
||||
/// Optional library-relative file paths. When non-empty, only these files
|
||||
/// are transferred; SourceFolderPath recursive enumeration is skipped.
|
||||
/// </summary>
|
||||
public IReadOnlyList<string> SelectedFilePaths { get; set; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>
|
||||
/// When true, recreate the source folder name under the destination folder
|
||||
/// (dest/srcFolderName/... ). When false, the source folder's contents land
|
||||
/// directly inside the destination folder.
|
||||
/// </summary>
|
||||
public bool IncludeSourceFolder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// When true (default), transfer the files inside the source folder.
|
||||
/// When false, only create the folder structure (useful together with
|
||||
/// <see cref="IncludeSourceFolder"/> to clone an empty scaffold).
|
||||
/// </summary>
|
||||
public bool CopyFolderContents { get; set; } = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user