[frontend/pages] Add migrations page with alias management
This commit is contained in:
parent
f1a1ed9039
commit
93a155375c
5 changed files with 161 additions and 0 deletions
|
@ -22,6 +22,12 @@
|
||||||
<span class="text">@Loc["Account"]</span>
|
<span class="text">@Loc["Account"]</span>
|
||||||
</div>
|
</div>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
<NavLink href="/settings/migration">
|
||||||
|
<div class="sidebar-btn">
|
||||||
|
<Icon Name="Icons.AirplaneTakeoff"/>
|
||||||
|
<span class="text">@Loc["Migration"]</span>
|
||||||
|
</div>
|
||||||
|
</NavLink>
|
||||||
<NavLink href="/settings/about">
|
<NavLink href="/settings/about">
|
||||||
<div class="sidebar-btn">
|
<div class="sidebar-btn">
|
||||||
<Icon Name="Icons.Info"/>
|
<Icon Name="Icons.Info"/>
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Iceshrimp.Frontend.Core.Services;
|
||||||
|
using Iceshrimp.Shared.Schemas.Web;
|
||||||
|
|
||||||
|
namespace Iceshrimp.Frontend.Core.ControllerModels;
|
||||||
|
|
||||||
|
internal class MigrationControllerModel(ApiClient api)
|
||||||
|
{
|
||||||
|
public Task<MigrationSchemas.MigrationStatusResponse> GetMigrationStatusAsync() =>
|
||||||
|
api.CallAsync<MigrationSchemas.MigrationStatusResponse>(HttpMethod.Get, "/migration");
|
||||||
|
|
||||||
|
public Task AddAliasAsync(MigrationSchemas.MigrationRequest request) =>
|
||||||
|
api.CallAsync(HttpMethod.Post, "/migration/aliases", data: request);
|
||||||
|
|
||||||
|
public Task RemoveAliasAsync(MigrationSchemas.MigrationRequest request) =>
|
||||||
|
api.CallAsync(HttpMethod.Delete, "/migration/aliases", data: request);
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ internal class ApiService(ApiClient client)
|
||||||
public readonly TimelineControllerModel Timelines = new(client);
|
public readonly TimelineControllerModel Timelines = new(client);
|
||||||
public readonly UserControllerModel Users = new(client);
|
public readonly UserControllerModel Users = new(client);
|
||||||
public readonly FollowRequestControllerModel FollowRequests = new(client);
|
public readonly FollowRequestControllerModel FollowRequests = new(client);
|
||||||
|
public readonly MigrationControllerModel Migrations = new(client);
|
||||||
public readonly MiscControllerModel Misc = new(client);
|
public readonly MiscControllerModel Misc = new(client);
|
||||||
public readonly ProfileControllerModel Profile = new(client);
|
public readonly ProfileControllerModel Profile = new(client);
|
||||||
public readonly FilterControllerModel Filters = new(client);
|
public readonly FilterControllerModel Filters = new(client);
|
||||||
|
|
121
Iceshrimp.Frontend/Pages/Settings/Migration.razor
Normal file
121
Iceshrimp.Frontend/Pages/Settings/Migration.razor
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
@page "/settings/migration"
|
||||||
|
@using Iceshrimp.Frontend.Core.Services
|
||||||
|
@using Iceshrimp.Frontend.Localization
|
||||||
|
@using Microsoft.AspNetCore.Authorization
|
||||||
|
@using Microsoft.Extensions.Localization
|
||||||
|
@using Microsoft.AspNetCore.Components.Sections
|
||||||
|
@using Iceshrimp.Assets.PhosphorIcons
|
||||||
|
@using Iceshrimp.Shared.Schemas.Web
|
||||||
|
@using Iceshrimp.Frontend.Components
|
||||||
|
@using Iceshrimp.Frontend.Core.Miscellaneous
|
||||||
|
|
||||||
|
@attribute [Authorize]
|
||||||
|
@layout SettingsLayout
|
||||||
|
@inject ApiService Api;
|
||||||
|
@inject GlobalComponentSvc Global;
|
||||||
|
@inject IStringLocalizer<Localization> Loc;
|
||||||
|
@inject NavigationManager Nav;
|
||||||
|
|
||||||
|
<HeadTitle Text="@Loc["Migration"]"/>
|
||||||
|
|
||||||
|
<SectionContent SectionName="top-bar">
|
||||||
|
<Icon Name="Icons.AirplaneTakeoff"></Icon>
|
||||||
|
@Loc["Migration"]
|
||||||
|
</SectionContent>
|
||||||
|
|
||||||
|
@if (State is State.Loaded)
|
||||||
|
{
|
||||||
|
<div class="body">
|
||||||
|
<div class="section">
|
||||||
|
<h3>@Loc["Move to this account from an older account"]</h3>
|
||||||
|
<div class="aliases">
|
||||||
|
@foreach (var alias in Status.Aliases)
|
||||||
|
{
|
||||||
|
<div class="alias">
|
||||||
|
<a href="@alias" target="_blank">@alias</a>
|
||||||
|
<button class="button" title="@Loc["Remove alias"]" @onclick="() => DeleteAlias(alias)">
|
||||||
|
<Icon Name="Icons.Trash"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div class="new-alias">
|
||||||
|
<input class="input" placeholder="@("@old@example.com")" autocomplete="off" @bind="@Alias" @oninput="ResetAliasButtonState"/>
|
||||||
|
<StateButton OnClick="AddAlias" ExtraClasses="button" @ref="AliasButton">
|
||||||
|
<Initial>
|
||||||
|
<Icon Name="Icons.Plus"/>
|
||||||
|
</Initial>
|
||||||
|
<Loading>
|
||||||
|
<LoadingSpinner />
|
||||||
|
</Loading>
|
||||||
|
<Failed>
|
||||||
|
<Icon Name="Icons.Warning"/>
|
||||||
|
</Failed>
|
||||||
|
<Success>
|
||||||
|
<Icon Name="Icons.Check"/>
|
||||||
|
</Success>
|
||||||
|
</StateButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
private MigrationSchemas.MigrationStatusResponse Status { get; set; } = null!;
|
||||||
|
private State State { get; set; } = State.Loading;
|
||||||
|
private StateButton AliasButton { get; set; } = null!;
|
||||||
|
private string Alias { get; set; } = "";
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
|
{
|
||||||
|
Status = await Api.Migrations.GetMigrationStatusAsync();
|
||||||
|
State = State.Loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AddAlias()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(Alias)) return;
|
||||||
|
|
||||||
|
var acct = Alias.Trim().TrimStart('@').Split('@');
|
||||||
|
if (string.IsNullOrWhiteSpace(acct[0])) return;
|
||||||
|
|
||||||
|
AliasButton.State = StateButton.StateEnum.Loading;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var user = await Api.Users.LookupUserAsync(acct[0], acct.Length > 1 ? acct[1] : null);
|
||||||
|
await Api.Migrations.AddAliasAsync(new MigrationSchemas.MigrationRequest { UserId = user?.Id });
|
||||||
|
|
||||||
|
Status = await Api.Migrations.GetMigrationStatusAsync();
|
||||||
|
}
|
||||||
|
catch (ApiException e)
|
||||||
|
{
|
||||||
|
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred while adding an alias"], NoticeDialog.NoticeType.Error)!;
|
||||||
|
AliasButton.State = StateButton.StateEnum.Failed;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Alias = "";
|
||||||
|
AliasButton.State = StateButton.StateEnum.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task DeleteAlias(string uri)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await Api.Migrations.RemoveAliasAsync(new MigrationSchemas.MigrationRequest { UserUri = uri });
|
||||||
|
}
|
||||||
|
catch (ApiException e)
|
||||||
|
{
|
||||||
|
await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred while removing an alias"], NoticeDialog.NoticeType.Error)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
Status = await Api.Migrations.GetMigrationStatusAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetAliasButtonState()
|
||||||
|
{
|
||||||
|
if (AliasButton.State is StateButton.StateEnum.Failed or StateButton.StateEnum.Success)
|
||||||
|
AliasButton.State = StateButton.StateEnum.Initial;
|
||||||
|
}
|
||||||
|
}
|
17
Iceshrimp.Frontend/Pages/Settings/Migration.razor.css
Normal file
17
Iceshrimp.Frontend/Pages/Settings/Migration.razor.css
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
.alias, .new-alias {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
padding: 0.75rem;
|
||||||
|
margin: 0.2rem;
|
||||||
|
i {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.alias .button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue