feat: add missing features
This commit is contained in:
parent
e6eb19aba6
commit
1a48cd1712
@ -205,6 +205,12 @@ namespace Flawless.Client.Remote
|
||||
[Get("/api/repo/{userName}/{repositoryName}/get_users")]
|
||||
Task<RepoUserRoleListingResponse> GetUsers(string userName, string repositoryName, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <returns>OK</returns>
|
||||
/// <exception cref="ApiException">Thrown when the request returns a non-success status code.</exception>
|
||||
[Headers("Accept: text/plain, application/json, text/json")]
|
||||
[Get("/api/repo/{userName}/{repositoryName}/stats")]
|
||||
Task<RepoStatisticResponse> Stats(string userName, string repositoryName, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <returns>A <see cref="Task"/> that completes when the request is finished.</returns>
|
||||
/// <exception cref="ApiException">Thrown when the request returns a non-success status code.</exception>
|
||||
[Headers("Content-Type: application/json")]
|
||||
@ -406,6 +412,30 @@ namespace Flawless.Client.Remote
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.4.0.0 (NJsonSchema v11.3.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
public partial class CommitByDayDetail
|
||||
{
|
||||
|
||||
[JsonPropertyName("day")]
|
||||
public System.DateTimeOffset Day { get; set; }
|
||||
|
||||
[JsonPropertyName("count")]
|
||||
public int Count { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.4.0.0 (NJsonSchema v11.3.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
public partial class CommitByPersonDetail
|
||||
{
|
||||
|
||||
[JsonPropertyName("username")]
|
||||
public string Username { get; set; }
|
||||
|
||||
[JsonPropertyName("count")]
|
||||
public int Count { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.4.0.0 (NJsonSchema v11.3.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
public partial class CommitManifest
|
||||
{
|
||||
@ -451,6 +481,18 @@ namespace Flawless.Client.Remote
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.4.0.0 (NJsonSchema v11.3.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
public partial class DepotDetail
|
||||
{
|
||||
|
||||
[JsonPropertyName("depotName")]
|
||||
public string DepotName { get; set; }
|
||||
|
||||
[JsonPropertyName("depotSize")]
|
||||
public long DepotSize { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.4.0.0 (NJsonSchema v11.3.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
public partial class DepotLabel
|
||||
{
|
||||
@ -644,6 +686,21 @@ namespace Flawless.Client.Remote
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.4.0.0 (NJsonSchema v11.3.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
public partial class RepoStatisticResponse
|
||||
{
|
||||
|
||||
[JsonPropertyName("depots")]
|
||||
public ICollection<DepotDetail> Depots { get; set; }
|
||||
|
||||
[JsonPropertyName("commitByPerson")]
|
||||
public ICollection<CommitByPersonDetail> CommitByPerson { get; set; }
|
||||
|
||||
[JsonPropertyName("commitByDay")]
|
||||
public ICollection<CommitByDayDetail> CommitByDay { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.4.0.0 (NJsonSchema v11.3.2.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
public partial class RepoUserRole
|
||||
{
|
||||
|
||||
@ -1157,7 +1157,6 @@ public class RepositoryService : BaseService<RepositoryService>
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.NotifyError(e);
|
||||
Console.WriteLine(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1182,7 +1181,6 @@ public class RepositoryService : BaseService<RepositoryService>
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.NotifyError(e);
|
||||
Console.WriteLine(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,10 @@ using Flawless.Client.Remote;
|
||||
using Flawless.Client.Service;
|
||||
using Flawless.Client.ViewModels.ModalBox;
|
||||
using Flawless.Client.Views.ModalBox;
|
||||
using LiveChartsCore;
|
||||
using LiveChartsCore.Defaults;
|
||||
using LiveChartsCore.Kernel.Sketches;
|
||||
using LiveChartsCore.SkiaSharpView;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.SourceGenerators;
|
||||
using Ursa.Controls;
|
||||
@ -123,6 +127,13 @@ public class CommitTransitNode
|
||||
|
||||
public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
{
|
||||
public class DepotStatsInfo
|
||||
{
|
||||
public string Id { get; set; }
|
||||
|
||||
public long Size { get; set; }
|
||||
}
|
||||
|
||||
public RepositoryModel Repository { get; }
|
||||
|
||||
public RepositoryLocalDatabaseModel LocalDatabase { get; }
|
||||
@ -133,18 +144,28 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
|
||||
public FlatTreeDataGridSource<CommitTransitNode> Commits { get; }
|
||||
|
||||
public FlatTreeDataGridSource<DepotStatsInfo> Depots { get; }
|
||||
|
||||
public ObservableCollectionExtended<LocalChangesNode> LocalChangeSetRaw { get; } = new();
|
||||
|
||||
public ObservableCollectionExtended<LocalChangesNode> CurrentCommitFileTreeRaw { get; } = new();
|
||||
|
||||
public ObservableCollectionExtended<CommitTransitNode> CommitsRaw { get; } = new();
|
||||
|
||||
public ObservableCollection<DepotStatsInfo> DepotsStats { get; } = new();
|
||||
|
||||
public UserModel User { get; }
|
||||
|
||||
[Reactive] private bool _autoDetectChanges = true;
|
||||
|
||||
[Reactive] private bool _isOwnerRole, _isDeveloperRole, _isReporterRole, _isGuestRole, _showWebHook;
|
||||
|
||||
|
||||
[Reactive] private ISeries[] _byDay = [new ColumnSeries<DateTimePoint>()];
|
||||
|
||||
public ICartesianAxis[] XAxesByDay { get; set; } = [
|
||||
new DateTimeAxis(TimeSpan.FromDays(1), date => date.ToString("MMMM dd"))
|
||||
];
|
||||
|
||||
private string _wsRoot;
|
||||
|
||||
public RepositoryViewModel(RepositoryModel repo, IScreen hostScreen) : base(hostScreen)
|
||||
@ -234,6 +255,20 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
}
|
||||
};
|
||||
|
||||
Depots = new FlatTreeDataGridSource<DepotStatsInfo>(DepotsStats)
|
||||
{
|
||||
Columns =
|
||||
{
|
||||
new TextColumn<DepotStatsInfo, string>(
|
||||
"Id",
|
||||
n => n.Id),
|
||||
|
||||
new TextColumn<DepotStatsInfo, string>(
|
||||
"Size",
|
||||
n => PathUtility.ConvertBytesToBestDisplay(n.Size)),
|
||||
}
|
||||
};
|
||||
|
||||
_ = StartupTasksAsync();
|
||||
}
|
||||
|
||||
@ -242,6 +277,7 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
{
|
||||
await RefreshRepositoryRoleInfoAsyncCommand.Execute();
|
||||
await RefreshRepositoryIssuesAsyncCommand.Execute();
|
||||
await RefreshStatisticDataCommand.Execute();
|
||||
await RefreshWebhooksCommand.Execute();
|
||||
await DetectLocalChangesAsyncCommand.Execute();
|
||||
await RendererFileTreeAsync();
|
||||
@ -745,4 +781,37 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
foreach (var n in LocalChangeSetRaw)
|
||||
n.Included = false;
|
||||
}
|
||||
|
||||
[ReactiveCommand]
|
||||
private async Task RefreshStatisticData()
|
||||
{
|
||||
try
|
||||
{
|
||||
var api = Api.C;
|
||||
if (api.RequireRefreshToken() && !(await api.TryRefreshTokenAsync()))
|
||||
{
|
||||
api.ClearGateway();
|
||||
return;
|
||||
}
|
||||
|
||||
var rsp = await api.Gateway.Stats(Repository.OwnerName, Repository.Name);
|
||||
|
||||
DepotsStats.Clear();
|
||||
foreach (var dp in rsp.Depots)
|
||||
DepotsStats.Add(new DepotStatsInfo{ Id = dp.DepotName, Size = dp.DepotSize});
|
||||
|
||||
ByDay = new[]
|
||||
{
|
||||
new ColumnSeries<DateTimePoint>
|
||||
{
|
||||
Values = rsp.CommitByDay.Select(k => new DateTimePoint(k.Day.LocalDateTime, k.Count)).ToList(),
|
||||
}
|
||||
};
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.NotifyError(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,6 +13,7 @@ using Flawless.Client.Remote;
|
||||
using Flawless.Client.Service;
|
||||
using Flawless.Client.ViewModels.ModalBox;
|
||||
using Flawless.Client.Views.ModalBox;
|
||||
using LiveChartsCore;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.SourceGenerators;
|
||||
using Refit;
|
||||
@ -82,14 +83,6 @@ public partial class SettingViewModel : RoutableViewModelBase
|
||||
{
|
||||
UIHelper.NotifyError(ex);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
UIHelper.NotifyError(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task LoadClientSettingsAsync()
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:u="https://irihi.tech/ursa"
|
||||
xmlns:vm="using:Flawless.Client.ViewModels"
|
||||
xmlns:lvc="using:LiveChartsCore.SkiaSharpView.Avalonia"
|
||||
xmlns:views="clr-namespace:Flawless.Client.Views"
|
||||
x:DataType="vm:RepositoryViewModel"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
@ -95,10 +96,23 @@
|
||||
</u:Form>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem Header="Statics" IsVisible="{Binding IsDeveloperRole}">
|
||||
<StackPanel Width="600" HorizontalAlignment="Stretch">
|
||||
|
||||
</StackPanel>
|
||||
<TabItem Header="Statics" IsVisible="{Binding IsOwnerRole}">
|
||||
<ScrollViewer Width="600" HorizontalAlignment="Stretch">
|
||||
<StackPanel Spacing="16" HorizontalAlignment="Stretch">
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<u:IconButton Content="Refresh" Icon="{StaticResource SemiIconRefresh}"
|
||||
Command="{Binding RefreshWebhooksCommand}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Stretch" Orientation="Vertical">
|
||||
<Label>Every Day Commits</Label>
|
||||
<lvc:CartesianChart Series="{Binding ByDay}" XAxes="{Binding XAxesByDay}"/>
|
||||
</StackPanel>
|
||||
<StackPanel HorizontalAlignment="Stretch" Orientation="Vertical">
|
||||
<Label>Depot Sizes</Label>
|
||||
<TreeDataGrid Source="{Binding Depots}"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</UserControl>
|
||||
|
||||
31
Flawless.Communication/Response/RepoStatisticResponse.cs
Normal file
31
Flawless.Communication/Response/RepoStatisticResponse.cs
Normal file
@ -0,0 +1,31 @@
|
||||
namespace Flawless.Communication.Response;
|
||||
|
||||
public struct RepoStatisticResponse
|
||||
{
|
||||
public struct DepotDetail
|
||||
{
|
||||
public string DepotName { get; set; }
|
||||
|
||||
public long DepotSize { get; set; }
|
||||
}
|
||||
|
||||
public struct CommitByPersonDetail
|
||||
{
|
||||
public string Username { get; set; }
|
||||
|
||||
public int Count { get; set; }
|
||||
}
|
||||
|
||||
public struct CommitByDayDetail
|
||||
{
|
||||
public DateTime Day { get; set; }
|
||||
|
||||
public int Count { get; set; }
|
||||
}
|
||||
|
||||
public DepotDetail[] Depots { get; set; }
|
||||
|
||||
public CommitByPersonDetail[] CommitByPerson { get; set; }
|
||||
|
||||
public CommitByDayDetail[] CommitByDay { get; set; }
|
||||
}
|
||||
@ -174,6 +174,45 @@ public class RepositoryInnieController(
|
||||
|
||||
return rp;
|
||||
}
|
||||
|
||||
[HttpGet("stats")]
|
||||
public async Task<ActionResult<RepoStatisticResponse>> GetStatisticAsync(string userName, string repositoryName)
|
||||
{
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
var grantIssue = await ValidateRepositoryAsync(userName, repositoryName, user, RepositoryRole.Owner);
|
||||
if (grantIssue is not Repository rp) return (ActionResult) grantIssue;
|
||||
|
||||
|
||||
var response = new RepoStatisticResponse();
|
||||
|
||||
// 获取Depot大小统计
|
||||
response.Depots = rp.Depots
|
||||
.Select(d => new RepoStatisticResponse.DepotDetail
|
||||
{
|
||||
DepotName = d.DepotId.ToString(),
|
||||
DepotSize = d.Length
|
||||
}).ToArray();
|
||||
|
||||
// 获取提交者提交数量统计
|
||||
response.CommitByPerson = rp.Commits
|
||||
.GroupBy(c => c.Author.UserName)
|
||||
.Select(g => new RepoStatisticResponse.CommitByPersonDetail
|
||||
{
|
||||
Username = g.Key!,
|
||||
Count = g.Count()
|
||||
}).ToArray();
|
||||
|
||||
// 获取每日提交数量统计
|
||||
response.CommitByDay = rp.Commits
|
||||
.GroupBy(c => c.CommittedOn)
|
||||
.Select(g => new RepoStatisticResponse.CommitByDayDetail
|
||||
{
|
||||
Day = g.Key,
|
||||
Count = g.Count()
|
||||
}).ToArray();
|
||||
|
||||
return Ok(response);
|
||||
}
|
||||
|
||||
[HttpPost("webhooks/create")]
|
||||
public async Task<IActionResult> CreateWebhook(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user