Compare commits
3 Commits
53e99bd291
...
b14dcd9d21
| Author | SHA1 | Date | |
|---|---|---|---|
| b14dcd9d21 | |||
| a29948587c | |||
| 2929fb5b31 |
@ -19,6 +19,7 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEventId_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fd0319a0b2a6743ffb27031fdd18a267a1f000_003F72_003Fcd473540_003FEventId_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AEventPipeEventProvider_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F84661d4944484e5e93fdc174ab4e7d09d19e00_003F46_003F893b69bd_003FEventPipeEventProvider_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFileInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F4c8540adf3cd4f6ab5d99f290234ba1ad19c00_003Ffe_003F5a5023e2_003FFileInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFlawless_002EClient_002EViewModels_002ESettingViewModel_002EReactiveCommands_002Eg_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002E_002E_003Ftmp_003FJetBrainsPerUserTemp_002D1000_002D1_003FSourceGeneratedDocuments_003F290B001EA0034408A45A9794_003FReactiveUI_002ESourceGenerators_003FReactiveUI_002ESourceGenerators_002EReactiveCommandGenerator_003FFlawless_002EClient_002EViewModels_002ESettingViewModel_002EReactiveCommands_002Eg_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIdentityDbContext_00601_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003FAppData_003FRoaming_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3eeae7a548684642a53a9ceddc825b7a1a930_003Fcf_003F6a374370_003FIdentityDbContext_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIdentityDbContext_00603_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3eeae7a548684642a53a9ceddc825b7a1a930_003F67_003Ff95019b3_003FIdentityDbContext_00603_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIdentityDbContext_00608_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2025_002E1_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F3eeae7a548684642a53a9ceddc825b7a1a930_003Fc6_003Fcbfda1f6_003FIdentityDbContext_00608_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
<PackageReference Include="Irihi.Ursa" Version="1.10.0" />
|
||||
<PackageReference Include="Irihi.Ursa.ReactiveUIExtension" Version="1.0.1" />
|
||||
<PackageReference Include="Irihi.Ursa.Themes.Semi" Version="1.10.0" />
|
||||
<PackageReference Include="LiveChartsCore.SkiaSharpView.Avalonia" Version="2.0.0-rc5.4" />
|
||||
<PackageReference Include="Markdown.Avalonia" Version="11.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.3" />
|
||||
|
||||
@ -31,10 +31,7 @@ public partial class RepositoryModel : ReactiveModel
|
||||
|
||||
public ObservableCollection<Commit> Commits { get; } = new();
|
||||
|
||||
// todo cache depots?
|
||||
public ObservableCollection<Depot> Depots { get; } = new();
|
||||
|
||||
public ObservableCollection<Lock> Locks { get; } = new();
|
||||
public ObservableCollection<Webhook> Webhooks { get; } = new();
|
||||
|
||||
public ObservableCollection<Issue> Issues { get; } = new();
|
||||
|
||||
@ -45,7 +42,20 @@ public partial class RepositoryModel : ReactiveModel
|
||||
Developer = 2,
|
||||
Owner = 3,
|
||||
}
|
||||
|
||||
|
||||
public partial class Webhook : ReactiveModel
|
||||
{
|
||||
[Reactive] private int _id;
|
||||
|
||||
[Reactive] private string _targetUrl;
|
||||
|
||||
[Reactive] private bool _active;
|
||||
|
||||
[Reactive] private DateTime _createdAt;
|
||||
|
||||
[Reactive] private WebhookEventType _eventType;
|
||||
}
|
||||
|
||||
public partial class Issue : ReactiveModel
|
||||
{
|
||||
[Reactive] private ulong _id;
|
||||
|
||||
@ -202,24 +202,24 @@ namespace Flawless.Client.Remote
|
||||
/// <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")]
|
||||
[Post("/api/repo/{userName}/{repositoryName}/create_webhook")]
|
||||
Task CreateWebhook(string userName, string repositoryName, [Body] WebhookCreateRequest body, CancellationToken cancellationToken = default);
|
||||
[Post("/api/repo/{userName}/{repositoryName}/webhooks/create")]
|
||||
Task Create(string userName, string repositoryName, [Body] WebhookCreateRequest body, 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}")]
|
||||
Task<ICollection<Webhook>> RepoGet(string userName, string repositoryName, CancellationToken cancellationToken = default);
|
||||
[Get("/api/repo/{userName}/{repositoryName}/webhooks")]
|
||||
Task<ICollection<Webhook>> WebhooksGet(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>
|
||||
[Post("/api/repo/{userName}/{repositoryName}/{webhookId}/toggle")]
|
||||
[Post("/api/repo/{userName}/{repositoryName}/webhooks/{webhookId}/toggle")]
|
||||
Task Toggle(string userName, string repositoryName, int webhookId, [Query] bool? activate, 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>
|
||||
[Delete("/api/repo/{userName}/{repositoryName}/{webhookId}")]
|
||||
Task RepoDelete(string userName, string repositoryName, int webhookId, CancellationToken cancellationToken = default);
|
||||
[Delete("/api/repo/{userName}/{repositoryName}/webhooks/{webhookId}")]
|
||||
Task WebhooksDelete(string userName, string repositoryName, int webhookId, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <returns>OK</returns>
|
||||
/// <exception cref="ApiException">Thrown when the request returns a non-success status code.</exception>
|
||||
@ -855,16 +855,16 @@ namespace Flawless.Client.Remote
|
||||
|
||||
[JsonPropertyName("publicEmail")]
|
||||
public bool? PublicEmail { get; set; }
|
||||
|
||||
[JsonPropertyName("isActive")]
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
[JsonPropertyName("isAdmin")]
|
||||
public bool IsAdmin { get; set; }
|
||||
|
||||
[JsonPropertyName("createdAt")]
|
||||
public System.DateTimeOffset? CreatedAt { get; set; }
|
||||
|
||||
[JsonPropertyName("isAdmin")]
|
||||
public bool? IsAdmin { get; set; }
|
||||
|
||||
[JsonPropertyName("isActive")]
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "14.3.0.0 (NJsonSchema v11.2.0.0 (Newtonsoft.Json v13.0.0.0))")]
|
||||
@ -938,11 +938,11 @@ namespace Flawless.Client.Remote
|
||||
public enum WebhookEventType
|
||||
{
|
||||
|
||||
_0 = 0,
|
||||
Push = 0,
|
||||
|
||||
IssueCreated = 1,
|
||||
|
||||
_1 = 1,
|
||||
|
||||
_2 = 2,
|
||||
IssueUpdate = 2
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -572,6 +572,8 @@ public class RepositoryService : BaseService<RepositoryService>
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async ValueTask<bool> UpdateIssueAsync(RepositoryModel repo, ulong issueId, string? title, string? description, IEnumerable<string>? tags)
|
||||
{
|
||||
@ -1382,4 +1384,126 @@ public class RepositoryService : BaseService<RepositoryService>
|
||||
|
||||
return depotFile;
|
||||
}
|
||||
|
||||
public async ValueTask<bool> UpdateWebhooksFromServerAsync(RepositoryModel repo)
|
||||
{
|
||||
var api = Api.C;
|
||||
try
|
||||
{
|
||||
if (api.RequireRefreshToken() && !(await api.TryRefreshTokenAsync()))
|
||||
{
|
||||
api.ClearGateway();
|
||||
return false;
|
||||
}
|
||||
|
||||
var webhooks = await api.Gateway.WebhooksGet(repo.OwnerName, repo.Name);
|
||||
|
||||
var dict = webhooks.ToDictionary(w => w.Id);
|
||||
for (var i = 0; i < repo.Webhooks.Count; i++)
|
||||
{
|
||||
var wh = repo.Webhooks[i];
|
||||
if (!dict.Remove(wh.Id, out var newWh))
|
||||
{
|
||||
repo.Webhooks.RemoveAt(i);
|
||||
i -= 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
wh.TargetUrl = newWh.TargetUrl;
|
||||
wh.Active = newWh.IsActive;
|
||||
wh.EventType = newWh.EventType;
|
||||
}
|
||||
|
||||
foreach (var wh in dict.Values)
|
||||
{
|
||||
repo.Webhooks.Add(new RepositoryModel.Webhook
|
||||
{
|
||||
Id = wh.Id,
|
||||
TargetUrl = wh.TargetUrl,
|
||||
Active = wh.IsActive,
|
||||
CreatedAt = wh.CreatedAt.UtcDateTime,
|
||||
EventType = wh.EventType
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.NotifyError(e);
|
||||
Console.WriteLine(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<bool> AddWebhookAsync(RepositoryModel repo, string targetUrl, string secret, WebhookEventType evt)
|
||||
{
|
||||
var api = Api.C;
|
||||
try
|
||||
{
|
||||
if (api.RequireRefreshToken() && !(await api.TryRefreshTokenAsync()))
|
||||
{
|
||||
api.ClearGateway();
|
||||
return false;
|
||||
}
|
||||
|
||||
await api.Gateway.Create(repo.OwnerName, repo.Name,
|
||||
new WebhookCreateRequest {
|
||||
TargetUrl = targetUrl,
|
||||
Secret = secret,
|
||||
EventType = evt,
|
||||
});
|
||||
|
||||
return await UpdateWebhooksFromServerAsync(repo);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.NotifyError(e);
|
||||
Console.WriteLine(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<bool> DeleteWebhookAsync(RepositoryModel repo, int webhookId)
|
||||
{
|
||||
var api = Api.C;
|
||||
try
|
||||
{
|
||||
if (api.RequireRefreshToken() && !(await api.TryRefreshTokenAsync()))
|
||||
{
|
||||
api.ClearGateway();
|
||||
return false;
|
||||
}
|
||||
|
||||
await api.Gateway.WebhooksDelete(repo.OwnerName, repo.Name, webhookId);
|
||||
return await UpdateWebhooksFromServerAsync(repo);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.NotifyError(e);
|
||||
Console.WriteLine(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<bool> ToggleWebhookAsync(RepositoryModel repo, int webhookId, bool activate)
|
||||
{
|
||||
var api = Api.C;
|
||||
try
|
||||
{
|
||||
if (api.RequireRefreshToken() && !(await api.TryRefreshTokenAsync()))
|
||||
{
|
||||
api.ClearGateway();
|
||||
return false;
|
||||
}
|
||||
|
||||
await api.Gateway.Toggle(repo.OwnerName, repo.Name, webhookId, activate);
|
||||
return await UpdateWebhooksFromServerAsync(repo);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
UIHelper.NotifyError(e);
|
||||
Console.WriteLine(e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,7 +45,7 @@ public partial class UserService : BaseService<UserService>
|
||||
user.CanEdit = info.Authorized;
|
||||
user.PhoneNumber = info.Phone;
|
||||
user.Email = info.Email;
|
||||
user.IsAdmin = info.IsAdmin;
|
||||
user.IsAdmin = info.IsAdmin ?? false;
|
||||
user.IsActive = info.IsActive;
|
||||
user.JoinDate = info.CreatedAt!.Value.LocalDateTime;
|
||||
|
||||
@ -81,7 +81,7 @@ public partial class UserService : BaseService<UserService>
|
||||
user.CanEdit = info.Authorized;
|
||||
user.PhoneNumber = info.Phone;
|
||||
user.Email = info.Email;
|
||||
user.IsAdmin = info.IsAdmin;
|
||||
user.IsAdmin = info.IsAdmin ?? false;
|
||||
user.IsActive = info.IsActive;
|
||||
user.JoinDate = info.CreatedAt!.Value.LocalDateTime;
|
||||
}
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
using Flawless.Client.Remote;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.SourceGenerators;
|
||||
|
||||
namespace Flawless.Client.ViewModels.ModalBox;
|
||||
|
||||
public partial class WebhookEditDialogViewModel : ReactiveObject
|
||||
{
|
||||
[Reactive] private string _url;
|
||||
|
||||
[Reactive] private string _secret;
|
||||
|
||||
[Reactive] private WebhookEventType _eventType;
|
||||
|
||||
}
|
||||
@ -12,13 +12,14 @@ using DynamicData;
|
||||
using DynamicData.Binding;
|
||||
using Flawless.Abstraction;
|
||||
using Flawless.Client.Models;
|
||||
using Flawless.Client.Remote;
|
||||
using Flawless.Client.Service;
|
||||
using Flawless.Client.ViewModels.ModalBox;
|
||||
using Flawless.Client.Views.ModalBox;
|
||||
using Flawless.Core.Modal;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.SourceGenerators;
|
||||
using Ursa.Controls;
|
||||
using WorkspaceFile = Flawless.Core.Modal.WorkspaceFile;
|
||||
|
||||
namespace Flawless.Client.ViewModels;
|
||||
|
||||
@ -138,7 +139,7 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
|
||||
[Reactive] private bool _autoDetectChanges = true;
|
||||
|
||||
[Reactive] private bool _isOwnerRole, _isDeveloperRole, _isReporterRole, _isGuestRole;
|
||||
[Reactive] private bool _isOwnerRole, _isDeveloperRole, _isReporterRole, _isGuestRole, _showWebHook;
|
||||
|
||||
private string _wsRoot;
|
||||
|
||||
@ -238,10 +239,13 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
var path = Path.Combine(_wsRoot, node.FullPath);
|
||||
return (ulong)new FileInfo(path).Length;
|
||||
}
|
||||
|
||||
|
||||
private async Task StartupTasksAsync()
|
||||
{
|
||||
await RefreshRepositoryRoleInfoAsyncCommand.Execute();
|
||||
await RefreshRepositoryIssuesAsyncCommand.Execute();
|
||||
await RefreshWebhooksCommand.Execute();
|
||||
await DetectLocalChangesAsyncCommand.Execute();
|
||||
await RendererFileTreeAsync();
|
||||
SyncCommitsFromRepository();
|
||||
@ -333,6 +337,48 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
if (role >= RepositoryModel.RepositoryRole.Reporter) IsReporterRole = true;
|
||||
if (role >= RepositoryModel.RepositoryRole.Guest) IsGuestRole = true;
|
||||
}
|
||||
|
||||
[ReactiveCommand]
|
||||
private async Task AddWebhookAsync()
|
||||
{
|
||||
if (!IsOwnerRole) return;
|
||||
|
||||
var vm = new WebhookEditDialogViewModel();
|
||||
var result = await OverlayDialog.ShowModal<WebhookEditDialogView, WebhookEditDialogViewModel>(
|
||||
vm, AppDefaultValues.HostId, UIHelper.DefaultOverlayDialogOptionsYesNo());
|
||||
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
using var l = UIHelper.MakeLoading("Create Webhook...");
|
||||
await RepositoryService.C.AddWebhookAsync(Repository, vm.Url, vm.Secret, vm.EventType);
|
||||
}
|
||||
}
|
||||
|
||||
[ReactiveCommand]
|
||||
private async Task DeleteWebhookAsync(Webhook webhook)
|
||||
{
|
||||
if (!IsOwnerRole) return;
|
||||
|
||||
var confirm = await UIHelper.SimpleAskAsync($"Do you sure to delete webhook with url at {webhook.TargetUrl} ?");
|
||||
if (confirm == DialogResult.Yes)
|
||||
{
|
||||
using var l = UIHelper.MakeLoading("Delete webhook...");
|
||||
await RepositoryService.C.DeleteWebhookAsync(Repository, webhook.Id);
|
||||
}
|
||||
}
|
||||
|
||||
[ReactiveCommand]
|
||||
public async Task ToggleWebhookAsync(Webhook webhook)
|
||||
{
|
||||
if (!IsOwnerRole) return;
|
||||
|
||||
using var l = UIHelper.MakeLoading("Update Webhook...");
|
||||
var success = await RepositoryService.C.ToggleWebhookAsync(
|
||||
Repository,
|
||||
webhook.Id,
|
||||
!webhook.IsActive);
|
||||
}
|
||||
|
||||
|
||||
[ReactiveCommand]
|
||||
private async Task RevertFileTreeToSelectedCommitKeepAsync()
|
||||
@ -559,6 +605,15 @@ public partial class RepositoryViewModel : RoutableViewModelBase
|
||||
await RepositoryService.C.CloseRepositoryAsync(Repository);
|
||||
await HostScreen.Router.NavigateBack.Execute();
|
||||
}
|
||||
|
||||
[ReactiveCommand]
|
||||
private async Task RefreshWebhooksAsync()
|
||||
{
|
||||
ShowWebHook = IsDeveloperRole && (Api.C.Status.Value?.AllowWebHook ?? false);
|
||||
if (!ShowWebHook) return;
|
||||
using var l = UIHelper.MakeLoading("刷新Webhook列表...");
|
||||
await RepositoryService.C.UpdateWebhooksFromServerAsync(Repository);
|
||||
}
|
||||
|
||||
[ReactiveCommand]
|
||||
private async ValueTask RefreshRepositoryRoleInfoAsync()
|
||||
|
||||
27
Flawless.Client/Views/ModalBox/WebhookEditDialogView.axaml
Normal file
27
Flawless.Client/Views/ModalBox/WebhookEditDialogView.axaml
Normal file
@ -0,0 +1,27 @@
|
||||
<UserControl xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:u="https://irihi.tech/ursa"
|
||||
xmlns:vm="using:Flawless.Client.ViewModels.ModalBox"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Flawless.Client.Views.ModalBox.WebhookEditDialogView"
|
||||
x:DataType="vm:WebhookEditDialogViewModel">
|
||||
|
||||
<u:Form HorizontalAlignment="Stretch" LabelPosition="Top">
|
||||
<u:Form.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Grid RowDefinitions="*, *, *" />
|
||||
</ItemsPanelTemplate>
|
||||
</u:Form.ItemsPanel>
|
||||
<u:FormItem Grid.Row="0" Label="URL">
|
||||
<TextBox Text="{Binding Url}"/>
|
||||
</u:FormItem>
|
||||
<u:FormItem Grid.Row="1" Label="Secret">
|
||||
<TextBox Text="{Binding Secret}"/>
|
||||
</u:FormItem>
|
||||
<u:FormItem Grid.Row="1" Label="Event Type">
|
||||
<u:EnumSelector SelectedValue="{Binding EventType}"/>
|
||||
</u:FormItem>
|
||||
</u:Form>
|
||||
</UserControl>
|
||||
@ -0,0 +1,13 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
|
||||
namespace Flawless.Client.Views.ModalBox;
|
||||
|
||||
public partial class WebhookEditDialogView : UserControl
|
||||
{
|
||||
public WebhookEditDialogView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@ -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:views="clr-namespace:Flawless.Client.Views"
|
||||
x:DataType="vm:RepositoryViewModel"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="Flawless.Client.Views.RepositoryPage.RepoSettingPageView">
|
||||
@ -56,18 +57,48 @@
|
||||
<Button HorizontalAlignment="Stretch" Classes="Danger" Content="Yes I Want to Delete this Repository"
|
||||
Command="{Binding DeleteRepositoryBothServerAndLocalCommand}"/>
|
||||
</u:FormItem>
|
||||
<u:FormItem Label="Webhook" IsVisible="{Binding ShowWebHook}">
|
||||
<StackPanel>
|
||||
<StackPanel Orientation="Horizontal" Spacing="10">
|
||||
<u:IconButton Content="Refresh" Icon="{StaticResource SemiIconRefresh}"
|
||||
Command="{Binding RefreshWebhooksCommand}"/>
|
||||
<u:IconButton Content="Add" Icon="{StaticResource SemiIconPlus}"
|
||||
Command="{Binding AddWebhookCommand}"
|
||||
IsVisible="{Binding IsOwnerRole}"/>
|
||||
</StackPanel>
|
||||
|
||||
<DataGrid ItemsSource="{Binding Repository.Webhooks}"
|
||||
IsReadOnly="True"
|
||||
AutoGenerateColumns="False">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="URL" Binding="{Binding TargetUrl}"/>
|
||||
<DataGridCheckBoxColumn Header="Active" Binding="{Binding Active}"/>
|
||||
<DataGridTextColumn Header="Type" Binding="{Binding EventType}"/>
|
||||
<DataGridTemplateColumn IsVisible="{Binding IsOwnerRole}">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="Toggle Activate"
|
||||
Command="{Binding $parent[views:RepositoryView].((vm:RepositoryViewModel)DataContext).ToggleWebhookCommand}"
|
||||
CommandParameter="{Binding}"/>
|
||||
<Button Content="Toggle Activate"
|
||||
Command="{Binding $parent[views:RepositoryView].((vm:RepositoryViewModel)DataContext).DeleteWebhookCommand}"
|
||||
CommandParameter="{Binding}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
</StackPanel>
|
||||
</u:FormItem>
|
||||
</u:Form>
|
||||
</ScrollViewer>
|
||||
</TabItem>
|
||||
<TabItem Header="Statics" IsVisible="{Binding IsDeveloperRole}">
|
||||
<StackPanel Width="600" HorizontalAlignment="Stretch">
|
||||
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="Hooks" IsVisible="{Binding IsOwnerRole}">
|
||||
<StackPanel Width="600" HorizontalAlignment="Stretch">
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Width="600" HorizontalAlignment="Stretch">
|
||||
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
</UserControl>
|
||||
|
||||
@ -163,7 +163,7 @@ public class RepositoryInnieController(
|
||||
return rp;
|
||||
}
|
||||
|
||||
[HttpPost("create_webhook")]
|
||||
[HttpPost("webhooks/create")]
|
||||
public async Task<IActionResult> CreateWebhook(
|
||||
string userName,
|
||||
string repositoryName,
|
||||
@ -177,7 +177,7 @@ public class RepositoryInnieController(
|
||||
return Created();
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
[HttpGet("webhooks")]
|
||||
public async Task<ActionResult<IEnumerable<Webhook>>> GetWebhooks(string userName, string repositoryName)
|
||||
{
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
@ -187,7 +187,7 @@ public class RepositoryInnieController(
|
||||
return Ok(await webhookService.GetWebhooksAsync(rp.Id));
|
||||
}
|
||||
|
||||
[HttpPost("{webhookId}/toggle")]
|
||||
[HttpPost("webhooks/{webhookId}/toggle")]
|
||||
public async Task<IActionResult> ToggleWebhook(string userName, string repositoryName, int webhookId, bool activate)
|
||||
{
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
@ -198,7 +198,7 @@ public class RepositoryInnieController(
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpDelete("{webhookId}")]
|
||||
[HttpDelete("webhooks/{webhookId}")]
|
||||
public async Task<IActionResult> DeleteWebhook(string userName, string repositoryName, int webhookId)
|
||||
{
|
||||
var user = (await userManager.GetUserAsync(HttpContext.User))!;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user