Created custom CopyToClipboard button and made refinements

This commit is contained in:
Peer Schütt 2025-07-24 15:10:11 +02:00
parent 739bdb1068
commit 7f367d83aa
4 changed files with 100 additions and 90 deletions

View File

@ -0,0 +1,5 @@
<MudTooltip Text=@ToolTipMessage>
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy"
Size="Size.Small"
OnClick="@(() => CopyToClipboard(this.CopyableContent))"/>
</MudTooltip>

View File

@ -0,0 +1,42 @@
using AIStudio.Pages;
using AIStudio.Tools.PluginSystem;
using Microsoft.AspNetCore.Components;
namespace AIStudio.Components;
public partial class MudCopyClipboardButton : ComponentBase
{
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(About).Namespace, nameof(About));
/// <summary>
/// The string that will be copied when the button is clicked.
/// </summary>
[Parameter]
public required string CopyableContent { get; set; }
/// <summary>
/// The tooltip that should be shown to the user.
/// </summary>
[Parameter]
public string ToolTipMessage { get; set; } = TB("Copies the content to the clipboard");
[Inject]
private IJSRuntime JsRuntime { get; set; } = null!;
[Inject]
private ISnackbar Snackbar { get; init; } = null!;
private async Task CopyToClipboard(string text)
{
try
{
await this.JsRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text);
this.Snackbar.Add(TB("Successfully copied the content to your clipboard"), Severity.Success);
}
catch (Exception)
{
this.Snackbar.Add(TB("Failed to copy the content to your clipboard"), Severity.Error);
}
}
}

View File

@ -1,6 +1,4 @@
@attribute [Route(Routes.ABOUT)] @attribute [Route(Routes.ABOUT)]
@using AIStudio.Tools.PluginSystem
@using AIStudio.Tools.Services
@inherits MSGComponentBase @inherits MSGComponentBase
<div class="inner-scrolling-context"> <div class="inner-scrolling-context">
@ -26,57 +24,50 @@
<MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@TauriVersion"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Memory" Text="@TauriVersion"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Translate" Text="@this.OSLanguage"/> <MudListItem T="string" Icon="@Icons.Material.Outlined.Translate" Text="@this.OSLanguage"/>
<MudListItem T="string" Icon="@Icons.Material.Outlined.Business"> <MudListItem T="string" Icon="@Icons.Material.Outlined.Business">
@{ @switch (currentEnvironment.IsActive)
var configPlug = PluginFactory.AvailablePlugins.FirstOrDefault(x => x.Type is PluginType.CONFIGURATION);
var currentEnvironment = EnterpriseEnvironmentService.CURRENT_ENVIRONMENT;
}
@if (!currentEnvironment.IsActive && configPlug is null)
{ {
case false when configPlug is null:
<MudText>@T("AI Studio runs without an enterprise configuration.")</MudText> <MudText>@T("AI Studio runs without an enterprise configuration.")</MudText>
} break;
else if (!currentEnvironment.IsActive) case false:
{ <MudText>@T("AI Studio runs with an enterprise configuration using the configuration plugin, without central configuration management.")</MudText>
<MudText>@T("AI Studio runs with an enterprise configuration using the configuration plugin.")</MudText>
<MudCollapse Expanded="@showConfigDetails"> <MudCollapse Expanded="@showConfigDetails">
<MudText Typo="Typo.caption" Class="mt-2">Plugin ID: @configPlug!.Id</MudText> <MudText>@T("Configuration Plugin ID:") @configPlug!.Id
<MudCopyClipboardButton CopyableContent=@configPlug!.Id.ToString()/>
</MudText>
</MudCollapse> </MudCollapse>
} break;
else if (currentEnvironment.IsActive && configPlug is null) case true when configPlug is null:
{ <MudText>@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is not yet available.")</MudText>
<MudText>@T("AI Studio runs with an enterprise configuration. The configuration plugin is not yet available.")</MudText>
<MudCollapse Expanded="@showConfigDetails"> <MudCollapse Expanded="@showConfigDetails">
<MudText Typo="Typo.caption">Config ID: @currentEnvironment.ConfigurationId</MudText> <MudText>@T("Configuration Plugin ID:") @currentEnvironment.ConfigurationId
<MudText Typo="Typo.caption">Server URL: @currentEnvironment.ConfigurationServerUrl</MudText> <MudCopyClipboardButton ToolTipMessage="@T("Copies the config ID to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationId.ToString()/>
</MudText>
<MudText>@T("Configuration Server:") @currentEnvironment.ConfigurationServerUrl
<MudCopyClipboardButton ToolTipMessage="@T("Copies the server URL to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationServerUrl/>
</MudText>
</MudCollapse> </MudCollapse>
} break;
else if (currentEnvironment.IsActive) case true:
{ <MudText>@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is active.")</MudText>
<MudText>@T("AI Studio runs with an enterprise configuration. The configuration plugin is active.")</MudText>
<MudCollapse Expanded="@showConfigDetails"> <MudCollapse Expanded="@showConfigDetails">
<div class="d-flex align-center gap-2"> <MudText Class="ml-4">@T("Configuration Plugin ID:") @currentEnvironment.ConfigurationId
<MudText Typo="Typo.caption">Config ID: @currentEnvironment.ConfigurationId</MudText> <MudCopyClipboardButton ToolTipMessage="@T("Copies the config ID to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationId.ToString()/>
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" </MudText>
Size="Size.Small"
OnClick="@(() => CopyToClipboard(currentEnvironment.ConfigurationId.ToString()))" <MudText Class="ml-4">@T("Configuration Server:") @currentEnvironment.ConfigurationServerUrl
Title="Copy Config ID" /> <MudCopyClipboardButton ToolTipMessage="@T("Copies the server URL to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationServerUrl/>
</div> </MudText>
<div class="d-flex align-center gap-2">
<MudText Typo="Typo.caption">Server URL: @currentEnvironment.ConfigurationServerUrl</MudText>
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy"
Size="Size.Small"
OnClick="@(() => CopyToClipboard(currentEnvironment.ConfigurationServerUrl))"
Title="Copy Server URL" />
</div>
</MudCollapse> </MudCollapse>
break;
} }
<MudButton StartIcon="@(showConfigDetails ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)" <MudButton StartIcon="@(showConfigDetails ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)"
Size="Size.Small" Size="Size.Small"
Variant="Variant.Text" Variant="Variant.Text"
Class="mt-1" OnClick="@this.ToggleEnterpriseConfigDetails">
OnClick="@this.ToggleConfigDetails"> @(showConfigDetails ? @T("Hide Details") : @T("Show Details"))
@(showConfigDetails ? "Hide Details" : "Show Details")
</MudButton> </MudButton>
</MudListItem> </MudListItem>
</MudList> </MudList>

View File

@ -58,6 +58,12 @@ public partial class About : MSGComponentBase
private GetLogPathsResponse logPaths; private GetLogPathsResponse logPaths;
private bool showConfigDetails = false;
private IPluginMetadata? configPlug = PluginFactory.AvailablePlugins.FirstOrDefault(x => x.Type is PluginType.CONFIGURATION);
private EnterpriseEnvironment currentEnvironment = EnterpriseEnvironmentService.CURRENT_ENVIRONMENT;
#region Overrides of ComponentBase #region Overrides of ComponentBase
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
@ -120,49 +126,15 @@ public partial class About : MSGComponentBase
await this.DeterminePandocVersion(); await this.DeterminePandocVersion();
} }
private bool showConfigDetails = false; private void ToggleEnterpriseConfigDetails()
private void ToggleConfigDetails()
{ {
// can configPlug and currentEnvironment change?
this.configPlug = PluginFactory.AvailablePlugins.FirstOrDefault(x => x.Type is PluginType.CONFIGURATION);
this.currentEnvironment = EnterpriseEnvironmentService.CURRENT_ENVIRONMENT;
this.showConfigDetails = !this.showConfigDetails; this.showConfigDetails = !this.showConfigDetails;
} }
[Inject] private IJSRuntime JSRuntime { get; set; } = default!;
private async Task CopyToClipboard(string text)
{
try
{
await this.JSRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text);
this.Snackbar.Add("Copied to clipboard!", Severity.Success);
}
catch (Exception)
{
this.Snackbar.Add("Failed to copy to clipboard", Severity.Error);
}
}
private string GetEnterpriseEnvironment()
{
var configPlug = PluginFactory.AvailablePlugins.FirstOrDefault(x => x.Type is PluginType.CONFIGURATION);
var currentEnvironment = EnterpriseEnvironmentService.CURRENT_ENVIRONMENT;
switch (currentEnvironment)
{
case { IsActive: false } when configPlug is null:
return T("AI Studio runs without an enterprise configuration.");
case { IsActive: false }:
return string.Format(T("AI Studio runs with an enterprise configuration using the configuration plugin '{0}', without central configuration management."), configPlug.Id);
case { IsActive: true } when configPlug is null:
return string.Format(T("AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is not yet available."), currentEnvironment.ConfigurationId, currentEnvironment.ConfigurationServerUrl);
case { IsActive: true }:
return string.Format(T("AI Studio runs with an enterprise configuration id '{0}' and configuration server URL '{1}'. The configuration plugin is active."), currentEnvironment.ConfigurationId, currentEnvironment.ConfigurationServerUrl);
}
}
private async Task CopyStartupLogPath() private async Task CopyStartupLogPath()
{ {
await this.RustService.CopyText2Clipboard(this.Snackbar, this.logPaths.LogStartupPath); await this.RustService.CopyText2Clipboard(this.Snackbar, this.logPaths.LogStartupPath);