Changed all icons of AI Studio to Lucide (#1187)

This commit is contained in:
Thorsten Sommer authored and GitHub committed 2026-11-11 14:20:49 +01:00
1 parent 9a676101f7
commit 7ef26cd5c8
352 files changed
+6257 -1616

No files matched your search

@@ -170,7 +170,7 @@ public sealed class AssistantAuditAgent(ILogger<AssistantAuditAgent> logger, ILo
? TB("The selected provider is not trusted enough for security checks. Pick one which meets the confidence required here, or choose a dedicated provider for security checks in the app settings.")
: TB("No provider is configured for the Security Audit Agent.");
await MessageBus.INSTANCE.SendError(new (Icons.Material.Filled.SettingsSuggest, message));
await MessageBus.INSTANCE.SendError(new (AppIcons.AGENT, message));
return new AssistantAuditResult
{
@@ -270,7 +270,7 @@ public sealed class AssistantAuditAgent(ILogger<AssistantAuditAgent> logger, ILo
if (response.Content is not ContentText content || string.IsNullOrWhiteSpace(content.Text))
{
logger.LogWarning($"The assistant plugin audit agent did not return text: {response}");
await MessageBus.INSTANCE.SendWarning(new (Icons.Material.Filled.PendingActions, string.Format(TB("The security check could not be completed because the LLM's response was unusable. The audit level remains Unknown, so please try again later."))));
await MessageBus.INSTANCE.SendWarning(new (AppIcons.AUDIT_INCOMPLETE, string.Format(TB("The security check could not be completed because the LLM's response was unusable. The audit level remains Unknown, so please try again later."))));
return new AssistantAuditResult
{
@@ -34,10 +34,10 @@ public static class AssistantAuditLevelExtensions
public string Icon => level switch
{
AssistantAuditLevel.DANGEROUS => Icons.Material.Filled.Dangerous,
AssistantAuditLevel.CAUTION => Icons.Material.Filled.Warning,
AssistantAuditLevel.SAFE => Icons.Material.Filled.Verified,
_ => Icons.Material.Filled.HelpOutline,
AssistantAuditLevel.DANGEROUS => AppIcons.SECURITY_DANGEROUS,
AssistantAuditLevel.CAUTION => AppIcons.WARNING,
AssistantAuditLevel.SAFE => AppIcons.AUDIT_SAFE,
_ => AppIcons.UNKNOWN,
};
/// <summary>
@@ -1,11 +1,11 @@
@attribute [Route(Routes.ASSISTANT_AGENDA)]
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogAgenda>
<MudTextField T="string" @bind-Text="@this.inputName" Validation="@this.ValidateName" Label="@T("Meeting Name")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Tag" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Name the meeting, seminar, etc.")" Placeholder="@T("Weekly jour fixe")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputTopic" Validation="@this.ValidateTopic" Label="@T("Topic")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.EventNote" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the topic of the meeting, seminar, etc. Is it about quantum computing, software engineering, or is it a general business meeting?")" Placeholder="@T("Project meeting")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputName" Validation="@this.ValidateName" Label="@T("Meeting Name")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.NAME" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Name the meeting, seminar, etc.")" Placeholder="@T("Weekly jour fixe")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputTopic" Validation="@this.ValidateTopic" Label="@T("Topic")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.MEETING_TOPIC" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the topic of the meeting, seminar, etc. Is it about quantum computing, software engineering, or is it a general business meeting?")" Placeholder="@T("Project meeting")" Class="mb-3"/>
<ReadFileContent Text="@T("Load the content list from file")" FileContent="@this.inputContent" FileContentChanged="@this.ContentLoadedFromFile" EnableDragDrop="true"/>
<DebouncedTextField @bind-Text="@this.inputContent" ValidationFunc="@this.ValidateContent" DebounceTime="TimeSpan.FromSeconds(1)" Label="@T("Content list")" Lines="6" Attributes="@USER_INPUT_ATTRIBUTES" HelpText="@T("Bullet list the content of the meeting, seminar, etc. roughly. Use dashes (-) to separate the items.")" Placeholder="@PLACEHOLDER_CONTENT" WhenTextCanged="@this.OnContentChanged" Icon="@Icons.Material.Filled.ListAlt"/>
<MudSelect T="string" Label="@T("(Optional) What topics should be the focus?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
<DebouncedTextField @bind-Text="@this.inputContent" ValidationFunc="@this.ValidateContent" DebounceTime="TimeSpan.FromSeconds(1)" Label="@T("Content list")" Lines="6" Attributes="@USER_INPUT_ATTRIBUTES" HelpText="@T("Bullet list the content of the meeting, seminar, etc. roughly. Use dashes (-) to separate the items.")" Placeholder="@PLACEHOLDER_CONTENT" WhenTextCanged="@this.OnContentChanged" Icon="@AppIcons.LIST"/>
<MudSelect T="string" Label="@T("(Optional) What topics should be the focus?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LIST">
@foreach (var contentLine in this.contentLines)
{
@if(!this.justBriefly.Contains(contentLine))
@@ -17,7 +17,7 @@
}
</MudSelect>
<MudSelect T="string" Label="@T("(Optional) What topics should only be briefly addressed?")" MultiSelection="@true" @bind-SelectedValues="@this.justBriefly" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
<MudSelect T="string" Label="@T("(Optional) What topics should only be briefly addressed?")" MultiSelection="@true" @bind-SelectedValues="@this.justBriefly" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LIST">
@foreach (var contentLine in this.contentLines)
{
@if(!this.selectedFoci.Contains(contentLine))
@@ -29,19 +29,19 @@
}
</MudSelect>
<MudTextField T="string" @bind-Text="@this.inputObjective" Validation="@this.ValidateObjective" Label="@T("Objective")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Flag" Variant="Variant.Outlined" Lines="3" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the objective(s) of the meeting, seminar, etc. What should be achieved?")" Placeholder="@T("Discuss the current project status and plan the next steps.")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputModerator" Validation="@this.ValidateModerator" Label="@T("Moderator")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person3" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Who will moderate the meeting, seminar, etc.?")" Placeholder="Jane Doe" Class="mb-3" />
<MudTextField T="string" @bind-Text="@this.inputDuration" Validation="@this.ValidateDuration" Label="@T("Duration")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Schedule" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("How long will the meeting, seminar, etc. last? E.g., '2 hours', or '2 days (first day 8 hours, then 4 hours)', etc.")" Placeholder="@T("2 hours")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputStartTime" Validation="@this.ValidateStartTime" Label="Start time" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Schedule" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("When will the meeting, seminar, etc. start? E.g., '9:00 AM', or '9:00 AM (CET)', etc. When the meeting is a multi-day event, specify the start time for each day.")" Placeholder="@T("9:00 AM")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputObjective" Validation="@this.ValidateObjective" Label="@T("Objective")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.OBJECTIVE" Variant="Variant.Outlined" Lines="3" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the objective(s) of the meeting, seminar, etc. What should be achieved?")" Placeholder="@T("Discuss the current project status and plan the next steps.")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputModerator" Validation="@this.ValidateModerator" Label="@T("Moderator")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.MODERATOR" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Who will moderate the meeting, seminar, etc.?")" Placeholder="Jane Doe" Class="mb-3" />
<MudTextField T="string" @bind-Text="@this.inputDuration" Validation="@this.ValidateDuration" Label="@T("Duration")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.TIME" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("How long will the meeting, seminar, etc. last? E.g., '2 hours', or '2 days (first day 8 hours, then 4 hours)', etc.")" Placeholder="@T("2 hours")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputStartTime" Validation="@this.ValidateStartTime" Label="Start time" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.TIME" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("When will the meeting, seminar, etc. start? E.g., '9:00 AM', or '9:00 AM (CET)', etc. When the meeting is a multi-day event, specify the start time for each day.")" Placeholder="@T("9:00 AM")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputWhoIsPresenting" Label="@T("(Optional) Who is presenting?")" Variant="Variant.Outlined" Lines="6" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("(Optional) List the persons who will present at the meeting, seminar, etc. Use dashes (-) to separate the items.")" Placeholder="@PLACEHOLDER_WHO_IS_PRESENTING" Class="mb-3"/>
<MudTextSwitch Label="@T("Do the participants need to get to know each other first?")" @bind-Value="@this.introduceParticipants" LabelOn="@T("Yes, introduce participants")" LabelOff="@T("No, participants know each other")" />
<EnumSelection T="NumberParticipants" @bind-Value="@this.numberParticipants" NameFunc="@(participants => participants.Name)" Icon="@Icons.Material.Filled.Group" Label="@T("Number of participants")" ValidateSelection="@this.ValidateNumberParticipants"/>
<EnumSelection T="NumberParticipants" @bind-Value="@this.numberParticipants" NameFunc="@(participants => participants.Name)" Icon="@AppIcons.PARTICIPANTS" Label="@T("Number of participants")" ValidateSelection="@this.ValidateNumberParticipants"/>
<MudTextSwitch Label="@T("Should the participants be involved passively or actively?")" @bind-Value="@this.activeParticipation" LabelOn="@T("Active participation, like world café, discussions, etc.")" LabelOff="@T("Passive participation, like presentations, lectures, etc.")" />
<MudTextSwitch Label="@T("Is this a virtual event, e.g., a call or webinar?")" @bind-Value="@this.isMeetingVirtual" LabelOn="@T("Yes, this is a virtual event")" LabelOff="@T("No, this is a physical event")" />
@if (!this.isMeetingVirtual)
{
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<MudTextField T="string" @bind-Text="@this.inputLocation" Validation="@this.ValidateLocation" Label="@T("Location")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.MyLocation" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Where will the meeting, seminar, etc. take place?")" Placeholder="@T("Hamburg, Germany")" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputLocation" Validation="@this.ValidateLocation" Label="@T("Location")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LOCATION" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Where will the meeting, seminar, etc. take place?")" Placeholder="@T("Hamburg, Germany")" Class="mb-3"/>
<MudTextSwitch Label="@T("Should there be a joint dinner?")" @bind-Value="@this.goingToDinner" LabelOn="@T("Yes, there should be a joint dinner")" LabelOff="@T("No, there should be no joint dinner")" />
<MudTextSwitch Label="@T("Should there be a social activity?")" @bind-Value="@this.doingSocialActivity" LabelOn="@T("Yes, there should be a social activity")" LabelOff="@T("No, there should be no social activity")" />
<MudTextSwitch Label="@T("Do participants need to arrive and depart?")" @bind-Value="@this.needToArriveAndDepart" LabelOn="@T("Yes, participants need to arrive and depart")" LabelOff="@T("No, participants do not need to arrive and depart")" />
@@ -52,5 +52,5 @@
</MudPaper>
}
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -20,7 +20,7 @@
@if (this.HasSettingsPanel)
{
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" OnClick="@(async () => await this.OpenSettingsDialog())"/>
<MudIconButton Variant="Variant.Text" Icon="@AppIcons.SETTINGS" OnClick="@(async () => await this.OpenSettingsDialog())"/>
}
</MudStack>
@@ -48,7 +48,7 @@
@if (this.IsProcessing)
{
<MudTooltip Text="@TB("Stop generation")">
<MudIconButton Variant="Variant.Filled" Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="@(async () => await this.CancelStreaming())"/>
<MudIconButton Variant="Variant.Filled" Icon="@AppIcons.STOP" Color="Color.Error" OnClick="@(async () => await this.CancelStreaming())"/>
</MudTooltip>
}
</MudStack>
@@ -127,7 +127,7 @@
{
@if (this.ShowSendTo && this.VisibleSendToAssistants.Count > 0)
{
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded" MaxHeight="@MenuDefaults.MAX_HEIGHT">
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@AppIcons.SEND_TO" EndIcon="@AppIcons.DROPDOWN_MENU" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded" MaxHeight="@MenuDefaults.MAX_HEIGHT">
@foreach (var assistant in this.VisibleSendToAssistants)
{
<MudMenuItem OnClick="@(async () => await this.SendToAssistant(assistant, new()))">
@@ -159,7 +159,7 @@
case SendToButton sendToButton:
@if (this.VisibleSendToAssistants.Count > 0)
{
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@Icons.Material.Filled.Apps" EndIcon="@Icons.Material.Filled.KeyboardArrowDown" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded" MaxHeight="@MenuDefaults.MAX_HEIGHT">
<MudMenu AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" StartIcon="@AppIcons.SEND_TO" EndIcon="@AppIcons.DROPDOWN_MENU" Label="@TB("Send to ...")" Variant="Variant.Filled" Style="@this.GetSendToColor()" Class="rounded" MaxHeight="@MenuDefaults.MAX_HEIGHT">
@foreach (var assistant in this.VisibleSendToAssistants)
{
<MudMenuItem OnClick="@(async () => await this.SendToAssistant(assistant, sendToButton))">
@@ -174,14 +174,14 @@
@if (this.ShowCopyResult)
{
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.ContentCopy" OnClick="@(async () => await this.CopyToClipboard())">
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.COPY" OnClick="@(async () => await this.CopyToClipboard())">
@TB("Copy result")
</MudButton>
}
@if (this.ShowReset)
{
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@Icons.Material.Filled.Refresh" Disabled="@this.MediaTranscriptionService.IsBusy(this.CurrentMediaImportOwner)" OnClick="@(async () => await this.InnerResetForm())">
<MudButton Variant="Variant.Filled" Style="@this.GetResetColor()" StartIcon="@AppIcons.RESET" Disabled="@this.MediaTranscriptionService.IsBusy(this.CurrentMediaImportOwner)" OnClick="@(async () => await this.InnerResetForm())">
@TB("Reset")
</MudButton>
}
@@ -425,14 +425,14 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
sessionStatus = AssistantSessionStatus.FAILED;
errorMessage = e.UserMessage;
this.Logger.LogError(e, "The provider request failed for assistant '{AssistantTitle}'. Status={StatusCode}, Reason='{ReasonPhrase}', Body='{ResponseBody}'", this.Title, e.StatusCode, e.ReasonPhrase, e.ResponseBody);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.CloudOff, e.UserMessage));
await MessageBus.INSTANCE.SendError(new(AppIcons.PROVIDER_ERROR, e.UserMessage));
}
catch (Exception e)
{
sessionStatus = AssistantSessionStatus.FAILED;
errorMessage = e.Message;
this.Logger.LogError(e, "The assistant session '{AssistantTitle}' failed.", this.Title);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Stream, string.Format(this.TB("The assistant failed. The message is: '{0}'"), e.Message)));
await MessageBus.INSTANCE.SendError(new(AppIcons.ANSWER_STREAM, string.Format(this.TB("The assistant failed. The message is: '{0}'"), e.Message)));
}
finally
{
@@ -769,7 +769,7 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
catch (ProviderRequestException e)
{
this.Logger.LogError(e, "The provider request failed for assistant '{AssistantTitle}'. Status={StatusCode}, Reason='{ReasonPhrase}', Body='{ResponseBody}'", this.Title, e.StatusCode, e.ReasonPhrase, e.ResponseBody);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.CloudOff, e.UserMessage));
await MessageBus.INSTANCE.SendError(new(AppIcons.PROVIDER_ERROR, e.UserMessage));
if (this.ResultingContentBlock is not null && string.IsNullOrWhiteSpace(aiText.Text))
{
@@ -1091,22 +1091,22 @@ public abstract partial class AssistantBase<TSettings> : AssistantLowerBase wher
if (outcome.Failures.Count > 0)
{
var message = string.Join(Environment.NewLine, outcome.Failures.Select(failure => $"{failure.FileName}: {failure.UserMessage}"));
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, message));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, message));
}
else if (outcome.Status is MediaImportStatus.FAILED)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, this.TB("The media file could not be transcribed.")));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, this.TB("The media file could not be transcribed.")));
}
if (outcome.Warnings.Count > 0)
{
var message = string.Join(Environment.NewLine, outcome.Warnings.Select(warning => $"{warning.FileName}: {warning.UserMessage}"));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, message));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, message));
}
if (outcome.Status is MediaImportStatus.CANCELLED)
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, this.TB("The media transcription was canceled.")));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, this.TB("The media transcription was canceled.")));
}
}
@@ -21,7 +21,7 @@
<div class="mt-6">
<FilePatternSelection>
<AllowedContent>
<MudTextField T="string" @bind-Text="@this.filePatterns" Validation="@this.ValidateFilePatterns" Immediate="@true" Disabled="@this.isProcessingBatch" Label="@T("Files to include")" AdornmentIcon="@Icons.Material.Filled.Restore" Adornment="Adornment.End" OnAdornmentClick="@this.RestoreDefaultFilePatterns" AdornmentAriaLabel="@T("Restore default patterns")" Lines="1" Sizing="InputSizing.Auto" MaxLines="@FilePatternSelection.MAX_FIELD_LINES" Class="pattern-text-field" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.filePatterns" Validation="@this.ValidateFilePatterns" Immediate="@true" Disabled="@this.isProcessingBatch" Label="@T("Files to include")" AdornmentIcon="@AppIcons.RESTORE_DEFAULT" Adornment="Adornment.End" OnAdornmentClick="@this.RestoreDefaultFilePatterns" AdornmentAriaLabel="@T("Restore default patterns")" Lines="1" Sizing="InputSizing.Auto" MaxLines="@FilePatternSelection.MAX_FIELD_LINES" Class="pattern-text-field" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
</AllowedContent>
</FilePatternSelection>
</div>
@@ -35,7 +35,7 @@
</MudJustifiedText>
<MudStack Class="mb-3">
<MudButton OnClick="@this.ToggleExpertSettings" Variant="Variant.Text" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Tune">
<MudButton OnClick="@this.ToggleExpertSettings" Variant="Variant.Text" Color="Color.Primary" StartIcon="@AppIcons.ADVANCED_SETTINGS">
@(this.showExpertSettings ? T("Hide Expert Settings") : T("Show Expert Settings"))
</MudButton>
<MudDivider/>
@@ -59,7 +59,7 @@
@T("Instructions")
</MudText>
<MudSelect T="BatchProcessingPromptSource" Value="@this.promptSource" ValueChanged="@this.PromptSourceChanged" Disabled="@this.isProcessingBatch" AdornmentIcon="@Icons.Material.Filled.EditNote" Adornment="Adornment.Start" Label="@T("Source of the instructions")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
<MudSelect T="BatchProcessingPromptSource" Value="@this.promptSource" ValueChanged="@this.PromptSourceChanged" Disabled="@this.isProcessingBatch" AdornmentIcon="@AppIcons.PROMPT" Adornment="Adornment.Start" Label="@T("Source of the instructions")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
@foreach (var source in Enum.GetValues<BatchProcessingPromptSource>())
{
<MudSelectItem Value="@source">
@@ -117,7 +117,7 @@ else
}
else
{
<MudSelect T="DataDocumentAnalysisPolicy" Value="@this.selectedPolicy" ValueChanged="@this.SelectedPolicyChanged" Disabled="@this.isProcessingBatch" AdornmentIcon="@Icons.Material.Filled.Policy" Adornment="Adornment.Start" Label="@T("Document analysis policy")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
<MudSelect T="DataDocumentAnalysisPolicy" Value="@this.selectedPolicy" ValueChanged="@this.SelectedPolicyChanged" Disabled="@this.isProcessingBatch" AdornmentIcon="@AppIcons.ANALYSIS_POLICY" Adornment="Adornment.Start" Label="@T("Document analysis policy")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
@foreach (var policy in this.SettingsManager.ConfigurationData.DocumentAnalysis.Policies)
{
<MudSelectItem Value="@policy">
@@ -145,7 +145,7 @@ else
@T("Output")
</MudText>
<MudSelect T="BatchProcessingOutputMode" @bind-Value="@this.outputMode" Disabled="@this.isProcessingBatch" AdornmentIcon="@Icons.Material.Filled.Output" Adornment="Adornment.Start" Label="@T("Output mode")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
<MudSelect T="BatchProcessingOutputMode" @bind-Value="@this.outputMode" Disabled="@this.isProcessingBatch" AdornmentIcon="@AppIcons.OUTPUT" Adornment="Adornment.Start" Label="@T("Output mode")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
@foreach (var mode in Enum.GetValues<BatchProcessingOutputMode>())
{
<MudSelectItem Value="@mode">
@@ -156,7 +156,7 @@ else
@if (this.outputMode is BatchProcessingOutputMode.INDIVIDUAL_FILES)
{
<MudSelect T="FileExportFormat" @bind-Value="@this.resultFileFormat" Disabled="@this.isProcessingBatch" AdornmentIcon="@Icons.Material.Filled.Description" Adornment="Adornment.Start" Label="@T("File format")" HelperText="@T("Choose the format of the result files. Everything except Markdown is converted by Pandoc, which AI Studio offers to install when it is missing.")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
<MudSelect T="FileExportFormat" @bind-Value="@this.resultFileFormat" Disabled="@this.isProcessingBatch" AdornmentIcon="@AppIcons.DOCUMENT" Adornment="Adornment.Start" Label="@T("File format")" HelperText="@T("Choose the format of the result files. Everything except Markdown is converted by Pandoc, which AI Studio offers to install when it is missing.")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
@foreach (var format in FileExportFormat.AnswerFormats)
{
<MudSelectItem Value="@format">
@@ -171,11 +171,11 @@ else
}
else
{
<MudTextField T="string" @bind-Text="@this.csvFileName" Validation="@this.ValidateCsvFileName" Immediate="@true" Disabled="@this.isProcessingBatch" Label="@T("Name of the results table (optional)")" HelperText="@T("The file name of the CSV results table. We add the ending .csv when it is missing. When left empty, we use 'batch-results.csv'.")" AdornmentIcon="@Icons.Material.Filled.Description" Adornment="Adornment.Start" Variant="Variant.Outlined" Margin="Margin.Normal" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.csvFileName" Validation="@this.ValidateCsvFileName" Immediate="@true" Disabled="@this.isProcessingBatch" Label="@T("Name of the results table (optional)")" HelperText="@T("The file name of the CSV results table. We add the ending .csv when it is missing. When left empty, we use 'batch-results.csv'.")" AdornmentIcon="@AppIcons.DOCUMENT" Adornment="Adornment.Start" Variant="Variant.Outlined" Margin="Margin.Normal" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.resultColumnHeader" Disabled="@this.isProcessingBatch" Label="@T("Header of the result column (optional)")" HelperText="@T("The results table contains one row per document, starting with the file name. Here you can name the column that holds the AI answer, e.g., Summary. When left empty, we use 'Result'.")" AdornmentIcon="@Icons.Material.Filled.TableChart" Adornment="Adornment.Start" Variant="Variant.Outlined" Margin="Margin.Normal" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.resultColumnHeader" Disabled="@this.isProcessingBatch" Label="@T("Header of the result column (optional)")" HelperText="@T("The results table contains one row per document, starting with the file name. Here you can name the column that holds the AI answer, e.g., Summary. When left empty, we use 'Result'.")" AdornmentIcon="@AppIcons.RESULT_COLUMN" Adornment="Adornment.Start" Variant="Variant.Outlined" Margin="Margin.Normal" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudSelect T="BatchProcessingCsvSeparator" @bind-Value="@this.csvSeparator" Disabled="@this.isProcessingBatch" AdornmentIcon="@Icons.Material.Filled.FormatListBulleted" Adornment="Adornment.Start" Label="@T("Column separator")" HelperText="@T("Choose which character separates the columns of the results table.")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
<MudSelect T="BatchProcessingCsvSeparator" @bind-Value="@this.csvSeparator" Disabled="@this.isProcessingBatch" AdornmentIcon="@AppIcons.CSV_SEPARATOR" Adornment="Adornment.Start" Label="@T("Column separator")" HelperText="@T("Choose which character separates the columns of the results table.")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3">
@foreach (var separator in Enum.GetValues<BatchProcessingCsvSeparator>())
{
<MudSelectItem Value="@separator">
@@ -186,7 +186,7 @@ else
@if (this.csvSeparator is BatchProcessingCsvSeparator.CUSTOM)
{
<MudTextField T="string" @bind-Text="@this.customCsvSeparator" Validation="@this.ValidateCustomCsvSeparator" Immediate="@true" Disabled="@this.isProcessingBatch" Label="@T("Custom column separator")" HelperText="@T("Enter one punctuation or symbol character.")" AdornmentIcon="@Icons.Material.Filled.Edit" Adornment="Adornment.Start" Variant="Variant.Outlined" Margin="Margin.Normal" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.customCsvSeparator" Validation="@this.ValidateCustomCsvSeparator" Immediate="@true" Disabled="@this.isProcessingBatch" Label="@T("Custom column separator")" HelperText="@T("Enter one punctuation or symbol character.")" AdornmentIcon="@AppIcons.CSV_SEPARATOR" Adornment="Adornment.Start" Variant="Variant.Outlined" Margin="Margin.Normal" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
}
}
@@ -219,7 +219,7 @@ else
@if (this.pauseBeforeNextFileSeconds > 0)
{
<MudAlert Severity="Severity.Info" Icon="@Icons.Material.Filled.HourglassTop" Dense="true" Class="mb-3">
<MudAlert Severity="Severity.Info" Icon="@AppIcons.PENDING" Dense="true" Class="mb-3">
@(string.Format(T("Waiting {0} seconds before starting the next file."), this.pauseBeforeNextFileSeconds))
</MudAlert>
}
@@ -248,7 +248,7 @@ else
@if (this.isProcessingBatch)
{
<MudButton OnClick="@this.CancelBatchProcessingAsync" Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Cancel" Class="mb-3">
<MudButton OnClick="@this.CancelBatchProcessingAsync" Variant="Variant.Filled" Color="Color.Error" StartIcon="@AppIcons.CANCEL" Class="mb-3">
@T("Cancel the batch run")
</MudButton>
}
@@ -269,7 +269,7 @@ else
@switch (fileResult.Status)
{
case BatchProcessingFileStatus.QUEUED:
<MudIcon Icon="@Icons.Material.Filled.Schedule" Size="Size.Small" Title="@T("Queued")"/>
<MudIcon Icon="@AppIcons.PENDING" Size="Size.Small" Title="@T("Queued")"/>
break;
case BatchProcessingFileStatus.PROCESSING:
@@ -277,15 +277,15 @@ else
break;
case BatchProcessingFileStatus.DONE:
<MudIcon Icon="@Icons.Material.Filled.CheckCircle" Color="Color.Success" Size="Size.Small" Title="@T("Done")"/>
<MudIcon Icon="@AppIcons.SUCCESS" Color="Color.Success" Size="Size.Small" Title="@T("Done")"/>
break;
case BatchProcessingFileStatus.FAILED:
<MudIcon Icon="@Icons.Material.Filled.Error" Color="Color.Error" Size="Size.Small" Title="@T("Failed")"/>
<MudIcon Icon="@AppIcons.ERROR" Color="Color.Error" Size="Size.Small" Title="@T("Failed")"/>
break;
case BatchProcessingFileStatus.CANCELED:
<MudIcon Icon="@Icons.Material.Filled.Cancel" Color="Color.Warning" Size="Size.Small" Title="@T("Canceled")"/>
<MudIcon Icon="@AppIcons.CANCELED" Color="Color.Warning" Size="Size.Small" Title="@T("Canceled")"/>
break;
}
</td>
@@ -128,13 +128,13 @@ public partial class AssistantBatchProcessing
if (extraction.Outcome is FileExtractionOutcome.PARTIAL)
{
this.Logger.LogWarning("Parts of the batch file '{FilePath}' could not be read: pages={FailedPages}.", fileResult.FilePath, string.Join(", ", extraction.FailedPages));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Description, extraction.ToPartialUserMessage(fileResult.FileName)));
await this.MessageBus.SendWarning(new(AppIcons.DOCUMENT, extraction.ToPartialUserMessage(fileResult.FileName)));
}
if (extraction.HasExtensionMismatch)
{
this.Logger.LogWarning("The batch file '{FilePath}' is actually a '{DetectedFormat}'.", fileResult.FilePath, extraction.DetectedFormat);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.RuleFolder, extraction.ToExtensionMismatchUserMessage(fileResult.FileName)));
await this.MessageBus.SendWarning(new(AppIcons.FILE_TYPE_MISMATCH, extraction.ToExtensionMismatchUserMessage(fileResult.FileName)));
}
if (!string.IsNullOrWhiteSpace(extraction.Content))
@@ -162,7 +162,7 @@ public partial class AssistantBatchProcessing
return;
this.hasReportedWriteFailure = true;
await this.MessageBus.SendError(new(Icons.Material.Filled.SaveAs, string.Format(T("Was not able to write '{0}'. Please make sure that the file is not opened in another application. The results of this run are incomplete on disk. The message is: '{1}'"), Path.GetFileName(targetFilePath), e.Message)));
await this.MessageBus.SendError(new(AppIcons.SAVE_FAILED, string.Format(T("Was not able to write '{0}'. Please make sure that the file is not opened in another application. The results of this run are incomplete on disk. The message is: '{1}'"), Path.GetFileName(targetFilePath), e.Message)));
}
}
@@ -195,7 +195,7 @@ public partial class AssistantBatchProcessing
// Without this message, continuing the run would silently process
// every document again, because we recognize nothing as completed:
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Warning, T("Was not able to read the log of the previous run. Continuing the run would process all documents again.")));
await this.MessageBus.SendWarning(new(AppIcons.WARNING, T("Was not able to read the log of the previous run. Continuing the run would process all documents again.")));
}
return entries;
@@ -227,7 +227,7 @@ public partial class AssistantBatchProcessing
catch (Exception e)
{
this.Logger.LogWarning(e, "Was not able to read the results table of the previous batch run at '{ResultsFilePath}'.", resultsFilePath);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Warning, T("Was not able to read the results table of the previous run. Its completed documents cannot be restored and will be processed again.")));
await this.MessageBus.SendWarning(new(AppIcons.WARNING, T("Was not able to read the results table of the previous run. Its completed documents cannot be restored and will be processed again.")));
}
return results;
@@ -109,7 +109,7 @@ public partial class AssistantBatchProcessing
? T("The selected model cannot read images, so the image among the selected files will fail. All other files are processed as usual.")
: string.Format(T("The selected model cannot read images, so the {0} images among the selected files will fail. All other files are processed as usual."), numImages);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.ImageNotSupported, warning));
await this.MessageBus.SendWarning(new(AppIcons.IMAGE_NOT_SUPPORTED, warning));
}
/// <summary>
@@ -198,7 +198,7 @@ public partial class AssistantBatchProcessing
var failureMessage = failedFiles == 1
? T("The batch run finished, but one file could not be processed. See the progress table and log for details.")
: string.Format(T("The batch run finished, but {0} files could not be processed. See the progress table and log for details."), failedFiles);
await this.MessageBus.SendError(new(Icons.Material.Filled.Error, failureMessage));
await this.MessageBus.SendError(new(AppIcons.ERROR, failureMessage));
}
}
}
@@ -10,16 +10,16 @@
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-3 mr-3" StretchItems="StretchItems.Start">
<MudText Typo="Typo.h3">@T("BeyondFacts Lab")</MudText>
<MudSpacer/>
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" OnClick="@this.OpenSettingsDialogAsync"/>
<MudIconButton Variant="Variant.Text" Icon="@AppIcons.SETTINGS" OnClick="@this.OpenSettingsDialogAsync"/>
</MudStack>
<InnerScrolling>
@* How to work with the lab opens by itself while there is no preparation yet. *@
<MudExpansionPanels MultiExpansion="@true" Class="mb-6 mr-3">
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.School" HeaderText="@T("Working with the lab")" IsExpanded="@this.introductionExpanded" ExpandedChanged="@this.IntroductionExpandedChanged">
<ExpansionPanel HeaderIcon="@AppIcons.INTRODUCTION" HeaderText="@T("Working with the lab")" IsExpanded="@this.introductionExpanded" ExpandedChanged="@this.IntroductionExpandedChanged">
<BflIntroduction/>
</ExpansionPanel>
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.HelpOutline" HeaderText="@T("Is the lab right for my task?")">
<ExpansionPanel HeaderIcon="@AppIcons.HELP" HeaderText="@T("Is the lab right for my task?")">
<BflOnboarding/>
</ExpansionPanel>
</MudExpansionPanels>
@@ -56,7 +56,7 @@
</MudList>
}
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add" OnClick="@this.CreateProjectAsync" Disabled="@this.isBusy" Class="mt-1">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.ADD" OnClick="@this.CreateProjectAsync" Disabled="@this.isBusy" Class="mt-1">
@T("New preparation")
</MudButton>
@@ -76,7 +76,7 @@
<MudCopyClipboardButton TooltipMessage="@T("Copy preparation ID")" StringContent="@unavailableProject.ProjectId.ToString("D")"/>
</MudStack>
<MudStack Row="true" Spacing="1" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.DeleteForever" Color="Color.Error" OnClick="@this.DeleteProjectAsync" Disabled="@this.isBusy">@T("Delete")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.DELETE" Color="Color.Error" OnClick="@this.DeleteProjectAsync" Disabled="@this.isBusy">@T("Delete")</MudButton>
</MudStack>
</MudStack>
</MudPaper>
@@ -102,8 +102,8 @@
<MudSwitch T="bool" Value="@(project.HappenedAtUtc is not null)" ValueChanged="@this.SetHappenedAsync" Disabled="@this.isBusy" Color="Color.Primary" Class="mr-2">
@T("The event has taken place")
</MudSwitch>
<MudButton StartIcon="@Icons.Material.Filled.DriveFileRenameOutline" OnClick="@this.RenameProjectAsync" Disabled="@this.isBusy">@T("Rename")</MudButton>
<MudButton StartIcon="@Icons.Material.Filled.DeleteForever" Color="Color.Error" OnClick="@this.DeleteProjectAsync" Disabled="@this.isBusy">@T("Delete")</MudButton>
<MudButton StartIcon="@AppIcons.RENAME" OnClick="@this.RenameProjectAsync" Disabled="@this.isBusy">@T("Rename")</MudButton>
<MudButton StartIcon="@AppIcons.DELETE" Color="Color.Error" OnClick="@this.DeleteProjectAsync" Disabled="@this.isBusy">@T("Delete")</MudButton>
</MudStack>
</MudStack>
@@ -207,7 +207,7 @@ public partial class BeyondFactsLabAssistant
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException or ArgumentException)
{
this.Logger.LogError(exception, "A change of the preparations of the BeyondFacts Lab failed.");
await this.MessageBus.SendError(new(Icons.Material.Filled.RecordVoiceOver, TA("AI Studio could not save the change of your preparations. Please try again.")));
await this.MessageBus.SendError(new(AppIcons.ASSISTANT_BEYOND_FACTS_LAB, TA("AI Studio could not save the change of your preparations. Please try again.")));
await this.ReloadAfterFailureAsync();
}
finally
@@ -237,9 +237,9 @@ public partial class BeyondFactsLabAssistant
/// <param name="project">The preparation.</param>
private static string ProjectIcon(BflProjectEntry project) => project switch
{
{ IsAvailable: false } => Icons.Material.Filled.WarningAmber,
{ Project.HappenedAtUtc: not null } => Icons.Material.Filled.EventAvailable,
_ => Icons.Material.Filled.Event,
{ IsAvailable: false } => AppIcons.WARNING,
{ Project.HappenedAtUtc: not null } => AppIcons.EVENT_TOOK_PLACE,
_ => AppIcons.EVENT,
};
/// <summary>
@@ -72,19 +72,19 @@ public partial class BeyondFactsLabAssistant
if (BflEventVisibility.IsNotPublic(this.forms))
{
await this.MessageBus.SendInfo(new(Icons.Material.Filled.PublicOff, BflEventVisibility.NotPublicMessage));
await this.MessageBus.SendInfo(new(AppIcons.NOT_PUBLIC, BflEventVisibility.NotPublicMessage));
return;
}
if (BflEventVisibility.IsSuggestionPending(this.workStates, this.forms))
{
await this.MessageBus.SendInfo(new(Icons.Material.Filled.TravelExplore, string.Format(TA("The lab has not started the research on the web yet. First, decide on the suggestion below the work state whether the event is public. Afterward, you can start the research in the step '{0}'."), BflStep.STRATEGY.Title)));
await this.MessageBus.SendInfo(new(AppIcons.WEB_RESEARCH, string.Format(TA("The lab has not started the research on the web yet. First, decide on the suggestion below the work state whether the event is public. Afterward, you can start the research in the step '{0}'."), BflStep.STRATEGY.Title)));
return;
}
var started = await this.ResearchRunner.StartWhenDueAsync(project.ProjectId, this.providerSettings, this.forms);
if (started.Count > 0)
await this.MessageBus.SendInfo(new(Icons.Material.Filled.TravelExplore, string.Format(TA("The lab now researches the event on the web, with the public details about it only. You find the result in the step '{0}'."), BflStep.STRATEGY.Title)));
await this.MessageBus.SendInfo(new(AppIcons.WEB_RESEARCH, string.Format(TA("The lab now researches the event on the web, with the public details about it only. You find the result in the step '{0}'."), BflStep.STRATEGY.Title)));
}
/// <summary>
@@ -156,7 +156,7 @@ public partial class BeyondFactsLabAssistant
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException)
{
this.Logger.LogError(exception, "Could not save the details of a step in the BeyondFacts Lab.");
await this.MessageBus.SendError(new(Icons.Material.Filled.RecordVoiceOver, TA("AI Studio could not save your details. Please try again.")));
await this.MessageBus.SendError(new(AppIcons.ASSISTANT_BEYOND_FACTS_LAB, TA("AI Studio could not save your details. Please try again.")));
}
}
@@ -14,7 +14,7 @@ else if (this.conversation.Thread is not { } thread)
<MudAlert Severity="Severity.Error" Variant="Variant.Outlined" Class="mb-3">
@TA("AI Studio cannot open this conversation. Its file may be damaged, or a newer version of AI Studio stored it. You can start the conversation over, which deletes it.")
</MudAlert>
<MudButton StartIcon="@Icons.Material.Filled.RestartAlt" Color="Color.Error" OnClick="@this.ResetAsync">@T("Start over")</MudButton>
<MudButton StartIcon="@AppIcons.RESET" Color="Color.Error" OnClick="@this.ResetAsync">@T("Start over")</MudButton>
}
else
{
@@ -22,7 +22,7 @@ else
{
<MudText Typo="Typo.body2" Class="mb-3">@this.Introduction</MudText>
<div class="mb-4">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Forum" OnClick="@this.StartAsync" Disabled="@(!this.CanSend)">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.CHAT" OnClick="@this.StartAsync" Disabled="@(!this.CanSend)">
@T("Start the conversation")
</MudButton>
</div>
@@ -53,7 +53,7 @@ else
Variant="Variant.Outlined"
Label="@TA("Your message")"
Adornment="Adornment.End"
AdornmentIcon="@Icons.Material.Filled.Send"
AdornmentIcon="@AppIcons.SEND"
AdornmentColor="@(this.CanSendMessage ? Color.Primary : Color.Default)"
AdornmentAriaLabel="@T("Send")"
OnAdornmentClick="@this.SendAsync"
@@ -68,11 +68,11 @@ else
<MudStack Row="true" Spacing="1" Class="mt-2">
@if (this.IsRunning)
{
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Stop" OnClick="@this.CancelAsync">@T("Stop")</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@AppIcons.STOP" OnClick="@this.CancelAsync">@T("Stop")</MudButton>
}
@if (this.conversation.HasVisibleMessages)
{
<MudButton StartIcon="@Icons.Material.Filled.RestartAlt" OnClick="@this.ResetAsync" Disabled="@this.IsRunning">@T("Start over")</MudButton>
<MudButton StartIcon="@AppIcons.RESET" OnClick="@this.ResetAsync" Disabled="@this.IsRunning">@T("Start over")</MudButton>
}
</MudStack>
}
@@ -341,7 +341,7 @@ public partial class BflChat : MSGComponentBase
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException)
{
this.Logger.LogError(exception, "Could not delete the chat '{Location}' of the BeyondFacts Lab.", this.Location.Key);
await this.MessageBus.SendError(new(Icons.Material.Filled.DeleteForever, TA("AI Studio could not delete this conversation. Please try again.")));
await this.MessageBus.SendError(new(AppIcons.DELETE, TA("AI Studio could not delete this conversation. Please try again.")));
}
}
}
@@ -15,7 +15,7 @@
var confirmed = this.WorkStates[step].Confirmed!;
var isOutdated = BflStaleness.Of(step, this.WorkStates, this.Forms) is BflWorkStateStatus.OUTDATED;
<ExpansionPanel @key="step"
HeaderIcon="@(isOutdated ? Icons.Material.Filled.Update : Icons.Material.Filled.CheckCircle)"
HeaderIcon="@(isOutdated ? AppIcons.OUTDATED : AppIcons.SUCCESS)"
IconColor="@(isOutdated ? Color.Warning : Color.Success)"
HeaderText="@(isOutdated ? string.Format(T("{0} (outdated)"), step.Title) : step.Title)">
@foreach (var section in BflWorkStateSections.ForStep(step).Where(section => !string.IsNullOrWhiteSpace(confirmed.Sections.GetValueOrDefault(section.Key))))
@@ -155,13 +155,13 @@ public sealed class BflConversationService(BeyondFactsLabStore store, SettingsMa
catch (BflPromptOverrideException exception)
{
logger.LogWarning(exception, "A prompt override of the BeyondFacts Lab has a placeholder which the lab does not fill.");
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."),exception.FileName, exception.Placeholder)));
await messageBus.SendError(new(AppIcons.ERROR, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."),exception.FileName, exception.Placeholder)));
return;
}
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or FormatException)
{
logger.LogError(exception, "The BeyondFacts Lab could not put together the system prompt of the chat '{Location}'.", location.Key);
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, TA("The BeyondFacts Lab could not put together its instructions for the model. Please report this as a bug.")));
await messageBus.SendError(new(AppIcons.ERROR, TA("The BeyondFacts Lab could not put together its instructions for the model. Please report this as a bug.")));
return;
}
@@ -231,12 +231,12 @@ public sealed class BflConversationService(BeyondFactsLabStore store, SettingsMa
catch (ProviderRequestException exception)
{
logger.LogError(exception, "The provider request of the BeyondFacts Lab failed. Status={StatusCode}, Reason='{ReasonPhrase}'.", exception.StatusCode, exception.ReasonPhrase);
await messageBus.SendError(new(Icons.Material.Filled.CloudOff, exception.UserMessage));
await messageBus.SendError(new(AppIcons.PROVIDER_ERROR, exception.UserMessage));
}
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException)
{
logger.LogError(exception, "The BeyondFacts Lab could not store the chat '{Location}'.", location.Key);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not save this conversation. Please try again.")));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not save this conversation. Please try again.")));
}
finally
{
@@ -532,7 +532,7 @@ public sealed class BflConversationService(BeyondFactsLabStore store, SettingsMa
if (reason is null)
return true;
await messageBus.SendError(new(Icons.Material.Filled.CloudOff, reason));
await messageBus.SendError(new(AppIcons.PROVIDER_ERROR, reason));
return false;
}
@@ -563,7 +563,7 @@ public sealed class BflConversationService(BeyondFactsLabStore store, SettingsMa
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException)
{
logger.LogError(exception, "The BeyondFacts Lab could not store the chat '{Location}'.", conversation.Location.Key);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not save this conversation. Please try again.")));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not save this conversation. Please try again.")));
}
}
@@ -8,7 +8,7 @@
@T("The knowledge base of the lab is a guide on science in public debates by Lara Wüster from the Technical University of Munich (TUM).")
</MudJustifiedText>
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Icon="@Icons.Material.Filled.Schedule" Class="mb-4">
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Icon="@AppIcons.TIME" Class="mb-4">
<MudJustifiedText Typo="Typo.body1">
@TA("Plan about 30 to 60 minutes for a preparation. You can pause at any time: AI Studio saves your details and conversations, and you continue where you left off.")
</MudJustifiedText>
@@ -22,25 +22,25 @@
@* Laid out like MudTextList, whose items have a header of their own: justified and hyphenated, with the icon at the first line. *@
<MudText Typo="Typo.h6">@T("How to proceed")</MudText>
<MudList T="string" ReadOnly="@true" Dense="@true" Class="mud-text-list mb-3">
<MudListItem T="string" Icon="@Icons.Material.Filled.LooksOne" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.STEP_1" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("Create a preparation for your event with 'New preparation'.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.LooksTwo" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.STEP_2" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("Work through the seven steps, in any order you like. Each step has the form 'Your details' and a conversation of its own.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Looks3" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.STEP_3" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("Fill in what you know. Fields may stay empty: the lab shows which key details are missing and asks for them in the conversation.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Looks4" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.STEP_4" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("Add material beside the steps, e.g., notes, a talk draft, a paper, the invitation, the recording of an interview, or a poster. It applies to all steps, and the lab asks you about it. Add only what you may process with the selected provider; recordings also go to the transcription provider of AI Studio.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Looks5" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.STEP_5" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("Let the lab start the conversation of a step, or write first and say what support you want, e.g., with your role, your strategy, or a round of critical questions. You can always say that you do not know.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Looks6" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.STEP_6" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("Once a step is largely clear, let the lab create its work state below the conversation. You check and edit it, and once you confirm it, the later steps build on it. The lab also suggests values for empty fields of 'Your details', which you take over one by one.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.TaskAlt" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.CHECKLIST_ITEM" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("In the last step, let the lab create your materials from your confirmed work states: a reflection folder, a position paper, a conversation guide, questions and answers, and your open points. You check, edit, and confirm each of them, and then export it as a document.")</MudJustifiedText>
</MudListItem>
</MudList>
@@ -50,7 +50,7 @@
@string.Format(Culture, TA("In the step '{0}', research agents of the lab look into the event, its participants, and the public debate on its topic, one agent for each. They start on their own once you confirm the event details, provided the web search is set up in AI Studio, and you can start them again at any time."), BflStep.STRATEGY.Title)
@TA("If you state in the event details that the event is not public, the lab never researches it on the web.")
</MudJustifiedText>
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Icon="@Icons.Material.Filled.Shield" Class="mb-4">
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Icon="@AppIcons.PRIVACY" Class="mb-4">
<MudJustifiedText Typo="Typo.body1">
@TA("The research agents receive only the public details about the event, which the form marks with a symbol. Your other details, your material, your work states, and your conversations stay in your preparation and never reach a search. The conversations of the steps never search the web themselves: they only read web pages whose addresses stand in them, e.g., the link to the event.")
</MudJustifiedText>
@@ -58,22 +58,22 @@
<MudText Typo="Typo.h6">@T("How to recognize good results")</MudText>
<MudList T="string" ReadOnly="@true" Dense="@true" Class="mud-text-list mb-3">
<MudListItem T="string" Icon="@Icons.Material.Filled.TaskAlt" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.CHECKLIST_ITEM" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("The answers refer to your event and your details.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.TaskAlt" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.CHECKLIST_ITEM" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("You can tell evidence, interpretation, assumptions about values, and recommendations apart.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.TaskAlt" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.CHECKLIST_ITEM" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("Uncertainties and the limits of your expertise stay visible.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.TaskAlt" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.CHECKLIST_ITEM" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@T("Counterarguments are presented fairly.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.TaskAlt" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.CHECKLIST_ITEM" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("The strategy fits your real speaking time and focuses on a few key messages.")</MudJustifiedText>
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.TaskAlt" Style="@LIST_ITEM_STYLE">
<MudListItem T="string" Icon="@AppIcons.CHECKLIST_ITEM" Style="@LIST_ITEM_STYLE">
<MudJustifiedText Typo="Typo.body1">@TA("You keep the decision about which position you take.")</MudJustifiedText>
</MudListItem>
</MudList>
@@ -128,7 +128,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException)
{
logger.LogError(exception, "Could not list the material of the preparation '{ProjectId}' of the BeyondFacts Lab.", projectId);
await messageBus.SendError(new(Icons.Material.Filled.Description, TA("AI Studio could not read the material of this preparation. Please try again.")));
await messageBus.SendError(new(AppIcons.DOCUMENT, TA("AI Studio could not read the material of this preparation. Please try again.")));
return;
}
@@ -182,7 +182,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException)
{
logger.LogError(exception, "Could not delete the material '{MaterialId}' of the preparation '{ProjectId}' of the BeyondFacts Lab.", materialId, projectId);
await messageBus.SendError(new(Icons.Material.Filled.DeleteForever, TA("AI Studio could not delete the material. Please try again.")));
await messageBus.SendError(new(AppIcons.DELETE, TA("AI Studio could not delete the material. Please try again.")));
return false;
}
@@ -233,14 +233,14 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException)
{
logger.LogWarning(exception, "The BeyondFacts Lab could not open the file '{Path}'.", path);
await messageBus.SendError(new(Icons.Material.Filled.Description, string.Format(TB("AI Studio could not open the file '{0}'."), name)));
await messageBus.SendError(new(AppIcons.DOCUMENT, string.Format(TB("AI Studio could not open the file '{0}'."), name)));
return;
}
// Before anything is read, and above all before a recording is paid for:
if (!knownHashes.Add(hash))
{
await messageBus.SendInfo(new(Icons.Material.Filled.Description, string.Format(TB("The material of this preparation contains '{0}' already."), name)));
await messageBus.SendInfo(new(AppIcons.DOCUMENT, string.Format(TB("The material of this preparation contains '{0}' already."), name)));
return;
}
@@ -279,9 +279,9 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
{
var addition = await store.AddMaterialAsync(projectId, material, extraction.Content);
if (addition.IsDuplicate)
await messageBus.SendInfo(new(Icons.Material.Filled.Description, string.Format(TB("The material of this preparation contains '{0}' already."), addition.Material.Name)));
await messageBus.SendInfo(new(AppIcons.DOCUMENT, string.Format(TB("The material of this preparation contains '{0}' already."), addition.Material.Name)));
else if (addition.Material.IsShortened)
await messageBus.SendInfo(new(Icons.Material.Filled.ContentCut, string.Format(TB("The lab keeps only the beginning of '{0}': a conversation never takes more of one material."), addition.Material.Name)));
await messageBus.SendInfo(new(AppIcons.CONTENT_SHORTENED, string.Format(TB("The lab keeps only the beginning of '{0}': a conversation never takes more of one material."), addition.Material.Name)));
}
catch (FileNotFoundException)
{
@@ -292,7 +292,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
{
knownHashes.Remove(hash);
logger.LogError(exception, "The BeyondFacts Lab could not store the material '{Name}' of the preparation '{ProjectId}'.", name, projectId);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, string.Format(TA("AI Studio could not save the material '{0}'. Please try again."), name)));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, string.Format(TA("AI Studio could not save the material '{0}'. Please try again."), name)));
}
}
@@ -317,7 +317,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
if (!prepared.IsPrepared)
{
logger.LogWarning("The BeyondFacts Lab could not prepare the image '{Path}': {ErrorCode}.", path, prepared.ErrorCode);
await messageBus.SendError(new(Icons.Material.Filled.Image, prepared.ErrorCode.ToUserMessage(name)));
await messageBus.SendError(new(AppIcons.IMAGE, prepared.ErrorCode.ToUserMessage(name)));
return false;
}
@@ -339,7 +339,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
{
var addition = await store.AddImageMaterialAsync(projectId, material, Convert.FromBase64String(prepared.Base64));
if (addition.IsDuplicate)
await messageBus.SendInfo(new(Icons.Material.Filled.Image, string.Format(TB("The material of this preparation contains '{0}' already."), addition.Material.Name)));
await messageBus.SendInfo(new(AppIcons.IMAGE, string.Format(TB("The material of this preparation contains '{0}' already."), addition.Material.Name)));
return true;
}
@@ -351,7 +351,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException or FormatException or ArgumentException)
{
logger.LogError(exception, "The BeyondFacts Lab could not store the image '{Name}' of the preparation '{ProjectId}'.", name, projectId);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, string.Format(TA("AI Studio could not save the material '{0}'. Please try again."), name)));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, string.Format(TA("AI Studio could not save the material '{0}'. Please try again."), name)));
return false;
}
}
@@ -372,7 +372,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
{
if (this.UsableTranscriptionProvider() is not { } provider)
{
await messageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, this.NoTranscriptionProviderMessage));
await messageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, this.NoTranscriptionProviderMessage));
return FileExtractionResult.Failed(FileExtractionErrorCode.INVALID_REQUEST, "No transcription provider may hear the recordings of the BeyondFacts Lab.");
}
@@ -386,7 +386,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
if (transcript.Status is not PersistentMediaTranscriptStatus.READY)
{
logger.LogWarning("The BeyondFacts Lab could not transcribe the recording '{Path}': {Status}.", path, transcript.Status);
await messageBus.SendError(new(Icons.Material.Filled.VoiceChat, string.Format(TB("AI Studio could not transcribe the recording '{0}': {1}"), name, transcript.UserMessage)));
await messageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, string.Format(TB("AI Studio could not transcribe the recording '{0}': {1}"), name, transcript.UserMessage)));
return FileExtractionResult.Failed(FileExtractionErrorCode.INTERNAL, transcript.UserMessage);
}
@@ -394,7 +394,7 @@ public sealed class BflMaterialService(BeyondFactsLabStore store, RustService ru
if (!extraction.HasUsableContent)
{
logger.LogError("The BeyondFacts Lab could not read the transcript of the recording '{Path}': code={ErrorCode}, message='{ErrorMessage}'.", path, extraction.ErrorCode, extraction.ErrorMessage);
await messageBus.SendError(new(Icons.Material.Filled.VoiceChat, extraction.ToUserMessage(name)));
await messageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, extraction.ToUserMessage(name)));
}
return extraction;
@@ -68,7 +68,7 @@
}
</MudStack>
<MudTooltip Text="@T("Remove material")">
<MudIconButton Icon="@Icons.Material.Filled.Delete" Size="Size.Small" OnClick="@(() => this.DeleteAsync(entry))"/>
<MudIconButton Icon="@AppIcons.DELETE" Size="Size.Small" OnClick="@(() => this.DeleteAsync(entry))"/>
</MudTooltip>
</MudStack>
}
@@ -258,7 +258,7 @@ public partial class BflMaterials : MSGComponentBase
{
if (this.MaterialService.UsableTranscriptionProvider() is not { } provider)
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, this.MaterialService.NoTranscriptionProviderMessage));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, this.MaterialService.NoTranscriptionProviderMessage));
return;
}
@@ -291,10 +291,10 @@ public partial class BflMaterials : MSGComponentBase
/// <param name="entry">The material.</param>
private static string Icon(BflMaterialEntry entry) => entry.Material?.Kind switch
{
null => Icons.Material.Filled.ErrorOutline,
BflMaterialKind.RECORDING => Icons.Material.Filled.Mic,
BflMaterialKind.IMAGE => Icons.Material.Filled.Image,
_ => Icons.Material.Filled.Description,
null => AppIcons.FILE_NOT_FOUND,
BflMaterialKind.RECORDING => AppIcons.MICROPHONE,
BflMaterialKind.IMAGE => AppIcons.IMAGE,
_ => AppIcons.DOCUMENT,
};
/// <summary>
@@ -6,14 +6,14 @@
@if (this.IsNotPublic)
{
@* An event which is not public is never researched, and earlier research no longer counts: *@
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Dense="true" Icon="@Icons.Material.Filled.PublicOff" Class="mb-3">
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Dense="true" Icon="@AppIcons.NOT_PUBLIC" Class="mb-3">
@string.Format(Culture, TA("The event is not public. Therefore, the lab does not research it on the web, and none of your details reach a search. If the event is public after all, change this in the step '{0}'."), BflStep.FRAMEWORK.Title)
</MudAlert>
}
else
{
@* What the research receives, and what it never receives: *@
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Dense="true" Icon="@Icons.Material.Filled.Shield" Class="mb-3">
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Dense="true" Icon="@AppIcons.PRIVACY" Class="mb-3">
<MudText Typo="Typo.body2">@TA("The research agents receive only the public details about the event. Your other details, your material, your work states, and your conversations stay in your preparation and never reach a search.")</MudText>
@if (this.PublicDetails.Count > 0)
{
@@ -42,7 +42,7 @@ else
<MudButton Variant="@(this.research.Count > 0 ? Variant.Outlined : Variant.Filled)"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.TravelExplore"
StartIcon="@AppIcons.WEB_RESEARCH"
OnClick="@this.StartAllAsync"
Disabled="@(!this.CanStart)"
Class="mb-3">
@@ -68,7 +68,7 @@ else
}
<MudText Typo="Typo.h6">@topic.Title</MudText>
<MudTooltip Text="@topic.Description" Placement="Placement.Top">
<MudIcon Icon="@Icons.Material.Outlined.Info" Size="Size.Small" Color="Color.Info" Class="ml-2"/>
<MudIcon Icon="@AppIcons.INFO" Size="Size.Small" Color="Color.Info" Class="ml-2"/>
</MudTooltip>
<MudSpacer/>
<MudText Typo="Typo.caption" Class="mr-2">@this.StatusText(found, isRunning)</MudText>
@@ -80,7 +80,7 @@ else
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="mb-1"/>
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2" Class="mb-3">
<MudText Typo="Typo.caption">@T("The agent researches this topic")</MudText>
<MudButton Size="Size.Small" StartIcon="@Icons.Material.Filled.Stop" OnClick="@(() => this.CancelAsync(topic))">@T("Stop")</MudButton>
<MudButton Size="Size.Small" StartIcon="@AppIcons.STOP" OnClick="@(() => this.CancelAsync(topic))">@T("Stop")</MudButton>
</MudStack>
}
@@ -135,7 +135,7 @@ else
<MudButton Size="Size.Small"
Variant="Variant.Outlined"
StartIcon="@Icons.Material.Filled.Refresh"
StartIcon="@AppIcons.WEB"
OnClick="@(() => this.StartAsync(topic))"
Disabled="@(!this.CanStart)">
@(found is null ? T("Research this topic") : T("Research this topic again"))
@@ -151,9 +151,9 @@ public partial class BflResearchPanel : MSGComponentBase
private string StatusIcon(BflResearch? found) => found switch
{
null => Icons.Material.Outlined.Circle,
_ when found.IsOutdated(this.PublicDetails) => Icons.Material.Filled.Update,
_ => Icons.Material.Filled.CheckCircle,
null => AppIcons.NOT_STARTED,
_ when found.IsOutdated(this.PublicDetails) => AppIcons.OUTDATED,
_ => AppIcons.SUCCESS,
};
private Color StatusColor(BflResearch? found) => found switch
@@ -138,7 +138,7 @@ public sealed class BflResearchRunner(BeyondFactsLabStore store, BflConversation
var availability = await this.CheckAvailabilityAsync(provider);
if (!availability.CanResearch)
{
await messageBus.SendError(new(Icons.Material.Filled.TravelExplore, availability.Message));
await messageBus.SendError(new(AppIcons.WEB_RESEARCH, availability.Message));
return;
}
@@ -157,14 +157,14 @@ public sealed class BflResearchRunner(BeyondFactsLabStore store, BflConversation
var forms = await store.LoadFormsAsync(location.ProjectId);
if (BflEventVisibility.IsNotPublic(forms))
{
await messageBus.SendError(new(Icons.Material.Filled.PublicOff, BflEventVisibility.NotPublicMessage));
await messageBus.SendError(new(AppIcons.NOT_PUBLIC, BflEventVisibility.NotPublicMessage));
return;
}
var details = BflPromptComposer.PublicDetailsOf(forms);
if (details.Count is 0)
{
await messageBus.SendError(new(Icons.Material.Filled.TravelExplore, string.Format(TA("Please enter public details about the event first, in the step '{0}', such as its topic or its link. The research receives these details only."), BflStep.FRAMEWORK.Title)));
await messageBus.SendError(new(AppIcons.WEB_RESEARCH, string.Format(TA("Please enter public details about the event first, in the step '{0}', such as its topic or its link. The research receives these details only."), BflStep.FRAMEWORK.Title)));
return;
}
@@ -187,7 +187,7 @@ public sealed class BflResearchRunner(BeyondFactsLabStore store, BflConversation
if (research.Text.Length is 0)
{
logger.LogWarning("The agent wrote no text for the research '{Location}' of the BeyondFacts Lab.", location.Key);
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, TA("The research ended without a result. Please try again, or try another provider.")));
await messageBus.SendError(new(AppIcons.ERROR, TA("The research ended without a result. Please try again, or try another provider.")));
return;
}
@@ -201,12 +201,12 @@ public sealed class BflResearchRunner(BeyondFactsLabStore store, BflConversation
catch (BflPromptOverrideException exception)
{
logger.LogWarning(exception, "A prompt override of the BeyondFacts Lab has a placeholder which the lab does not fill.");
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."), exception.FileName, exception.Placeholder)));
await messageBus.SendError(new(AppIcons.ERROR, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."), exception.FileName, exception.Placeholder)));
}
catch (ProviderRequestException exception)
{
logger.LogError(exception, "The provider request for a research of the BeyondFacts Lab failed. Status={StatusCode}, Reason='{ReasonPhrase}'.", exception.StatusCode, exception.ReasonPhrase);
await messageBus.SendError(new(Icons.Material.Filled.CloudOff, exception.UserMessage));
await messageBus.SendError(new(AppIcons.PROVIDER_ERROR, exception.UserMessage));
}
catch (FileNotFoundException)
{
@@ -215,7 +215,7 @@ public sealed class BflResearchRunner(BeyondFactsLabStore store, BflConversation
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException or FormatException)
{
logger.LogError(exception, "The BeyondFacts Lab could not do the research '{Location}'.", location.Key);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not finish this research. Please try again.")));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not finish this research. Please try again.")));
}
finally
{
@@ -104,7 +104,7 @@ public sealed class BflResultGenerator(BeyondFactsLabStore store, BflConversatio
if (text.Length is 0)
{
logger.LogWarning("The model wrote no text for the result '{Location}' of the BeyondFacts Lab.", location.Key);
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, TA("The model did not write this material. Please try again, or try another provider.")));
await messageBus.SendError(new(AppIcons.ERROR, TA("The model did not write this material. Please try again, or try another provider.")));
return;
}
@@ -118,12 +118,12 @@ public sealed class BflResultGenerator(BeyondFactsLabStore store, BflConversatio
catch (BflPromptOverrideException exception)
{
logger.LogWarning(exception, "A prompt override of the BeyondFacts Lab has a placeholder which the lab does not fill.");
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."), exception.FileName, exception.Placeholder)));
await messageBus.SendError(new(AppIcons.ERROR, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."), exception.FileName, exception.Placeholder)));
}
catch (ProviderRequestException exception)
{
logger.LogError(exception, "The provider request for a result of the BeyondFacts Lab failed. Status={StatusCode}, Reason='{ReasonPhrase}'.", exception.StatusCode, exception.ReasonPhrase);
await messageBus.SendError(new(Icons.Material.Filled.CloudOff, exception.UserMessage));
await messageBus.SendError(new(AppIcons.PROVIDER_ERROR, exception.UserMessage));
}
catch (FileNotFoundException)
{
@@ -132,7 +132,7 @@ public sealed class BflResultGenerator(BeyondFactsLabStore store, BflConversatio
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException or FormatException)
{
logger.LogError(exception, "The BeyondFacts Lab could not write the result '{Location}'.", location.Key);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not create this material. Please try again.")));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not create this material. Please try again.")));
}
finally
{
@@ -187,7 +187,7 @@ public sealed class BflResultGenerator(BeyondFactsLabStore store, BflConversatio
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException)
{
logger.LogError(exception, "The BeyondFacts Lab could not put the reflection folder of '{ProjectId}' together.", projectId);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not create this material. Please try again.")));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not create this material. Please try again.")));
}
finally
{
@@ -12,7 +12,7 @@
<MudButton Variant="@(this.AnyCreated ? Variant.Outlined : Variant.Filled)"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.AutoAwesome"
StartIcon="@AppIcons.GENERATE"
OnClick="@this.CreateAllAsync"
Disabled="@(!this.CanCreateAll)"
Class="mb-3">
@@ -30,7 +30,7 @@
<MudIcon Icon="@StatusIcon(status)" Color="@StatusColor(status)" Class="mr-3"/>
<MudText Typo="Typo.h6">@kind.Title</MudText>
<MudTooltip Text="@kind.Description" Placement="Placement.Top">
<MudIcon Icon="@Icons.Material.Outlined.Info" Size="Size.Small" Color="Color.Info" Class="ml-2"/>
<MudIcon Icon="@AppIcons.INFO" Size="Size.Small" Color="Color.Info" Class="ml-2"/>
</MudTooltip>
<MudSpacer/>
<MudText Typo="Typo.caption" Class="mr-2">@this.StatusText(status)</MudText>
@@ -50,7 +50,7 @@
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="mb-1"/>
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2" Class="mb-3">
<MudText Typo="Typo.caption">@T("The lab writes this material")</MudText>
<MudButton Size="Size.Small" StartIcon="@Icons.Material.Filled.Stop" OnClick="@(() => this.CancelAsync(kind))">@T("Stop")</MudButton>
<MudButton Size="Size.Small" StartIcon="@AppIcons.STOP" OnClick="@(() => this.CancelAsync(kind))">@T("Stop")</MudButton>
</MudStack>
}
@@ -85,16 +85,16 @@
}
<MudStack Row="true" Spacing="1" Wrap="Wrap.Wrap" Class="mt-3">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.CheckCircle" OnClick="@(() => this.ConfirmAsync(kind))" Disabled="@this.IsBusy(kind)">@T("Confirm")</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.CONFIRM" OnClick="@(() => this.ConfirmAsync(kind))" Disabled="@this.IsBusy(kind)">@T("Confirm")</MudButton>
@if (this.editing.Contains(kind))
{
<MudButton StartIcon="@Icons.Material.Filled.Preview" OnClick="@(() => this.ShowPreview(kind))" Disabled="@this.IsBusy(kind)">@T("Show preview")</MudButton>
<MudButton StartIcon="@AppIcons.PREVIEW" OnClick="@(() => this.ShowPreview(kind))" Disabled="@this.IsBusy(kind)">@T("Show preview")</MudButton>
}
else
{
<MudButton StartIcon="@Icons.Material.Filled.Edit" OnClick="@(() => this.StartEditing(kind))" Disabled="@this.IsBusy(kind)">@T("Edit")</MudButton>
<MudButton StartIcon="@AppIcons.EDIT" OnClick="@(() => this.StartEditing(kind))" Disabled="@this.IsBusy(kind)">@T("Edit")</MudButton>
}
<MudButton StartIcon="@Icons.Material.Filled.Delete" OnClick="@(() => this.DiscardDraftAsync(kind))" Disabled="@this.IsBusy(kind)">@T("Discard draft")</MudButton>
<MudButton StartIcon="@AppIcons.DELETE" OnClick="@(() => this.DiscardDraftAsync(kind))" Disabled="@this.IsBusy(kind)">@T("Discard draft")</MudButton>
</MudStack>
</div>
}
@@ -117,8 +117,8 @@
<MudStack Row="true" Spacing="1" Wrap="Wrap.Wrap" Class="mb-3">
<MudMenu Label="@T("Export")"
StartIcon="@Icons.Material.Filled.Save"
EndIcon="@Icons.Material.Filled.KeyboardArrowDown"
StartIcon="@AppIcons.EXPORT"
EndIcon="@AppIcons.DROPDOWN_MENU"
Variant="Variant.Filled"
Color="Color.Primary"
MaxHeight="@MenuDefaults.MAX_HEIGHT"
@@ -133,7 +133,7 @@
<MudMenuItem @key="format" OnClick="@(() => this.ExportAsync(kind, confirmed, format))" Icon="@format.Icon" Label="@format.Name"/>
}
</MudMenu>
<MudButton StartIcon="@Icons.Material.Filled.Edit" OnClick="@(() => this.EditAsync(kind))" Disabled="@this.IsBusy(kind)">@T("Edit")</MudButton>
<MudButton StartIcon="@AppIcons.EDIT" OnClick="@(() => this.EditAsync(kind))" Disabled="@this.IsBusy(kind)">@T("Edit")</MudButton>
</MudStack>
}
@@ -147,7 +147,7 @@
<MudButton Variant="@(result.Draft is null && result.Confirmed is null ? Variant.Filled : Variant.Outlined)"
Color="Color.Primary"
StartIcon="@(kind.IsWrittenByModel ? Icons.Material.Filled.AutoAwesome : Icons.Material.Filled.FolderCopy)"
StartIcon="@(kind.IsWrittenByModel ? AppIcons.GENERATE : AppIcons.REFLECTION_FOLDER)"
OnClick="@(() => this.CreateAsync(kind))"
Disabled="@(this.IsBusy(kind) || kind.IsWrittenByModel && this.ProviderIssue is not null)">
@(result.Draft is null && result.Confirmed is null ? T("Create") : T("Create anew"))
@@ -188,12 +188,12 @@ public partial class BflResults : MSGComponentBase
private static string StatusIcon(BflResultStatus status) => status switch
{
BflResultStatus.UNREADABLE => Icons.Material.Filled.Error,
BflResultStatus.WRITING => Icons.Material.Filled.HourglassTop,
BflResultStatus.DRAFT => Icons.Material.Filled.EditNote,
BflResultStatus.CONFIRMED => Icons.Material.Filled.CheckCircle,
BflResultStatus.OUTDATED => Icons.Material.Filled.Update,
_ => Icons.Material.Filled.RadioButtonUnchecked
BflResultStatus.UNREADABLE => AppIcons.ERROR,
BflResultStatus.WRITING => AppIcons.PENDING,
BflResultStatus.DRAFT => AppIcons.DRAFT,
BflResultStatus.CONFIRMED => AppIcons.SUCCESS,
BflResultStatus.OUTDATED => AppIcons.OUTDATED,
_ => AppIcons.NOT_CREATED
};
private static Color StatusColor(BflResultStatus status) => status switch
@@ -384,7 +384,7 @@ public partial class BflResults : MSGComponentBase
catch (ArgumentOutOfRangeException exception)
{
this.Logger.LogError(exception, "Could not export a result of the BeyondFacts Lab, because no exporter writes the format {ExportFormat}.", format);
await this.MessageBus.SendError(new(Icons.Material.Filled.Error, TA("AI Studio could not export this material. Please try another format.")));
await this.MessageBus.SendError(new(AppIcons.ERROR, TA("AI Studio could not export this material. Please try another format.")));
}
finally
{
@@ -403,7 +403,7 @@ public partial class BflResults : MSGComponentBase
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException)
{
this.Logger.LogError(exception, "Could not save the result '{Kind}' of a preparation in the BeyondFacts Lab.", kind);
await this.MessageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not save this material. Please try again.")));
await this.MessageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not save this material. Please try again.")));
}
finally
{
@@ -16,7 +16,7 @@
@if (this.HasPublicDetails && this.IsEventNotPublic)
{
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Dense="true" Icon="@Icons.Material.Filled.PublicOff" Class="mb-3">
<MudAlert Severity="Severity.Info" Variant="Variant.Outlined" Dense="true" Icon="@AppIcons.NOT_PUBLIC" Class="mb-3">
@TA("The event is not public. Therefore, the lab does not research it on the web, and none of your details reach a search, not even those marked with a symbol.")
</MudAlert>
}
@@ -46,7 +46,7 @@ public partial class BflStepForm : MSGComponentBase
/// <summary>
/// The symbol which marks a field whose value the research of the lab receives.
/// </summary>
private const string PUBLIC_DETAIL_ICON = Icons.Material.Filled.TravelExplore;
private const string PUBLIC_DETAIL_ICON = AppIcons.WEB_RESEARCH;
/// <summary>
/// Gets whether the step has fields whose values the research receives, so that the form explains their symbol.
@@ -109,7 +109,7 @@ public sealed class BflWorkStateGenerator(BeyondFactsLabStore store, BflConversa
if (answer.Sections.Count is 0)
{
logger.LogWarning("The model wrote no readable work state of the BeyondFacts Lab: {Problems}", string.Join(" ", answer.Problems));
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, TA("The model did not write a work state the lab can read. Please try again, or try another provider.")));
await messageBus.SendError(new(AppIcons.ERROR, TA("The model did not write a work state the lab can read. Please try again, or try another provider.")));
return;
}
@@ -126,12 +126,12 @@ public sealed class BflWorkStateGenerator(BeyondFactsLabStore store, BflConversa
catch (BflPromptOverrideException exception)
{
logger.LogWarning(exception, "A prompt override of the BeyondFacts Lab has a placeholder which the lab does not fill.");
await messageBus.SendError(new(Icons.Material.Filled.ErrorOutline, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."), exception.FileName, exception.Placeholder)));
await messageBus.SendError(new(AppIcons.ERROR, string.Format(TA("The file '{0}' in the test folder of the BeyondFacts Lab contains the placeholder '{1}', which the lab does not fill in this file. Please correct the file and try again."), exception.FileName, exception.Placeholder)));
}
catch (ProviderRequestException exception)
{
logger.LogError(exception, "The provider request for a work state of the BeyondFacts Lab failed. Status={StatusCode}, Reason='{ReasonPhrase}'.", exception.StatusCode, exception.ReasonPhrase);
await messageBus.SendError(new(Icons.Material.Filled.CloudOff, exception.UserMessage));
await messageBus.SendError(new(AppIcons.PROVIDER_ERROR, exception.UserMessage));
}
catch (FileNotFoundException)
{
@@ -140,7 +140,7 @@ public sealed class BflWorkStateGenerator(BeyondFactsLabStore store, BflConversa
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException or FormatException)
{
logger.LogError(exception, "The BeyondFacts Lab could not write the work state of '{Location}'.", location.Key);
await messageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not create the work state. Please try again.")));
await messageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not create the work state. Please try again.")));
}
finally
{
@@ -37,7 +37,7 @@ else
<MudProgressLinear Color="Color.Primary" Indeterminate="true" Class="mb-1"/>
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2" Class="mb-3">
<MudText Typo="Typo.caption">@T("The lab writes the work state from the conversation")</MudText>
<MudButton Size="Size.Small" StartIcon="@Icons.Material.Filled.Stop" OnClick="@this.CancelAsync">@T("Stop")</MudButton>
<MudButton Size="Size.Small" StartIcon="@AppIcons.STOP" OnClick="@this.CancelAsync">@T("Stop")</MudButton>
</MudStack>
}
@@ -61,8 +61,8 @@ else
}
</MudStack>
<MudStack Row="true" Spacing="1" Wrap="Wrap.Wrap" Class="mt-3">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.CheckCircle" OnClick="@this.ConfirmDraftAsync" Disabled="@this.IsBusy">@T("Confirm")</MudButton>
<MudButton StartIcon="@Icons.Material.Filled.Delete" OnClick="@this.DiscardDraftAsync" Disabled="@this.IsBusy">@T("Discard draft")</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.CONFIRM" OnClick="@this.ConfirmDraftAsync" Disabled="@this.IsBusy">@T("Confirm")</MudButton>
<MudButton StartIcon="@AppIcons.DELETE" OnClick="@this.DiscardDraftAsync" Disabled="@this.IsBusy">@T("Discard draft")</MudButton>
</MudStack>
</div>
}
@@ -78,17 +78,17 @@ else
<MudStack Row="true" Spacing="1" Wrap="Wrap.Wrap" Class="mt-3">
@if (this.Status is BflWorkStateStatus.OUTDATED or BflWorkStateStatus.DETAILS_CHANGED)
{
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.CheckCircle" OnClick="@this.ConfirmAgainAsync" Disabled="@this.IsBusy">@T("Confirm again")</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.CONFIRM" OnClick="@this.ConfirmAgainAsync" Disabled="@this.IsBusy">@T("Confirm again")</MudButton>
}
<MudButton StartIcon="@Icons.Material.Filled.Edit" OnClick="@this.EditAsync" Disabled="@this.IsBusy">@T("Edit")</MudButton>
<MudButton StartIcon="@Icons.Material.Filled.Undo" OnClick="@this.WithdrawAsync" Disabled="@this.IsBusy">@T("Withdraw")</MudButton>
<MudButton StartIcon="@AppIcons.EDIT" OnClick="@this.EditAsync" Disabled="@this.IsBusy">@T("Edit")</MudButton>
<MudButton StartIcon="@AppIcons.WITHDRAW" OnClick="@this.WithdrawAsync" Disabled="@this.IsBusy">@T("Withdraw")</MudButton>
</MudStack>
</MudPaper>
}
<MudButton Variant="@(workState.Draft is null && workState.Confirmed is null ? Variant.Filled : Variant.Outlined)"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.AutoAwesome"
StartIcon="@AppIcons.GENERATE"
OnClick="@this.GenerateAsync"
Disabled="@(this.IsBusy || this.ProviderIssue is not null)">
@(workState.Draft is null && workState.Confirmed is null ? T("Create work state") : T("Create anew"))
@@ -105,8 +105,8 @@ else
<MudText Typo="Typo.subtitle2">@field.Label</MudText>
<MudText Typo="Typo.body2" Style="white-space: pre-wrap;">@TextOf(field, value)</MudText>
<MudStack Row="true" Spacing="1" Wrap="Wrap.Wrap" Class="mt-2">
<MudButton Size="Size.Small" Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Check" OnClick="@(() => this.TakeOverSuggestionAsync(field, value))" Disabled="@this.IsBusy">@T("Take over")</MudButton>
<MudButton Size="Size.Small" StartIcon="@Icons.Material.Filled.Close" OnClick="@(() => this.DismissSuggestionAsync(field))" Disabled="@this.IsBusy">@T("Dismiss")</MudButton>
<MudButton Size="Size.Small" Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.CONFIRM" OnClick="@(() => this.TakeOverSuggestionAsync(field, value))" Disabled="@this.IsBusy">@T("Take over")</MudButton>
<MudButton Size="Size.Small" StartIcon="@AppIcons.CLOSE" OnClick="@(() => this.DismissSuggestionAsync(field))" Disabled="@this.IsBusy">@T("Dismiss")</MudButton>
</MudStack>
</MudPaper>
}
@@ -241,7 +241,7 @@ public partial class BflWorkStatePanel : MSGComponentBase
catch (Exception exception) when (exception is IOException or UnauthorizedAccessException or InvalidDataException)
{
this.Logger.LogError(exception, "Could not save the work state of a step in the BeyondFacts Lab.");
await this.MessageBus.SendError(new(Icons.Material.Filled.SaveAs, TA("AI Studio could not save the work state. Please try again.")));
await this.MessageBus.SendError(new(AppIcons.SAVE_FAILED, TA("AI Studio could not save the work state. Please try again.")));
return false;
}
finally
@@ -5,10 +5,10 @@
<b>Links:</b>
</MudText>
<MudList T="string" Class="mb-6">
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://en.wikipedia.org/wiki/List_of_cognitive_biases">@T("Wikipedia list of cognitive biases")</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://commons.wikimedia.org/wiki/File:Cognitive_Bias_Codex_With_Definitions_1-2,_an_Extension_of_the_work_of_John_Manoogian_by_Brian_Rene_Morrissette.png">@T("Extended bias poster")</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://betterhumans.pub/cognitive-bias-cheat-sheet-55a472476b18">@T("Blog post of Buster Benson:") "Cognitive bias cheat sheet"</MudListItem>
<MudListItem T="string" Icon="@AppIcons.LINK" Target="_blank" Href="https://en.wikipedia.org/wiki/List_of_cognitive_biases">@T("Wikipedia list of cognitive biases")</MudListItem>
<MudListItem T="string" Icon="@AppIcons.LINK" Target="_blank" Href="https://commons.wikimedia.org/wiki/File:Cognitive_Bias_Codex_With_Definitions_1-2,_an_Extension_of_the_work_of_John_Manoogian_by_Brian_Rene_Morrissette.png">@T("Extended bias poster")</MudListItem>
<MudListItem T="string" Icon="@AppIcons.LINK" Target="_blank" Href="https://betterhumans.pub/cognitive-bias-cheat-sheet-55a472476b18">@T("Blog post of Buster Benson:") "Cognitive bias cheat sheet"</MudListItem>
</MudList>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -8,7 +8,7 @@
@if (this.step is BuilderStep.DESCRIBE)
{
<ReadFileContent Text="@T("Load description from file")" @bind-FileContent="@this.assistantDescription" EnableDragDrop="true" CatchAllDocuments="true"/>
<MudTextField T="string" @bind-Text="@this.assistantDescription" Validation="@this.ValidateAssistantDescription" AdornmentIcon="@Icons.Material.Filled.AutoAwesome" Adornment="Adornment.Start" Label="@T("Describe your assistant")" HelperText="@T("Describe the task, inputs, and desired output in your own words. The model will infer all the plugin details.")" Placeholder="@T("I need an assistant that turns meeting notes into clear tasks with owners and deadlines.")" Variant="Variant.Outlined" Lines="8" Sizing="InputSizing.Auto" MaxLines="18" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.assistantDescription" Validation="@this.ValidateAssistantDescription" AdornmentIcon="@AppIcons.GENERATE" Adornment="Adornment.Start" Label="@T("Describe your assistant")" HelperText="@T("Describe the task, inputs, and desired output in your own words. The model will infer all the plugin details.")" Placeholder="@T("I need an assistant that turns meeting notes into clear tasks with owners and deadlines.")" Variant="Variant.Outlined" Lines="8" Sizing="InputSizing.Auto" MaxLines="18" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
@* This switch chooses between the two kinds of assistant the Builder can create, so it stays
outside the advanced options. Its fields are required, and a collapsed panel would hide
@@ -32,7 +32,7 @@
launcher tile opens. The title lives here rather than in the advanced options, because a
launcher has no other visible content: its tile is the whole assistant. *@
<MudPaper Class="pa-3 mb-3 border-dashed border rounded-lg">
<MudTextField T="string" @bind-Text="@this.assistantName" AdornmentIcon="@Icons.Material.Filled.Assistant" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Tile title (optional)")" HelperText="@T("The title shown on the tile. Leave it empty to let the model choose one.")" Placeholder="@T("Weekly Report Chat")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.assistantName" AdornmentIcon="@AppIcons.NAME" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Tile title (optional)")" HelperText="@T("The title shown on the tile. Leave it empty to let the model choose one.")" Placeholder="@T("Weekly Report Chat")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<DirectChatLauncherForm WorkspaceName="@this.launcherWorkspaceName"
WorkspaceNameChanged="@this.LauncherWorkspaceNameChanged"
@bind-ProviderId="@this.launcherProviderId"
@@ -43,19 +43,19 @@
</MudPaper>
}
<CompactExpansionPanel HeaderText="@T("Advanced Options")" HeaderIcon="@Icons.Material.Filled.Tune" Class="mb-3 rounded">
<CompactExpansionPanel HeaderText="@T("Advanced Options")" HeaderIcon="@AppIcons.ADVANCED_SETTINGS" Class="mb-3 rounded">
@* A launcher shows this field inside its own frame above, next to the chat settings
it belongs with. *@
@if (!this.createChatLauncher)
{
<MudTextField T="string" @bind-Text="@this.assistantName" AdornmentIcon="@Icons.Material.Filled.Assistant" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Display Name (Optional)")" Placeholder="@T("Meeting Task Extractor")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.assistantName" AdornmentIcon="@AppIcons.NAME" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Display Name (Optional)")" Placeholder="@T("Meeting Task Extractor")" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
}
<EnumSelection T="AssistantCategory" NameFunc="@(category => category.NameSelecting)" @bind-Value="@this.selectedCategory" ValidateSelection="@this.ValidatingCategory" Icon="@Icons.Material.Filled.Category" IconSize="Size.Small" Label="@T("Category (Optional)")" AllowOther="@true" OtherValue="AssistantCategory.OTHER" @bind-OtherInput="@this.customCategory" ValidateOther="@this.ValidateCustomCategory" LabelOther="@T("Custom assistant category")" />
<EnumSelection T="AssistantCategory" NameFunc="@(category => category.NameSelecting)" @bind-Value="@this.selectedCategory" ValidateSelection="@this.ValidatingCategory" Icon="@AppIcons.CATEGORY" IconSize="Size.Small" Label="@T("Category (Optional)")" AllowOther="@true" OtherValue="AssistantCategory.OTHER" @bind-OtherInput="@this.customCategory" ValidateOther="@this.ValidateCustomCategory" LabelOther="@T("Custom assistant category")" />
@if (!this.createChatLauncher)
{
<MudTextField T="string" @bind-Text="@this.typicalInput" AdornmentIcon="@Icons.Material.Filled.Login" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Typical input (Optional)")" Placeholder="@T("What users provide, e.g. text, notes, files, or a URL")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="8" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.expectedOutput" AdornmentIcon="@Icons.Material.Filled.Logout" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Expected output (Optional)")" Placeholder="@T("What users should get, e.g. a summary or checklist")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="8" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudSelect T="AssistantComponentType" Label="@T("Input and UI components (Optional)")" MultiSelection="@true" @bind-SelectedValues="@this.selectedAssistantComponents" MultiSelectionTextFunc="@this.GetSelectedAssistantComponentText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3 rounded-lg" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ViewDay" IconSize="Size.Small">
<MudTextField T="string" @bind-Text="@this.typicalInput" AdornmentIcon="@AppIcons.INPUT" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Typical input (Optional)")" Placeholder="@T("What users provide, e.g. text, notes, files, or a URL")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="8" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.expectedOutput" AdornmentIcon="@AppIcons.OUTPUT" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Expected output (Optional)")" Placeholder="@T("What users should get, e.g. a summary or checklist")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="8" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudSelect T="AssistantComponentType" Label="@T("Input and UI components (Optional)")" MultiSelection="@true" @bind-SelectedValues="@this.selectedAssistantComponents" MultiSelectionTextFunc="@this.GetSelectedAssistantComponentText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="mb-3 rounded-lg" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.ASSISTANT_COMPONENTS" IconSize="Size.Small">
@foreach (var component in ASSISTANT_COMPONENT_OPTIONS)
{
<MudSelectItem T="AssistantComponentType" Value="@component">
@@ -63,10 +63,10 @@
</MudSelectItem>
}
</MudSelect>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedOutputLanguage" Icon="@Icons.Material.Filled.Translate" IconSize="Size.Small" Label="@T("(Optional) Output language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customOutputLanguage" ValidateOther="@this.ValidateCustomOutputLanguage" LabelOther="@T("Custom output language")" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedOutputLanguage" Icon="@AppIcons.LANGUAGE" IconSize="Size.Small" Label="@T("(Optional) Output language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customOutputLanguage" ValidateOther="@this.ValidateCustomOutputLanguage" LabelOther="@T("Custom output language")" />
<MudSwitch T="bool" @bind-Value="@this.allowGeneratedAssistantProfiles" Label="@T("Allow AI Studio profiles")" LabelPlacement="Placement.End" Color="Color.Primary" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.extraRules" AdornmentIcon="@Icons.Material.Filled.Rule" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Additional rules (Optional)")" Placeholder="@T("What to avoid or consider, e.g. do not invent missing facts")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="10" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.exampleRequest" AdornmentIcon="@Icons.Material.Filled.Lightbulb" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Example prompt (Optional)")" Placeholder="@T("An expected user prompt, e.g. summarize this document")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="10" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.extraRules" AdornmentIcon="@AppIcons.RULES" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Additional rules (Optional)")" Placeholder="@T("What to avoid or consider, e.g. do not invent missing facts")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="10" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.exampleRequest" AdornmentIcon="@AppIcons.EXAMPLE" Adornment="Adornment.Start" IconSize="Size.Small" Label="@T("Example prompt (Optional)")" Placeholder="@T("An expected user prompt, e.g. summarize this document")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="3" Sizing="InputSizing.Auto" MaxLines="10" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
}
</CompactExpansionPanel>
@@ -80,23 +80,23 @@ else
@T("Assistant draft")
</MudText>
<MudSpacer/>
<MudButton Variant="Variant.Outlined" StartIcon="@Icons.Material.Filled.Visibility" OnClick="@(async () => await this.OpenDraftDialog())">
<MudButton Variant="Variant.Outlined" StartIcon="@AppIcons.PREVIEW" OnClick="@(async () => await this.OpenDraftDialog())">
@T("View accepted draft")
</MudButton>
</MudStack>
<MudTextField T="string" @bind-Text="@this.reviewNotes" AdornmentIcon="@Icons.Material.Filled.EditNote" Adornment="Adornment.Start" Label="@T("Additional changes (Optional)")" HelperText="@T("These notes are applied on top of the accepted draft and can still change the generated assistant plugin. Leave empty to use the draft as-is.")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="2" Sizing="InputSizing.Auto" MaxLines="8" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.reviewNotes" AdornmentIcon="@AppIcons.PROMPT" Adornment="Adornment.Start" Label="@T("Additional changes (Optional)")" HelperText="@T("These notes are applied on top of the accepted draft and can still change the generated assistant plugin. Leave empty to use the draft as-is.")" Variant="Variant.Outlined" Margin="Margin.Dense" Lines="2" Sizing="InputSizing.Auto" MaxLines="8" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-6">
<MudTooltip Text="@T("Return to the original assistant description. The current draft and the plugin preview will be discarded.")">
<MudButton Variant="Variant.Text" StartIcon="@Icons.Material.Filled.ArrowBack" Size="Size.Small" OnClick="@this.BackToDescription">
<MudButton Variant="Variant.Text" StartIcon="@AppIcons.PREVIOUS" Size="Size.Small" OnClick="@this.BackToDescription">
@T("Change description")
</MudButton>
</MudTooltip>
@if (this.step is BuilderStep.DONE)
{
<MudTooltip Text="@T("Discard the current plugin preview, edit the accepted draft, and generate the plugin again.")">
<MudButton Variant="Variant.Outlined" StartIcon="@Icons.Material.Filled.Edit" Size="Size.Small" IconSize="Size.Small" OnClick="@(async () => await this.EditDraftAndDiscardPluginPreview())">
<MudButton Variant="Variant.Outlined" StartIcon="@AppIcons.EDIT" Size="Size.Small" IconSize="Size.Small" OnClick="@(async () => await this.EditDraftAndDiscardPluginPreview())">
@T("Edit draft")
</MudButton>
</MudTooltip>
@@ -110,7 +110,7 @@ else
@code {
private protected override RenderFragment? BelowSubmitContent => this.step is BuilderStep.DONE && !string.IsNullOrWhiteSpace(this.generatedLuaAssistant)
? @<MudStack Spacing="3" Class="mb-3">
<CompactExpansionPanel HeaderText="@T("Generated Lua plugin")" HeaderIcon="@Icons.Material.Filled.Code" IconColor="Color.Primary" Class="rounded">
<CompactExpansionPanel HeaderText="@T("Generated Lua plugin")" HeaderIcon="@AppIcons.CODE" IconColor="Color.Primary" Class="rounded">
<MudTextField T="string" Text="@this.generatedLuaAssistant" ReadOnly="true" Variant="Variant.Outlined" Lines="18" Class="mt-2" Style="font-family: monospace"/>
</CompactExpansionPanel>
@@ -135,13 +135,13 @@ else
}
else if (this.PluginCheckCompleted)
{
<MudAlert Severity="Severity.Info" Dense="@true" Icon="@Icons.Material.Filled.CheckCircle">
<MudAlert Severity="Severity.Info" Dense="@true" Icon="@AppIcons.SUCCESS">
@string.Format(T("The generated assistant '{0}' is valid and runnable."), this.pluginCheckResult?.PluginName ?? T("Unknown assistant"))
</MudAlert>
}
else
{
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Settings" Disabled="@(!this.CanRunPluginCheck)" OnClick="@(async () => await this.CheckGeneratedAssistantAsync())">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.PLUGIN_VALIDATION" Disabled="@(!this.CanRunPluginCheck)" OnClick="@(async () => await this.CheckGeneratedAssistantAsync())">
@T("Validate generated assistant")
</MudButton>
}
@@ -167,7 +167,7 @@ else
}
else if (this.PluginInstallCompleted)
{
<MudAlert Severity="Severity.Info" Dense="@true" Icon="@Icons.Material.Filled.Extension">
<MudAlert Severity="Severity.Info" Dense="@true" Icon="@AppIcons.PLUGIN">
@(this.pluginInstallResult?.ReplacedExisting is true
? string.Format(T("The assistant '{0}' was updated."), this.pluginInstallResult?.PluginName ?? T("Unknown assistant"))
: string.Format(T("The assistant '{0}' was installed."), this.pluginInstallResult?.PluginName ?? T("Unknown assistant")))
@@ -175,7 +175,7 @@ else
}
else
{
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Extension" Disabled="@(!this.CanInstallPlugin)" OnClick="@(async () => await this.InstallGeneratedAssistantAsync())">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.PLUGIN" Disabled="@(!this.CanInstallPlugin)" OnClick="@(async () => await this.InstallGeneratedAssistantAsync())">
@T("Install assistant")
</MudButton>
}
@@ -207,7 +207,7 @@ else
}
else
{
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Security" Disabled="@(!this.CanRunAudit)" OnClick="@(async () => await this.RunSecurityCheckAsync())">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.SECURITY_AUDIT" Disabled="@(!this.CanRunAudit)" OnClick="@(async () => await this.RunSecurityCheckAsync())">
@T("Start security audit")
</MudButton>
}
@@ -233,7 +233,7 @@ else
}
else if (this.EnableCompleted)
{
<MudAlert Severity="Severity.Info" Dense="@true" Icon="@Icons.Material.Filled.ToggleOn">
<MudAlert Severity="Severity.Info" Dense="@true" Icon="@AppIcons.ENABLE">
@T("The assistant is enabled.")
</MudAlert>
}
@@ -241,11 +241,11 @@ else
{
@if (this.RequiresActivationConfirmation)
{
<MudAlert Severity="Severity.Warning" Dense="@true" Icon="@Icons.Material.Filled.WarningAmber">
<MudAlert Severity="Severity.Warning" Dense="@true" Icon="@AppIcons.WARNING">
@T("The security check is below your required level. Your settings allow activation after confirmation.")
</MudAlert>
}
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.ToggleOn" Disabled="@(!this.CanEnableAssistant)" OnClick="@(async () => await this.EnableInstalledAssistantAsync())">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.ENABLE" Disabled="@(!this.CanEnableAssistant)" OnClick="@(async () => await this.EnableInstalledAssistantAsync())">
@T("Enable assistant")
</MudButton>
}
@@ -256,7 +256,7 @@ else
<MudStack Spacing="2" Class="mt-2">
@if (this.CanOpenAssistant)
{
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.OpenInNew" OnClick="@this.OpenInstalledAssistant">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.OPEN_ASSISTANT" OnClick="@this.OpenInstalledAssistant">
@T("Open assistant")
</MudButton>
}
@@ -640,7 +640,7 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
{
if (string.IsNullOrWhiteSpace(this.generatedLuaAssistant))
{
await this.MessageBus.SendError(new(Icons.Material.Filled.Extension, T("No assistant plugin was generated yet.")));
await this.MessageBus.SendError(new(AppIcons.PLUGIN, T("No assistant plugin was generated yet.")));
return;
}
@@ -655,11 +655,11 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
{
LOGGER.LogError($"The assistant plugin '{result.PluginName}' ({result.PluginId}) is not installable, because '{result.Issue}'");
this.FailInstallStep(BuilderInstallStep.CHECK_PLUGIN, result.Issue);
await this.MessageBus.SendError(new(Icons.Material.Filled.ReportProblem, T("The generated assistant could not be checked.")));
await this.MessageBus.SendError(new(AppIcons.ERROR, T("The generated assistant could not be checked.")));
return;
}
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.CheckCircle, T("The generated assistant can be installed.")));
await this.MessageBus.SendSuccess(new(AppIcons.SUCCESS, T("The generated assistant can be installed.")));
this.stepperIndex = (int)BuilderInstallStep.INSTALL_ASSISTANT;
}
finally
@@ -685,7 +685,7 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
{
LOGGER.LogError($"The assistant plugin {result.PluginName} ({result.PluginId}) could not be installed in the directory '{result.PluginDirectory}' with Issue: '{result.Issue}'.");
this.FailInstallStep(BuilderInstallStep.INSTALL_ASSISTANT, result.Issue);
await this.MessageBus.SendError(new(Icons.Material.Filled.ReportProblem, T("The assistant could not be installed.")));
await this.MessageBus.SendError(new(AppIcons.ERROR, T("The assistant could not be installed.")));
return;
}
@@ -693,11 +693,11 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
if (this.installedAssistantPlugin is null)
{
this.FailInstallStep(BuilderInstallStep.INSTALL_ASSISTANT, T("The installed assistant could not be loaded."));
await this.MessageBus.SendError(new(Icons.Material.Filled.ReportProblem, T("The installed assistant could not be loaded.")));
await this.MessageBus.SendError(new(AppIcons.ERROR, T("The installed assistant could not be loaded.")));
return;
}
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.Extension, result.ReplacedExisting ? T("Assistant updated.") : T("Assistant installed.")));
await this.MessageBus.SendSuccess(new(AppIcons.PLUGIN, result.ReplacedExisting ? T("Assistant updated.") : T("Assistant installed.")));
this.stepperIndex = this.AuditRequiredForActivation
? (int)BuilderInstallStep.SECURITY_CHECK
: this.EnableCompleted
@@ -725,7 +725,7 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
if (this.pluginAudit.Level is AssistantAuditLevel.UNKNOWN)
{
this.FailInstallStep(BuilderInstallStep.SECURITY_CHECK, T("The security check could not determine a result."));
await this.MessageBus.SendError(new(Icons.Material.Filled.GppMaybe, T("The security check could not be completed.")));
await this.MessageBus.SendError(new(AppIcons.SECURITY_WARNING, T("The security check could not be completed.")));
return;
}
@@ -741,7 +741,7 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
{
this.stepperIndex = (int)BuilderInstallStep.ENABLE_ASSISTANT;
this.FailInstallStep(BuilderInstallStep.ENABLE_ASSISTANT, T("This assistant cannot be enabled because the security check is below your required level."));
await this.MessageBus.SendError(new(Icons.Material.Filled.Block, T("The assistant cannot be enabled because it is below your required security level.")));
await this.MessageBus.SendError(new(AppIcons.BLOCKED, T("The assistant cannot be enabled because it is below your required security level.")));
return;
}
@@ -774,7 +774,7 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
await this.SettingsManager.StoreSettings();
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.ToggleOn, T("Assistant enabled.")));
await this.MessageBus.SendSuccess(new(AppIcons.ENABLE, T("Assistant enabled.")));
this.stepperIndex = (int)BuilderInstallStep.OPEN_ASSISTANT;
}
finally
@@ -813,7 +813,7 @@ public partial class AssistantBuilder : AssistantBaseCore<SettingsDialogAssistan
var result = await this.DirectChatService.TryCreateAssistantChatAsync(launcherPlugin);
if (result.Request is null)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.ReportProblem, result.ErrorMessage));
await this.MessageBus.SendError(new(AppIcons.ERROR, result.ErrorMessage));
return;
}
@@ -13,9 +13,9 @@
<MudTextSwitch Label="@T("Do you want to provide compiler messages?")" @bind-Value="@this.provideCompilerMessages" LabelOn="@T("Yes, provide compiler messages")" LabelOff="@T("No, there are no compiler messages")" />
@if (this.provideCompilerMessages)
{
<MudTextField T="string" @bind-Text="@this.compilerMessages" Validation="@this.ValidatingCompilerMessages" AdornmentIcon="@Icons.Material.Filled.Error" Adornment="Adornment.Start" Label="@T("Compiler messages")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.compilerMessages" Validation="@this.ValidatingCompilerMessages" AdornmentIcon="@AppIcons.COMPILER_MESSAGES" Adornment="Adornment.Start" Label="@T("Compiler messages")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
}
</MudStack>
<MudTextField T="string" @bind-Text="@this.questions" Validation="@this.ValidateQuestions" AdornmentIcon="@Icons.Material.Filled.QuestionMark" Adornment="Adornment.Start" Label="@T("Your question(s)")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.questions" Validation="@this.ValidateQuestions" AdornmentIcon="@AppIcons.QUESTIONS" Adornment="Adornment.Start" Label="@T("Your question(s)")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -27,16 +27,16 @@ else
{
@if (policy.IsEnterpriseConfiguration)
{
<MudListItem T="DataDocumentAnalysisPolicy" Icon="@Icons.Material.Filled.Policy" Value="@policy">
<MudListItem T="DataDocumentAnalysisPolicy" Icon="@AppIcons.ANALYSIS_POLICY" Value="@policy">
@policy.PolicyName
<MudTooltip Text="@T("This policy is managed by your organization.")" Placement="Placement.Right">
<MudIcon Icon="@Icons.Material.Filled.Business" Size="Size.Small" Class="ml-2" Style="vertical-align: middle;" />
<MudIcon Icon="@AppIcons.ORGANIZATION" Size="Size.Small" Class="ml-2" Style="vertical-align: middle;" />
</MudTooltip>
</MudListItem>
}
else
{
<MudListItem T="DataDocumentAnalysisPolicy" Icon="@Icons.Material.Filled.Policy" Value="@policy">
<MudListItem T="DataDocumentAnalysisPolicy" Icon="@AppIcons.ANALYSIS_POLICY" Value="@policy">
@policy.PolicyName
</MudListItem>
}
@@ -48,7 +48,7 @@ else
<MudButton OnClick="@this.AddPolicy" Disabled="@this.ArePolicyControlsDisabled" Variant="Variant.Filled" Color="Color.Primary">
@T("Add policy")
</MudButton>
<LockableButton Text="@T("Import policy")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY))" Disabled="@(() => this.ArePolicyControlsDisabled)" Icon="@Icons.Material.Filled.FileDownload" OnClickAsync="@this.ImportPolicy" ButtonVariant="Variant.Outlined" NoMargin="true" />
<LockableButton Text="@T("Import policy")" IsLocked="@(() => !this.SettingsManager.ConfigurationData.App.CanImportConfigurationSnippet(PluginConfigurationObjectType.DOCUMENT_ANALYSIS_POLICY))" Disabled="@(() => this.ArePolicyControlsDisabled)" Icon="@AppIcons.IMPORT" OnClickAsync="@this.ImportPolicy" ButtonVariant="Variant.Outlined" NoMargin="true" />
<MudButton OnClick="@this.RemovePolicy" Disabled="@(this.ArePolicyControlsDisabled || (this.selectedPolicy?.IsProtected ?? true) || (this.selectedPolicy?.IsEnterpriseConfiguration ?? true))" Variant="Variant.Filled" Color="Color.Error">
@T("Delete this policy")
</MudButton>
@@ -83,7 +83,7 @@ else
{
@* Standard view with expansion panels *@
<MudExpansionPanels Class="mb-3 mt-3" MultiExpansion="@false">
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Policy" HeaderText="@(T("Policy definition") + $": {this.selectedPolicy?.PolicyName}")" IsExpanded="@this.policyDefinitionExpanded" ExpandedChanged="@this.PolicyDefinitionExpandedChanged">
<ExpansionPanel HeaderIcon="@AppIcons.ANALYSIS_POLICY" HeaderText="@(T("Policy definition") + $": {this.selectedPolicy?.PolicyName}")" IsExpanded="@this.policyDefinitionExpanded" ExpandedChanged="@this.PolicyDefinitionExpandedChanged">
@if (!this.policyDefinitionExpanded)
{
<MudJustifiedText Typo="Typo.body1" Class="mb-1">
@@ -148,7 +148,7 @@ else
@T("Preparation for enterprise distribution")
</MudText>
<MudButton StartIcon="@Icons.Material.Filled.ContentCopy" Disabled="@(this.IsNoPolicySelected || (this.selectedPolicy?.IsEnterpriseConfiguration ?? false))" Variant="Variant.Filled" Color="Color.Default" OnClick="@this.ExportPolicyAsConfiguration">
<MudButton StartIcon="@AppIcons.EXPORT_CONFIGURATION" Disabled="@(this.IsNoPolicySelected || (this.selectedPolicy?.IsEnterpriseConfiguration ?? false))" Variant="Variant.Filled" Color="Color.Default" OnClick="@this.ExportPolicyAsConfiguration">
@T("Export policy as configuration section")
</MudButton>
}
@@ -157,7 +157,7 @@ else
<MudDivider Style="height: 0.25ch; margin: 1rem 0;" Class="mt-6" />
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.DocumentScanner" HeaderText="@(T("Document selection - Policy") + $": {this.selectedPolicy?.PolicyName}")" IsExpanded="@this.documentSelectionExpanded" ExpandedChanged="@this.DocumentSelectionExpandedChanged">
<ExpansionPanel HeaderIcon="@AppIcons.ASSISTANT_DOCUMENT_ANALYSIS" HeaderText="@(T("Document selection - Policy") + $": {this.selectedPolicy?.PolicyName}")" IsExpanded="@this.documentSelectionExpanded" ExpandedChanged="@this.DocumentSelectionExpandedChanged">
<MudText Typo="Typo.h5" Class="mb-1">
@T("Policy Description")
</MudText>
@@ -923,21 +923,21 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore<NoSettingsPan
if (!extraction.HasUsableContent)
{
this.Logger.LogError("Reading the document '{FilePath}' failed and it will not be analyzed: code={ErrorCode}, message='{ErrorMessage}'.", document.FilePath, extraction.ErrorCode, extraction.ErrorMessage);
await this.MessageBus.SendError(new(Icons.Material.Filled.Description, extraction.ToUserMessage(document.FileName)));
await this.MessageBus.SendError(new(AppIcons.DOCUMENT, extraction.ToUserMessage(document.FileName)));
continue;
}
if (extraction.Outcome is FileExtractionOutcome.PARTIAL)
{
this.Logger.LogWarning("Parts of the document '{FilePath}' could not be read: pages={FailedPages}.", document.FilePath, string.Join(", ", extraction.FailedPages));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Description, extraction.ToPartialUserMessage(document.FileName)));
await this.MessageBus.SendWarning(new(AppIcons.DOCUMENT, extraction.ToPartialUserMessage(document.FileName)));
}
// The file was read correctly, but its extension lies about what it contains:
if (extraction.HasExtensionMismatch)
{
this.Logger.LogWarning("The document '{FilePath}' is actually a '{DetectedFormat}'.", document.FilePath, extraction.DetectedFormat);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.RuleFolder, extraction.ToExtensionMismatchUserMessage(document.FileName)));
await this.MessageBus.SendWarning(new(AppIcons.FILE_TYPE_MISMATCH, extraction.ToExtensionMismatchUserMessage(document.FileName)));
}
var fileContent = extraction.Content;
@@ -1007,7 +1007,7 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore<NoSettingsPan
{
if (this.IsNoPolicySelected)
{
await this.MessageBus.SendError(new (Icons.Material.Filled.Policy, this.T("No policy is selected. Please select a policy to export.")));
await this.MessageBus.SendError(new (AppIcons.ANALYSIS_POLICY, this.T("No policy is selected. Please select a policy to export.")));
return;
}
@@ -1031,7 +1031,7 @@ public partial class DocumentAnalysisAssistant : AssistantBaseCore<NoSettingsPan
policyIssues.Count,
string.Join(" | ", policyIssues));
await this.MessageBus.SendError(new (Icons.Material.Filled.Policy, $"{this.T("The selected policy contains invalid data. Please fix the issues before exporting the policy.")} {string.Join(" ", policyIssues)}"));
await this.MessageBus.SendError(new (AppIcons.ANALYSIS_POLICY, $"{this.T("The selected policy contains invalid data. Please fix the issues before exporting the policy.")} {string.Join(" ", policyIssues)}"));
return;
}
@@ -57,7 +57,7 @@ else
@code {
private protected override RenderFragment? HeaderActions => this.CanReviseCurrentAssistant
? @<MudTooltip Text="@T("Revise assistant")">
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.AutoMode" OnClick="@(async () => await this.OpenRevisionDialogAsync())"/>
<MudIconButton Variant="Variant.Text" Icon="@AppIcons.REVISE_ASSISTANT" OnClick="@(async () => await this.OpenRevisionDialogAsync())"/>
</MudTooltip>
: null;
@@ -67,7 +67,7 @@ else
LabelPlacement="@assistantSwitch.GetLabelPlacement()"
Color="@AssistantSwitch.GetColor(assistantSwitch.CheckedColor)"
UncheckedColor="@AssistantSwitch.GetColor(assistantSwitch.UncheckedColor)"
ThumbIcon="@assistantSwitch.GetIconSvg()"
ThumbIcon="@assistantSwitch.GetIcon()"
ThumbIconColor="@AssistantSwitch.GetColor(assistantSwitch.IconColor)"
Disabled="@(assistantSwitch.Disabled || this.IsSwitchActionRunning(assistantSwitch.Name))"
Class="@assistantSwitch.Class"
@@ -104,7 +104,7 @@ else
MaxLength="@textArea.MaxLength"
Immediate="@textArea.IsImmediate"
Adornment="@textArea.GetAdornmentPos()"
AdornmentIcon="@AssistantComponentPropHelper.GetIconSvg(textArea.AdornmentIcon)"
AdornmentIcon="@AssistantComponentPropHelper.GetIcon(textArea.AdornmentIcon)"
AdornmentText="@textArea.AdornmentText"
AdornmentColor="@textArea.GetAdornmentColor()"
Variant="Variant.Outlined"
@@ -190,8 +190,8 @@ else
Default="@assistantDropdown.Default"
Label="@assistantDropdown.Label"
HelperText="@assistantDropdown.HelperText"
OpenIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.OpenIcon)"
CloseIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.CloseIcon)"
OpenIcon="@AssistantComponentPropHelper.GetIcon(assistantDropdown.OpenIcon)"
CloseIcon="@AssistantComponentPropHelper.GetIcon(assistantDropdown.CloseIcon)"
IconColor="@AssistantComponentPropHelper.GetColor(assistantDropdown.IconColor, Color.Default)"
IconPosition="@AssistantComponentPropHelper.GetAdornment(assistantDropdown.IconPositon, Adornment.End)"
Variant="@AssistantComponentPropHelper.GetVariant(assistantDropdown.Variant, Variant.Outlined)"
@@ -209,8 +209,8 @@ else
Default="@assistantDropdown.Default"
Label="@assistantDropdown.Label"
HelperText="@assistantDropdown.HelperText"
OpenIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.OpenIcon)"
CloseIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.CloseIcon)"
OpenIcon="@AssistantComponentPropHelper.GetIcon(assistantDropdown.OpenIcon)"
CloseIcon="@AssistantComponentPropHelper.GetIcon(assistantDropdown.CloseIcon)"
IconColor="@AssistantComponentPropHelper.GetColor(assistantDropdown.IconColor, Color.Default)"
IconPosition="@AssistantComponentPropHelper.GetAdornment(assistantDropdown.IconPositon, Adornment.End)"
Variant="@AssistantComponentPropHelper.GetVariant(assistantDropdown.Variant, Variant.Outlined)"
@@ -226,7 +226,7 @@ else
if (component is AssistantButton assistantButton)
{
var button = assistantButton;
var icon = AssistantComponentPropHelper.GetIconSvg(button.StartIcon);
var icon = AssistantComponentPropHelper.GetIcon(button.StartIcon);
var iconColor = AssistantComponentPropHelper.GetColor(button.IconColor, Color.Inherit);
var color = AssistantComponentPropHelper.GetColor(button.Color, Color.Default);
var size = AssistantComponentPropHelper.GetComponentSize(button.Size, Size.Medium);
@@ -244,7 +244,7 @@ else
Size="@size"
FullWidth="@button.IsFullWidth"
StartIcon="@icon"
EndIcon="@AssistantComponentPropHelper.GetIconSvg(button.EndIcon)"
EndIcon="@AssistantComponentPropHelper.GetIcon(button.EndIcon)"
IconColor="@iconColor"
IconSize="@iconSize"
Disabled="@disabled"
@@ -365,13 +365,13 @@ else
Dense="@accordionSection.IsDense"
Gutters="@accordionSection.HasInnerPadding"
HideIcon="@accordionSection.HideIcon"
Icon="@AssistantComponentPropHelper.GetIconSvg(accordionSection.ExpandIcon)"
Icon="@AssistantComponentPropHelper.GetIcon(accordionSection.ExpandIcon)"
MaxHeight="@accordionSection.MaxHeight"
Class="@accordionSection.Class"
Style="@GetOptionalStyle(accordionSection.Style)">
<TitleContent>
<div class="d-flex">
<MudIcon Icon="@AssistantComponentPropHelper.GetIconSvg(accordionSection.HeaderIcon)" class="mr-3"></MudIcon>
<MudIcon Icon="@AssistantComponentPropHelper.GetIcon(accordionSection.HeaderIcon)" class="mr-3"></MudIcon>
<MudText Align="@AssistantComponentPropHelper.GetAlignment(accordionSection.HeaderAlign)"
Color="@textColor"
Typo="@AssistantComponentPropHelper.GetTypography(accordionSection.HeaderTypo)">
@@ -458,11 +458,11 @@ else
@if (item.Type == "LINK")
{
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" IconColor="@iconColor" Target="_blank" Href="@item.Href">@item.Text</MudListItem>
<MudListItem T="string" Icon="@AppIcons.LINK" IconColor="@iconColor" Target="_blank" Href="@item.Href">@item.Text</MudListItem>
}
else
{
var icon = !string.IsNullOrEmpty(item.Icon) ? AssistantComponentPropHelper.GetIconSvg(item.Icon) : string.Empty;
var icon = !string.IsNullOrEmpty(item.Icon) ? AssistantComponentPropHelper.GetIcon(item.Icon) : string.Empty;
<MudListItem T="string" Icon="@icon" IconColor="@iconColor">@item.Text</MudListItem>
}
}
@@ -309,7 +309,7 @@ public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
if (updatedPlugin is not null && !updatedPlugin.StartsChatDirectly)
this.ApplyUpdatedAssistantPlugin(updatedPlugin);
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.AutoFixHigh, string.Format(this.T("The assistant '{0}' has been updated."), revisionResult.PluginName)));
await this.MessageBus.SendSuccess(new(AppIcons.REVISE_ASSISTANT, string.Format(this.T("The assistant '{0}' has been updated."), revisionResult.PluginName)));
await this.MessageBus.SendMessage<bool>(this, Event.PLUGINS_RELOADED);
await this.MessageBus.SendMessage<bool>(this, Event.CONFIGURATION_CHANGED);
@@ -327,7 +327,7 @@ public partial class AssistantDynamic : AssistantBaseCore<NoSettingsPanel>
var result = await this.DirectChatService.TryCreateAssistantChatAsync(launcherPlugin);
if (result.Request is null)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.ReportProblem, result.ErrorMessage));
await this.MessageBus.SendError(new(AppIcons.ERROR, result.ErrorMessage));
this.NavigationManager.NavigateTo(Routes.ASSISTANTS);
return;
}
@@ -5,13 +5,13 @@
@if (this.provideHistory)
{
<MudPaper Class="pa-3 mb-8 border-dashed border rounded-lg">
<MudTextField T="string" @bind-Text="@this.inputHistory" Validation="@this.ValidateHistory" Label="@T("Previous conversation")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Provide the previous conversation, e.g., the last e-mail, the last chat, etc.")" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.DocumentScanner"/>
<MudTextField T="string" @bind-Text="@this.inputHistory" Validation="@this.ValidateHistory" Label="@T("Previous conversation")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Provide the previous conversation, e.g., the last e-mail, the last chat, etc.")" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.INPUT_TEXT"/>
</MudPaper>
}
<MudTextField T="string" @bind-Text="@this.inputGreeting" Label="@T("(Optional) The greeting phrase to use")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Placeholder="@T("Dear Colleagues")" Class="mb-3"/>
<DebouncedTextField @bind-Text="@this.inputBulletPoints" ValidationFunc="@this.ValidateBulletPoints" Icon="@Icons.Material.Filled.ListAlt" Label="@T("Your bullet points")" Lines="6" MaxLines="12" Attributes="@USER_INPUT_ATTRIBUTES" HelpText="@T("Bullet list the content of the e-mail roughly. Use dashes (-) to separate the items.")" DebounceTime="TimeSpan.FromSeconds(1)" WhenTextCanged="@this.OnContentChanged" Placeholder="@PLACEHOLDER_BULLET_POINTS"/>
<MudSelect T="string" Label="@T("(Optional) Are any of your points particularly important?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ListAlt">
<MudTextField T="string" @bind-Text="@this.inputGreeting" Label="@T("(Optional) The greeting phrase to use")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.USER" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Placeholder="@T("Dear Colleagues")" Class="mb-3"/>
<DebouncedTextField @bind-Text="@this.inputBulletPoints" ValidationFunc="@this.ValidateBulletPoints" Icon="@AppIcons.LIST" Label="@T("Your bullet points")" Lines="6" MaxLines="12" Attributes="@USER_INPUT_ATTRIBUTES" HelpText="@T("Bullet list the content of the e-mail roughly. Use dashes (-) to separate the items.")" DebounceTime="TimeSpan.FromSeconds(1)" WhenTextCanged="@this.OnContentChanged" Placeholder="@PLACEHOLDER_BULLET_POINTS"/>
<MudSelect T="string" Label="@T("(Optional) Are any of your points particularly important?")" MultiSelection="@true" @bind-SelectedValues="@this.selectedFoci" Variant="Variant.Outlined" Class="mb-3" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LIST">
@foreach (var contentLine in this.bulletPointsLines)
{
<MudSelectItem T="string" Value="@contentLine">
@@ -19,7 +19,7 @@
</MudSelectItem>
}
</MudSelect>
<MudTextField T="string" @bind-Text="@this.inputName" Label="@T("(Optional) Your name for the closing salutation")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Person" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Your name for the closing salutation of your e-mail.")" Class="mb-3"/>
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name)" @bind-Value="@this.selectedWritingStyle" Icon="@Icons.Material.Filled.Edit" Label="@T("Select the writing style")" ValidateSelection="@this.ValidateWritingStyle"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<MudTextField T="string" @bind-Text="@this.inputName" Label="@T("(Optional) Your name for the closing salutation")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.USER" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Your name for the closing salutation of your e-mail.")" Class="mb-3"/>
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name)" @bind-Value="@this.selectedWritingStyle" Icon="@AppIcons.WRITING_STYLE" Label="@T("Select the writing style")" ValidateSelection="@this.ValidateWritingStyle"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidateTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -14,10 +14,10 @@
</b>
</MudText>
<MudList T="string" Class="mb-6">
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://github.com/MindWorkAI/ERI">
<MudListItem T="string" Icon="@AppIcons.LINK" Target="_blank" Href="https://github.com/MindWorkAI/ERI">
@T("ERI repository with example implementation in .NET and C#")
</MudListItem>
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="https://mindworkai.org/swagger-ui.html">
<MudListItem T="string" Icon="@AppIcons.LINK" Target="_blank" Href="https://mindworkai.org/swagger-ui.html">
@T("Interactive documentation aka Swagger UI")
</MudListItem>
</MudList>
@@ -44,7 +44,7 @@ else
<MudList Disabled="@this.AreServerPresetControlsDisabled" T="DataERIServer" Class="mb-1" SelectedValue="@this.selectedERIServer" SelectedValueChanged="@this.SelectedERIServerChanged">
@foreach (var server in this.SettingsManager.ConfigurationData.ERI.ERIServers)
{
<MudListItem T="DataERIServer" Icon="@Icons.Material.Filled.Settings" Value="@server">
<MudListItem T="DataERIServer" Icon="@AppIcons.ERI_SERVER" Value="@server">
@server.ServerName
</MudListItem>
}
@@ -93,7 +93,7 @@ else
<MudTextField T="string" Disabled="@this.IsERIInputDisabled" @bind-Text="@this.serverDescription" Validation="@this.ValidateServerDescription" Immediate="@true" Label="@T("ERI server description")" HelperText="@T("Please provide a brief description of your ERI server. Describe or explain what your ERI server does and what data it uses for this purpose. This description will be shown to users in AI Studio.")" Counter="512" MaxLength="512" Variant="Variant.Outlined" Margin="Margin.Normal" Lines="3" Sizing="InputSizing.Auto" MaxLines="6" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudStack Row="@true" Class="mb-3">
<MudSelect Disabled="@this.IsERIInputDisabled" T="ProgrammingLanguages" @bind-Value="@this.selectedProgrammingLanguage" AdornmentIcon="@Icons.Material.Filled.Code" Adornment="Adornment.Start" Label="@T("Programming language")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateProgrammingLanguage">
<MudSelect Disabled="@this.IsERIInputDisabled" T="ProgrammingLanguages" @bind-Value="@this.selectedProgrammingLanguage" AdornmentIcon="@AppIcons.CODE" Adornment="Adornment.Start" Label="@T("Programming language")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateProgrammingLanguage">
@foreach (var language in Enum.GetValues<ProgrammingLanguages>())
{
<MudSelectItem Value="@language">
@@ -117,7 +117,7 @@ else
}
</MudSelect>
<MudButton Variant="Variant.Outlined" Size="Size.Small" Disabled="@this.IsSpecificationSavingDisabled" OnClick="@this.SaveSpecificationAsync">
<MudIcon Icon="@Icons.Material.Filled.Save" Class="mr-2"/> @T("Save specification")
<MudIcon Icon="@AppIcons.SAVE" Class="mr-2"/> @T("Save specification")
</MudButton>
</MudStack>
@@ -126,7 +126,7 @@ else
</MudText>
<MudStack Row="@false" Spacing="1" Class="mb-3">
<MudSelect Disabled="@this.IsERIInputDisabled" T="DataSources" @bind-Value="@this.selectedDataSource" AdornmentIcon="@Icons.Material.Filled.Dataset" Adornment="Adornment.Start" Label="@T("Data source")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateDataSource" SelectedValuesChanged="@this.DataSourceWasChanged">
<MudSelect Disabled="@this.IsERIInputDisabled" T="DataSources" @bind-Value="@this.selectedDataSource" AdornmentIcon="@AppIcons.DATA_SOURCE" Adornment="Adornment.Start" Label="@T("Data source")" Variant="Variant.Outlined" Margin="Margin.Dense" Validation="@this.ValidateDataSource" SelectedValuesChanged="@this.DataSourceWasChanged">
@foreach (var dataSource in Enum.GetValues<DataSources>())
{
<MudSelectItem Value="@dataSource">
@@ -243,10 +243,10 @@ else
<MudTd>@context.EmbeddingType</MudTd>
<MudTd>
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditEmbedding(context)" Disabled="@this.IsProcessing">
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@AppIcons.EDIT" OnClick="() => this.EditEmbedding(context)" Disabled="@this.IsProcessing">
@T("Edit")
</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteEmbedding(context)" Disabled="@this.IsProcessing">
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@AppIcons.DELETE" OnClick="() => this.DeleteEmbedding(context)" Disabled="@this.IsProcessing">
@T("Delete")
</MudButton>
</MudStack>
@@ -262,7 +262,7 @@ else
}
}
<MudButton Disabled="@this.IsERIInputDisabled" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddEmbedding">
<MudButton Disabled="@this.IsERIInputDisabled" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@AppIcons.ADD" Class="mt-3 mb-6" OnClick="@this.AddEmbedding">
@T("Add Embedding Method")
</MudButton>
@@ -289,10 +289,10 @@ else
<MudTd>@context.Name</MudTd>
<MudTd>
<MudStack Row="true" Class="mb-2 mt-2" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@Icons.Material.Filled.Edit" OnClick="() => this.EditRetrievalProcess(context)" Disabled="@this.IsProcessing">
<MudButton Variant="Variant.Filled" Color="Color.Info" StartIcon="@AppIcons.EDIT" OnClick="() => this.EditRetrievalProcess(context)" Disabled="@this.IsProcessing">
@T("Edit")
</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="() => this.DeleteRetrievalProcess(context)" Disabled="@this.IsProcessing">
<MudButton Variant="Variant.Filled" Color="Color.Error" StartIcon="@AppIcons.DELETE" OnClick="() => this.DeleteRetrievalProcess(context)" Disabled="@this.IsProcessing">
@T("Delete")
</MudButton>
</MudStack>
@@ -308,7 +308,7 @@ else
}
}
<MudButton Disabled="@this.IsERIInputDisabled" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@Icons.Material.Filled.AddRoad" Class="mt-3 mb-6" OnClick="@this.AddRetrievalProcess">
<MudButton Disabled="@this.IsERIInputDisabled" Variant="Variant.Filled" Color="@Color.Primary" StartIcon="@AppIcons.ADD" Class="mt-3 mb-6" OnClick="@this.AddRetrievalProcess">
@T("Add Retrieval Process")
</MudButton>
@@ -53,7 +53,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
new ButtonData
{
Text = T("Open in chat"),
Icon = Icons.Material.Filled.Chat,
Icon = AppIcons.CHAT,
Color = Color.Default,
AsyncAction = this.OpenInChat,
DisabledActionParam = () => !this.CanOpenInChat,
@@ -398,7 +398,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
{
if (await this.WebRootFiles.CopyToAsync(specificationPath, response.SaveFilePath))
{
await feedback.SucceededAsync(Icons.Material.Filled.CheckCircle, T("The ERI specification was saved."), response.SaveFilePath, true);
await feedback.SucceededAsync(AppIcons.SUCCESS, T("The ERI specification was saved."), response.SaveFilePath, true);
return;
}
@@ -409,7 +409,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
this.Logger.LogError(exception, "Failed to save the ERI specification {ERIVersion}.", this.selectedERIVersion);
}
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Cancel, T("The ERI specification could not be saved.")));
await MessageBus.INSTANCE.SendError(new(AppIcons.ERROR, T("The ERI specification could not be saved.")));
}
/// <summary>
@@ -917,7 +917,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
if (!ERIServerFileList.TryParse(fileListAnswer, out var filesToGenerate))
{
this.Logger.LogWarning("The list of files could not be read from the answer of the model: '{Answer}'", fileListAnswer);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.SaveAs, T("The list of files in the answer of the model could not be read, so no files were created. Please try again.")));
await this.MessageBus.SendWarning(new(AppIcons.SAVE_FAILED, T("The list of files in the answer of the model could not be read, so no files were created. Please try again.")));
return;
}
@@ -986,7 +986,7 @@ public partial class AssistantERI : AssistantBaseCore<SettingsDialogERIServer>
if (outcome is ERIServerFileOutcome.WRITTEN)
generatedFiles.Add(ERIServerFiles.PathOf(baseDirectorySnapshot, file));
else
await this.MessageBus.SendWarning(new(Icons.Material.Filled.SaveAs, outcome.ToUserMessage(file)));
await this.MessageBus.SendWarning(new(AppIcons.SAVE_FAILED, outcome.ToUserMessage(file)));
}
}
@@ -2,6 +2,6 @@
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogGrammarSpelling>
<ReadFileContent Text="@T("Load text from file")" @bind-FileContent="@this.inputText" EnableDragDrop="true" CatchAllDocuments="true"/>
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Your input to check")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom language")" />
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@AppIcons.INPUT_TEXT" Adornment="Adornment.Start" Label="@T("Your input to check")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -2,7 +2,7 @@
@using AIStudio.Settings
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogI18N>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidatingTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" SelectionUpdated="_ => this.OnChangedLanguage()" Disabled="@this.IsProcessing" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidatingTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" SelectionUpdated="_ => this.OnChangedLanguage()" Disabled="@this.IsProcessing" />
<ConfigurationSelect OptionDescription="@T("Language plugin used for comparision")" SelectedValue="@(() => this.selectedLanguagePluginId)" Data="@ConfigurationSelectDataFactory.GetLanguagesData()" SelectionUpdate="@(async void (id) => await this.OnLanguagePluginChanged(id))" OptionHelp="@T("Select the language plugin used for comparision.")" Disabled="@(() => this.IsProcessing)"/>
@if (this.isLoading)
{
@@ -22,7 +22,7 @@ else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
</MudText>
<MudTable Items="@this.AddedContentRows" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
<ToolBarContent>
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.SEARCH" IconSize="Size.Medium" Class="mt-0"/>
</ToolBarContent>
<ColGroup>
<col/>
@@ -50,7 +50,7 @@ else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
</MudText>
<MudTable Items="@this.RemovedContentRows" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
<ToolBarContent>
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.SEARCH" IconSize="Size.Medium" Class="mt-0"/>
</ToolBarContent>
<ColGroup>
<col/>
@@ -92,7 +92,7 @@ else if (!this.isLoading && string.IsNullOrWhiteSpace(this.loadingIssue))
</MudText>
<MudTable Items="@this.LocalizedContentRows" Hover="@true" Filter="@this.FilterFunc" Class="border-dashed border rounded-lg mb-6">
<ToolBarContent>
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"/>
<MudTextField @bind-Value="@this.searchString" Immediate="true" Placeholder="@T("Search")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.SEARCH" IconSize="Size.Medium" Class="mt-0"/>
</ToolBarContent>
<ColGroup>
<col/>
@@ -64,7 +64,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
#else
Text = T("Copy Lua code to clipboard"),
#endif
Icon = Icons.Material.Filled.Extension,
Icon = AppIcons.PLUGIN,
Color = Color.Default,
#if DEBUG
AsyncAction = async () => await this.WriteToPluginFile(),
@@ -488,13 +488,13 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
{
if (this.selectedLanguagePlugin is null)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.Translate, T("No language plugin selected.")));
await this.MessageBus.SendError(new(AppIcons.ASSISTANT_LOCALIZATION, T("No language plugin selected.")));
return;
}
if (this.finalLuaCode.Length == 0)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.Code, T("No Lua code generated yet.")));
await this.MessageBus.SendError(new(AppIcons.CODE, T("No Lua code generated yet.")));
return;
}
@@ -510,7 +510,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
if (!File.Exists(pluginFilePath))
{
this.Logger.LogError("Plugin file not found: {PluginFilePath}.", pluginFilePath);
await this.MessageBus.SendError(new(Icons.Material.Filled.FindInPage, T("Plugin file not found.")));
await this.MessageBus.SendError(new(AppIcons.FILE_NOT_FOUND, T("Plugin file not found.")));
return;
}
@@ -524,7 +524,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
if (markerIndex == -1)
{
this.Logger.LogError("Could not find 'UI_TEXT_CONTENT = {{}}' marker in plugin file: {PluginFilePath}", pluginFilePath);
await this.MessageBus.SendError(new(Icons.Material.Filled.FindInPage, T("Could not find 'UI_TEXT_CONTENT = {}' marker in plugin file.")));
await this.MessageBus.SendError(new(AppIcons.FILE_NOT_FOUND, T("Could not find 'UI_TEXT_CONTENT = {}' marker in plugin file.")));
return;
}
@@ -534,12 +534,12 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
// Write the updated content back to the file:
await File.WriteAllTextAsync(pluginFilePath, newContent);
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.Translate, T("Successfully updated plugin file.")));
await this.MessageBus.SendSuccess(new(AppIcons.ASSISTANT_LOCALIZATION, T("Successfully updated plugin file.")));
}
catch (Exception ex)
{
this.Logger.LogError(ex, "Error writing to plugin file.");
await this.MessageBus.SendError(new(Icons.Material.Filled.Translate, T("Error writing to plugin file.")));
await this.MessageBus.SendError(new(AppIcons.ASSISTANT_LOCALIZATION, T("Error writing to plugin file.")));
}
}
#endif
@@ -13252,6 +13252,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1378412877"] = "Once the encodin
-- This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat.
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1388816916"] = "This library is used to read PDF files. This is necessary, e.g., for using PDFs as a data source for a chat."
-- The icons of AI Studio come from Lucide, an open-source icon set. AI Studio ships them as a font, so showing them never sends a request to the internet. Lucide is licensed under ISC; the icons it took over from Feather remain under MIT.
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1390097716"] = "The icons of AI Studio come from Lucide, an open-source icon set. AI Studio ships them as a font, so showing them never sends a request to the internet. Lucide is licensed under ISC; the icons it took over from Feather remain under MIT."
-- Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio.
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1402243995"] = "Updates are managed by your organization. Contact your IT department if you have questions about updating AI Studio."
@@ -1,10 +1,10 @@
@attribute [Route(Routes.ASSISTANT_ICON_FINDER)]
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogIconFinder>
<MudTextField T="string" @bind-Text="@this.inputContext" Validation="@this.ValidatingContext" AdornmentIcon="@Icons.Material.Filled.Description" Adornment="Adornment.Start" Label="@T("Your context")" Variant="Variant.Outlined" Lines="3" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.inputContext" Validation="@this.ValidatingContext" AdornmentIcon="@AppIcons.DESCRIPTION" Adornment="Adornment.Start" Label="@T("Your context")" Variant="Variant.Outlined" Lines="3" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudStack Row="@true" AlignItems="AlignItems.Center" Class="mb-3">
<MudSelect T="IconSources" @bind-Value="@this.selectedIconSource" AdornmentIcon="@Icons.Material.Filled.Source" Adornment="Adornment.Start" Label="@T("Your icon source")" Variant="Variant.Outlined" Margin="Margin.Dense">
<MudSelect T="IconSources" @bind-Value="@this.selectedIconSource" AdornmentIcon="@AppIcons.ICON_SOURCE" Adornment="Adornment.Start" Label="@T("Your icon source")" Variant="Variant.Outlined" Margin="Margin.Dense">
@foreach (var source in Enum.GetValues<IconSources>())
{
<MudSelectItem Value="@source">
@@ -1,20 +1,20 @@
@attribute [Route(Routes.ASSISTANT_JOB_POSTING)]
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogJobPostings>
<MudTextField T="string" @bind-Text="@this.inputCompanyName" Label="@T("(Optional) The company name")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Warehouse" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputCountryLegalFramework" Label="@T("Provide the country, where the company is located")" Validation="@this.ValidateCountryLegalFramework" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Flag" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3" HelperText="@T("This is important to consider the legal framework of the country.")"/>
<MudTextField T="string" @bind-Text="@this.inputCompanyName" Label="@T("(Optional) The company name")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.COMPANY" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputCountryLegalFramework" Label="@T("Provide the country, where the company is located")" Validation="@this.ValidateCountryLegalFramework" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.COUNTRY" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3" HelperText="@T("This is important to consider the legal framework of the country.")"/>
@* Four zones, so no default target: every drop has to be aimed at the field it belongs to. *@
<ReadFileContent Text="@T("Load the mandatory information from file")" @bind-FileContent="@this.inputMandatoryInformation" EnableDragDrop="true"/>
<MudTextField T="string" @bind-Text="@this.inputMandatoryInformation" Label="@T("(Optional) Provide mandatory information")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.TextSnippet" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Mandatory information that your company requires for all job postings. This can include the company description, etc.")" />
<MudTextField T="string" @bind-Text="@this.inputMandatoryInformation" Label="@T("(Optional) Provide mandatory information")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.JOB_DETAILS" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Mandatory information that your company requires for all job postings. This can include the company description, etc.")" />
<ReadFileContent Text="@T("Load the job description from file")" @bind-FileContent="@this.inputJobDescription" EnableDragDrop="true"/>
<MudTextField T="string" @bind-Text="@this.inputJobDescription" Label="@T("Job description")" Validation="@this.ValidateJobDescription" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Settings" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe what the person is supposed to do in the company. This might be just short bullet points.")" />
<MudTextField T="string" @bind-Text="@this.inputJobDescription" Label="@T("Job description")" Validation="@this.ValidateJobDescription" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.JOB_DETAILS" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe what the person is supposed to do in the company. This might be just short bullet points.")" />
<ReadFileContent Text="@T("Load the qualifications from file")" @bind-FileContent="@this.inputQualifications" EnableDragDrop="true"/>
<MudTextField T="string" @bind-Text="@this.inputQualifications" Label="@T("(Optional) Provide necessary job qualifications")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Settings" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe what the person should bring to the table. This might be just short bullet points.")" />
<MudTextField T="string" @bind-Text="@this.inputQualifications" Label="@T("(Optional) Provide necessary job qualifications")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.JOB_DETAILS" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe what the person should bring to the table. This might be just short bullet points.")" />
<ReadFileContent Text="@T("Load the responsibilities from file")" @bind-FileContent="@this.inputResponsibilities" EnableDragDrop="true"/>
<MudTextField T="string" @bind-Text="@this.inputResponsibilities" Label="@T("(Optional) Provide job responsibilities")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Settings" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the responsibilities the person should take on in the company.")" />
<MudTextField T="string" @bind-Text="@this.inputWorkLocation" Label="@T("(Optional) Provide the work location")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.MyLocation" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputEntryDate" Label="@T("(Optional) Provide the entry date")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.DateRange" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputValidUntil" Label="@T("(Optional) Provide the date until the job posting is valid")" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.DateRange" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputResponsibilities" Label="@T("(Optional) Provide job responsibilities")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.JOB_DETAILS" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES" HelperText="@T("Describe the responsibilities the person should take on in the company.")" />
<MudTextField T="string" @bind-Text="@this.inputWorkLocation" Label="@T("(Optional) Provide the work location")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LOCATION" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputEntryDate" Label="@T("(Optional) Provide the entry date")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.DATE" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<MudTextField T="string" @bind-Text="@this.inputValidUntil" Label="@T("(Optional) Provide the date until the job posting is valid")" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.DATE" Variant="Variant.Outlined" Margin="Margin.Dense" UserAttributes="@USER_INPUT_ATTRIBUTES" Class="mb-3"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -8,8 +8,8 @@
@* Two zones, so no default target: the user has to aim at the one they mean. *@
<ReadFileContent Text="@T("Load the legal document from file")" @bind-FileContent="@this.inputLegalDocument" EnableDragDrop="true"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputLegalDocument" Validation="@this.ValidatingLegalDocument" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Legal document")" Variant="Variant.Outlined" Lines="12" Sizing="InputSizing.Auto" MaxLines="24" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputLegalDocument" Validation="@this.ValidatingLegalDocument" AdornmentIcon="@AppIcons.INPUT_TEXT" Adornment="Adornment.Start" Label="@T("Legal document")" Variant="Variant.Outlined" Lines="12" Sizing="InputSizing.Auto" MaxLines="24" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<ReadFileContent Text="@T("Load your questions from file")" @bind-FileContent="@this.inputQuestions" EnableDragDrop="true"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputQuestions" Validation="@this.ValidatingQuestions" AdornmentIcon="@Icons.Material.Filled.QuestionAnswer" Adornment="Adornment.Start" Label="@T("Your questions")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputQuestions" Validation="@this.ValidatingQuestions" AdornmentIcon="@AppIcons.QUESTIONS" Adornment="Adornment.Start" Label="@T("Your questions")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -16,18 +16,18 @@
<MudCheckBox T="bool" Value="@this.autoRefresh" ValueChanged="@this.AutoRefreshChanged" Label="@T("Auto-refresh")" Color="Color.Primary" />
@if (!this.autoRefresh)
{
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Refresh" OnClick="@this.RefreshLogAsync" Disabled="@this.isLoading">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.REFRESH" OnClick="@this.RefreshLogAsync" Disabled="@this.isLoading">
@T("Refresh")
</MudButton>
}
<MudNumericField T="int" Value="@this.maxLines" ValueChanged="@this.MaxLinesChanged" Label="@T("Max lines")" Variant="Variant.Outlined" Margin="Margin.Dense" Min="@MIN_MAX_LINES" Max="@MAX_MAX_LINES" Step="500" Class="log-viewer-number" />
<MudButton Variant="Variant.Outlined" Color="Color.Default" StartIcon="@Icons.Material.Filled.FolderOpen" OnClick="@this.OpenCurrentLogInFileManager" Disabled="@(!this.CanOpenCurrentLogPath)">
<MudButton Variant="Variant.Outlined" Color="Color.Default" StartIcon="@AppIcons.FOLDER_OPEN" OnClick="@this.OpenCurrentLogInFileManager" Disabled="@(!this.CanOpenCurrentLogPath)">
@T("Open in folder")
</MudButton>
</MudStack>
<MudStack Row="@true" Wrap="@Wrap.Wrap" AlignItems="@AlignItems.Center" Spacing="2" Class="mb-1">
<MudSelect T="string" Label="@T("Log level")" MultiSelection="@true" SelectedValues="@this.selectedLogLevels" SelectedValuesChanged="@this.SelectedLogLevelsChanged" MultiSelectionTextFunc="@this.GetMultiSelectionText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="log-viewer-multiselect" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Label">
<MudSelect T="string" Label="@T("Log level")" MultiSelection="@true" SelectedValues="@this.selectedLogLevels" SelectedValuesChanged="@this.SelectedLogLevelsChanged" MultiSelectionTextFunc="@this.GetMultiSelectionText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="log-viewer-multiselect" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LOG_LEVEL">
@foreach (var option in this.logLevelOptions)
{
<MudSelectItem T="string" Value="@option">
@@ -35,7 +35,7 @@
</MudSelectItem>
}
</MudSelect>
<MudSelect T="string" Label="@T("Logger")" MultiSelection="@true" SelectedValues="@this.selectedLoggers" SelectedValuesChanged="@this.SelectedLoggersChanged" MultiSelectionTextFunc="@this.GetMultiSelectionText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="log-viewer-multiselect" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Source">
<MudSelect T="string" Label="@T("Logger")" MultiSelection="@true" SelectedValues="@this.selectedLoggers" SelectedValuesChanged="@this.SelectedLoggersChanged" MultiSelectionTextFunc="@this.GetMultiSelectionText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="log-viewer-multiselect" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LOGGER">
@foreach (var option in this.loggerOptions)
{
<MudSelectItem T="string" Value="@option">
@@ -43,7 +43,7 @@
</MudSelectItem>
}
</MudSelect>
<MudSelect T="string" Label="@T("Source details")" MultiSelection="@true" SelectedValues="@this.selectedSourceDetails" SelectedValuesChanged="@this.SelectedSourceDetailsChanged" MultiSelectionTextFunc="@this.GetMultiSelectionText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="log-viewer-multiselect" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Settings">
<MudSelect T="string" Label="@T("Source details")" MultiSelection="@true" SelectedValues="@this.selectedSourceDetails" SelectedValuesChanged="@this.SelectedSourceDetailsChanged" MultiSelectionTextFunc="@this.GetMultiSelectionText" Variant="Variant.Outlined" Margin="Margin.Dense" Class="log-viewer-multiselect" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.LOG_SOURCE_DETAILS">
@foreach (var option in this.sourceDetailOptions)
{
<MudSelectItem T="string" Value="@option">
@@ -55,8 +55,8 @@
</MudStack>
<MudStack Row="@true" Wrap="@Wrap.Wrap" AlignItems="@AlignItems.Center" Spacing="2" Class="mb-1">
<MudTextField T="string" @bind-Text="@this.FilterText" Immediate="@true" Label="@T("Find")" Variant="Variant.Outlined" Margin="Margin.Dense" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" Class="log-viewer-filter" />
<MudButton Variant="Variant.Text" Color="Color.Default" StartIcon="@Icons.Material.Filled.Clear" Disabled="@(!this.HasActiveFilter)" OnClick="@this.ClearFilters">
<MudTextField T="string" @bind-Text="@this.FilterText" Immediate="@true" Label="@T("Find")" Variant="Variant.Outlined" Margin="Margin.Dense" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.SEARCH" Class="log-viewer-filter" />
<MudButton Variant="Variant.Text" Color="Color.Default" StartIcon="@AppIcons.CLEAR" Disabled="@(!this.HasActiveFilter)" OnClick="@this.ClearFilters">
@T("Clear")
</MudButton>
<MudCheckBox T="bool" @bind-Value="@this.FilterOnly" Label="@T("Filter only")" Color="Color.Primary" />
@@ -89,7 +89,7 @@
else if (this.displayLines.Count == 0)
{
<div class="log-viewer-empty">
<MudIcon Icon="@Icons.Material.Filled.SearchOff" />
<MudIcon Icon="@AppIcons.SEARCH_NO_RESULTS" />
<MudText Typo="Typo.body2">@T("No matching log lines.")</MudText>
</div>
}
@@ -212,7 +212,7 @@ public partial class AssistantLogViewer : MSGComponentBase
var path = this.CurrentLogPath;
if (string.IsNullOrWhiteSpace(path))
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Folder, T("The log file path is not available yet.")));
await this.MessageBus.SendWarning(new(AppIcons.FOLDER_OPEN, T("The log file path is not available yet.")));
return;
}
@@ -224,18 +224,18 @@ public partial class AssistantLogViewer : MSGComponentBase
catch (Exception e)
{
this.Logger.LogWarning(e, "Could not open the log file location in the file manager.");
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, T("Could not open the log file location.")));
await this.MessageBus.SendError(new(AppIcons.FOLDER_OPEN, T("Could not open the log file location.")));
return;
}
if (response.Success)
{
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.FolderOpen, T("Opened the log file location.")));
await this.MessageBus.SendSuccess(new(AppIcons.FOLDER_OPEN, T("Opened the log file location.")));
return;
}
var issue = string.IsNullOrWhiteSpace(response.Issue) ? T("Unknown error") : response.Issue;
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, string.Format(T("Could not open the log file location: {0}"), issue)));
await this.MessageBus.SendError(new(AppIcons.FOLDER_OPEN, string.Format(T("Could not open the log file location: {0}"), issue)));
}
private void ClearFilters()
@@ -2,7 +2,7 @@
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogMyTasks>
<ProfileFormSelection Validation="@this.ValidateProfile" @bind-Profile="@this.CurrentProfile"/>
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Text or email")" Variant="Variant.Outlined" Lines="12" Sizing="InputSizing.Auto" MaxLines="24" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@AppIcons.INPUT_TEXT" Adornment="Adornment.Start" Label="@T("Text or email")" Variant="Variant.Outlined" Lines="12" Sizing="InputSizing.Auto" MaxLines="24" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudText Typo="Typo.h6" Class="mb-1 mt-1">@T("Attach documents")</MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
@T("You can enter text, attach one or more documents, or use both. At least one input is required.")
@@ -10,5 +10,5 @@
<div class="mb-3">
<AttachDocuments Name="My Tasks Documents" @bind-DocumentPaths="@this.loadedDocumentPaths" OnChange="@this.OnDocumentsChanged" CatchAllDocuments="true" UseSmallForm="false" Provider="@this.ProviderSettings"/>
</div>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -7,7 +7,7 @@
<MudTextField T="string"
@bind-Text="@this.inputPrompt"
Validation="@this.ValidateInputPrompt"
AdornmentIcon="@Icons.Material.Filled.AutoFixHigh"
AdornmentIcon="@AppIcons.ASSISTANT_PROMPT_OPTIMIZER"
Adornment="Adornment.Start"
Label="@T("Prompt or prompt description")"
Variant="Variant.Outlined"
@@ -20,7 +20,7 @@
<EnumSelection T="CommonLanguages"
NameFunc="@(language => language.NameSelectingOptional)"
@bind-Value="@this.selectedTargetLanguage"
Icon="@Icons.Material.Filled.Translate"
Icon="@AppIcons.LANGUAGE"
Label="@T("Language for the optimized prompt")"
AllowOther="@true"
OtherValue="CommonLanguages.OTHER"
@@ -37,7 +37,7 @@
HelperText="@T("(Optional) Specify aspects the optimizer should emphasize in the resulting prompt, such as output structure, or constraints.")"
ShrinkLabel="true"
Variant="Variant.Outlined"
AdornmentIcon="@Icons.Material.Filled.List"
AdornmentIcon="@AppIcons.IMPORTANT_ASPECTS"
Adornment="Adornment.Start"/>
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-2">
@@ -90,7 +90,7 @@ else if (this.useCustomPromptGuide)
<MudStack Row="true" AlignItems="AlignItems.Center" Wrap="Wrap.Wrap" StretchItems="StretchItems.None" Class="mb-3">
<MudButton Variant="Variant.Outlined"
StartIcon="@Icons.Material.Filled.MenuBook"
StartIcon="@AppIcons.PROMPT_GUIDE"
OnClick="@(async () => await this.OpenPromptingGuidelineDialog())">
@T("View default prompt guide")
</MudButton>
@@ -109,7 +109,7 @@ else if (this.useCustomPromptGuide)
Style="min-width: 18rem;"/>
<MudButton Variant="Variant.Outlined"
StartIcon="@Icons.Material.Filled.Visibility"
StartIcon="@AppIcons.PREVIEW"
Disabled="@(!this.CanPreviewCustomPromptGuide)"
OnClick="@(async () => await this.OpenCustomPromptGuideDialog())">
@T("View")
@@ -105,7 +105,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
{
Text = T("Improve further"),
Tooltip = T("Moves the optimized prompt into the prompt field so you can optimize it again."),
Icon = Icons.Material.Filled.Input,
Icon = AppIcons.USE_AS_INPUT,
Color = Color.Default,
AsyncAction = this.UseOptimizedPromptAsInput,
DisabledActionParam = () => !this.CanImproveFurther,
@@ -626,7 +626,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
this.currentCustomPromptGuidePath = filePath;
if (replacedPrevious)
await this.MessageBus.SendInfo(new(Icons.Material.Filled.SwapHoriz, T("Replaced the previously selected custom prompt guide file.")));
await this.MessageBus.SendInfo(new(AppIcons.REPLACE, T("Replaced the previously selected custom prompt guide file.")));
}
private async Task LoadCustomPromptGuidelineContentAsync(FileAttachment fileAttachment)
@@ -634,7 +634,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
if (!fileAttachment.Exists)
{
this.customPromptingGuidelineContent = string.Empty;
await this.MessageBus.SendWarning(new(Icons.Material.Filled.FindInPage, T("The selected custom prompt guide file could not be found.")));
await this.MessageBus.SendWarning(new(AppIcons.FILE_NOT_FOUND, T("The selected custom prompt guide file could not be found.")));
return;
}
@@ -649,7 +649,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
catch
{
this.customPromptingGuidelineContent = string.Empty;
await this.MessageBus.SendError(new(Icons.Material.Filled.Description, T("Failed to load custom prompt guide content.")));
await this.MessageBus.SendError(new(AppIcons.DOCUMENT, T("Failed to load custom prompt guide content.")));
}
finally
{
@@ -663,7 +663,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
var promptingGuideline = await ReadPromptingGuidelineAsync();
if (string.IsNullOrWhiteSpace(promptingGuideline))
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.MenuBook, T("The prompting guideline file could not be loaded.")));
await this.MessageBus.SendWarning(new(AppIcons.PROMPT_GUIDE, T("The prompting guideline file could not be loaded.")));
return;
}
@@ -2,8 +2,8 @@
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogRewrite>
<ReadFileContent Text="@T("Load text from file")" @bind-FileContent="@this.inputText" EnableDragDrop="true" CatchAllDocuments="true"/>
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Your input to improve")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom language")" />
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name)" @bind-Value="@this.selectedWritingStyle" Icon="@Icons.Material.Filled.Edit" Label="@T("Writing style")" AllowOther="@false" />
<EnumSelection T="SentenceStructure" NameFunc="@(voice => voice.Name)" @bind-Value="@this.selectedSentenceStructure" Icon="@Icons.Material.Filled.Person4" Label="@T("Sentence structure")" />
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidateText" AdornmentIcon="@AppIcons.INPUT_TEXT" Adornment="Adornment.Start" Label="@T("Your input to improve")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom language")" />
<EnumSelection T="WritingStyles" NameFunc="@(style => style.Name)" @bind-Value="@this.selectedWritingStyle" Icon="@AppIcons.WRITING_STYLE" Label="@T("Writing style")" AllowOther="@false" />
<EnumSelection T="SentenceStructure" NameFunc="@(voice => voice.Name)" @bind-Value="@this.selectedSentenceStructure" Icon="@AppIcons.SENTENCE_STRUCTURE" Label="@T("Sentence structure")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -259,7 +259,7 @@ public partial class AssistantSWOTAnalysis
}
await this.MessageBus.SendWarning(new(
Icons.Material.Filled.CloudOff,
AppIcons.PROVIDER_ERROR,
T("The research with the selected tools failed. The SWOT analysis continues without it.")));
return string.Empty;
}
@@ -310,7 +310,7 @@ public partial class AssistantSWOTAnalysis
var imageCandidates = this.contextMaterials.OfType<FileAttachmentImage>().ToList();
if (imageCandidates.Count > 0 && !this.ProviderSettings.SupportsImageInput())
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.HideImage, T("The selected model cannot read images. The SWOT analysis continues without the attached images.")));
await this.MessageBus.SendWarning(new(AppIcons.IMAGE_NOT_SUPPORTED, T("The selected model cannot read images. The SWOT analysis continues without the attached images.")));
return new(documentText, images);
}
@@ -325,7 +325,7 @@ public partial class AssistantSWOTAnalysis
continue;
}
await this.MessageBus.SendError(new(Icons.Material.Filled.BrokenImage, prepared.ErrorCode.ToUserMessage(image.FileName)));
await this.MessageBus.SendError(new(AppIcons.IMAGE_BROKEN, prepared.ErrorCode.ToUserMessage(image.FileName)));
}
catch (OperationCanceledException) when (token.IsCancellationRequested)
{
@@ -334,7 +334,7 @@ public partial class AssistantSWOTAnalysis
catch (Exception exception)
{
this.Logger.LogError(exception, "The image '{FilePath}' could not be prepared for the SWOT analysis.", image.FilePath);
await this.MessageBus.SendError(new(Icons.Material.Filled.BrokenImage, string.Format(T("The image '{0}' could not be read and is left out of the SWOT analysis."), image.FileName)));
await this.MessageBus.SendError(new(AppIcons.IMAGE_BROKEN, string.Format(T("The image '{0}' could not be read and is left out of the SWOT analysis."), image.FileName)));
}
}
@@ -14,15 +14,15 @@
<MudText Typo="Typo.h5" Class="mb-3">
@T("Input")
</MudText>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Subject of analysis")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@AppIcons.INPUT_TEXT" Adornment="Adornment.Start" Label="@T("Subject of analysis")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<ReadFileContent @bind-FileContent="@this.inputText" MediaImportTargetId="swot-analysis-subject" EnableDragDrop="true" CatchAllDocuments="true"/>
<MudText Typo="Typo.h5" Class="mb-3 mt-6">
@T("Analysis Options")
</MudText>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.analysisGoal" Validation="@this.ValidatingAnalysisGoal" AdornmentIcon="@Icons.Material.Filled.TrackChanges" Adornment="Adornment.Start" Label="@T("Analysis goal")" Variant="Variant.Outlined" Lines="4" Sizing="InputSizing.Auto" Class="mb-3"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.analysisGoal" Validation="@this.ValidatingAnalysisGoal" AdornmentIcon="@AppIcons.ANALYSIS_GOAL" Adornment="Adornment.Start" Label="@T("Analysis goal")" Variant="Variant.Outlined" Lines="4" Sizing="InputSizing.Auto" Class="mb-3"/>
<ReadFileContent @bind-FileContent="@this.analysisGoal" MediaImportTargetId="swot-analysis-goal" EnableDragDrop="true"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.importantAspects" AdornmentIcon="@Icons.Material.Filled.List" Adornment="Adornment.Start" Label="@T("(Optional) Analysis focus")" HelperText="@T("Specify topics the SWOT analysis should pay particular attention to.")" Variant="Variant.Outlined" Lines="4" Sizing="InputSizing.Auto" Class="mb-3"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.importantAspects" AdornmentIcon="@AppIcons.IMPORTANT_ASPECTS" Adornment="Adornment.Start" Label="@T("(Optional) Analysis focus")" HelperText="@T("Specify topics the SWOT analysis should pay particular attention to.")" Variant="Variant.Outlined" Lines="4" Sizing="InputSizing.Auto" Class="mb-3"/>
<ReadFileContent @bind-FileContent="@this.importantAspects" MediaImportTargetId="swot-analysis-focus" EnableDragDrop="true"/>
<MudText Typo="Typo.h5" Class="mb-3 mt-6">
@@ -34,6 +34,6 @@
<AttachDocuments Name="SWOT Analysis Context Material" @bind-DocumentPaths="@this.contextMaterials" UseSmallForm="false" Provider="@this.ProviderSettings"/>
<div style="margin-top: 20px;">
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.selectedTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
</div>
@@ -43,7 +43,7 @@
}
@if (!string.IsNullOrWhiteSpace(this.pictureLibraryPath) && !this.IsPictureLibraryLocked)
{
<MudButton StartIcon="@Icons.Material.Filled.FolderOff" Variant="Variant.Outlined" OnClick="@this.UseNoPictureLibrary" Class="mb-3">
<MudButton StartIcon="@AppIcons.CLEAR_FOLDER" Variant="Variant.Outlined" OnClick="@this.UseNoPictureLibrary" Class="mb-3">
@T("Use no picture library")
</MudButton>
}
@@ -60,7 +60,7 @@
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
@T("You might want to specify important aspects that the LLM should consider when creating the slides. For example, the use of emojis or specific topics that should be highlighted.")
</MudJustifiedText>
<MudTextField T="string" Sizing="InputSizing.Auto" Lines="3" @bind-Text="@this.importantAspects" class="mb-1" Label="@T("(Optional) Important Aspects")" ShrinkLabel="true" Variant="Variant.Outlined" AdornmentIcon="@Icons.Material.Filled.List" Adornment="Adornment.Start" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" Sizing="InputSizing.Auto" Lines="3" @bind-Text="@this.importantAspects" class="mb-1" Label="@T("(Optional) Important Aspects")" ShrinkLabel="true" Variant="Variant.Outlined" AdornmentIcon="@AppIcons.IMPORTANT_ASPECTS" Adornment="Adornment.Start" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudText Typo="Typo.h6" Class="mb-1 mt-3"> @T("Extent of the planned presentation")</MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
@@ -95,22 +95,22 @@
</MudGrid>
<MudText Typo="Typo.h6" Class="mb-1 mt-3"> @T("Language")</MudText>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.selectedTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
<MudText Typo="Typo.h6" Class="mb-1 mt-3">@T("Occasion")</MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
@T("The occasion helps the LLM to structure the presentation. A lecture, for example, may close its chapters with an interim summary or with room for questions, and a report to management leads with the key messages.")
</MudJustifiedText>
<EnumSelection T="PresentationOccasion" NameFunc="@(occasion => occasion.Name)" @bind-Value="@this.selectedOccasion" Icon="@Icons.Material.Filled.Event" Label="@T("Occasion of the presentation")" AllowOther="@true" @bind-OtherInput="@this.customOccasion" OtherValue="PresentationOccasion.OTHER" LabelOther="@T("Other occasion")" ValidateOther="@this.ValidateCustomOccasion" />
<EnumSelection T="PresentationOccasion" NameFunc="@(occasion => occasion.Name)" @bind-Value="@this.selectedOccasion" Icon="@AppIcons.EVENT" Label="@T("Occasion of the presentation")" AllowOther="@true" @bind-OtherInput="@this.customOccasion" OtherValue="PresentationOccasion.OTHER" LabelOther="@T("Other occasion")" ValidateOther="@this.ValidateCustomOccasion" />
<MudText Typo="Typo.h6" Class="mb-1 mt-3"> @T("Audience")</MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
@T("Please specify the audience for the planned presentation. This will help the LLM to create a presentation that fits your needs. You can specify the audience profile, the age group, organizational level, and the expertise. You don't have to specify all of these parameters, for example you might only want to specify the audience profile and leave the other parameters at their default values.")
</MudJustifiedText>
<EnumSelection T="AudienceProfile" NameFunc="@(profile => profile.Name)" @bind-Value="@this.selectedAudienceProfile" Icon="@Icons.Material.Filled.Groups" Label="@T("Audience profile")" />
<EnumSelection T="AudienceAgeGroup" NameFunc="@(ageGroup => ageGroup.Name)" @bind-Value="@this.selectedAudienceAgeGroup" Icon="@Icons.Material.Filled.Cake" Label="@T("Audience age group")" />
<EnumSelection T="AudienceOrganizationalLevel" NameFunc="@(level => level.Name)" @bind-Value="@this.selectedAudienceOrganizationalLevel" Icon="@Icons.Material.Filled.AccountTree" Label="@T("Audience organizational level")" />
<EnumSelection T="AudienceExpertise" NameFunc="@(expertise => expertise.Name)" @bind-Value="@this.selectedAudienceExpertise" Icon="@Icons.Material.Filled.School" Label="@T("Audience expertise")" />
<EnumSelection T="AudienceProfile" NameFunc="@(profile => profile.Name)" @bind-Value="@this.selectedAudienceProfile" Icon="@AppIcons.AUDIENCE" Label="@T("Audience profile")" />
<EnumSelection T="AudienceAgeGroup" NameFunc="@(ageGroup => ageGroup.Name)" @bind-Value="@this.selectedAudienceAgeGroup" Icon="@AppIcons.AUDIENCE_AGE_GROUP" Label="@T("Audience age group")" />
<EnumSelection T="AudienceOrganizationalLevel" NameFunc="@(level => level.Name)" @bind-Value="@this.selectedAudienceOrganizationalLevel" Icon="@AppIcons.AUDIENCE_ORGANIZATIONAL_LEVEL" Label="@T("Audience organizational level")" />
<EnumSelection T="AudienceExpertise" NameFunc="@(expertise => expertise.Name)" @bind-Value="@this.selectedAudienceExpertise" Icon="@AppIcons.AUDIENCE_EXPERTISE" Label="@T("Audience expertise")" />
<MudText Typo="Typo.h5" Class="mb-1 mt-6"> @T("PowerPoint template")</MudText>
<MudJustifiedText Typo="Typo.body1" Class="mb-2">
@@ -126,7 +126,7 @@
}
@if (!string.IsNullOrWhiteSpace(this.templatePath) && !this.IsTemplateLocked)
{
<MudButton StartIcon="@Icons.Material.Filled.LayersClear" Variant="Variant.Outlined" OnClick="@this.UseNoTemplate" Class="mb-3">
<MudButton StartIcon="@AppIcons.NO_TEMPLATE" Variant="Variant.Outlined" OnClick="@this.UseNoTemplate" Class="mb-3">
@T("Use no template")
</MudButton>
}
@@ -134,10 +134,10 @@
@* The select renders its items again on its own, e.g., while the form validates, when the template may be gone already: *@
@if (this.template is { } loadedTemplate)
{
<CompactExpansionPanel HeaderText="@T("Advanced Options")" HeaderIcon="@Icons.Material.Filled.Tune" Class="mb-3 rounded" @bind-Expanded="@this.advancedOptionsExpanded">
<CompactExpansionPanel HeaderText="@T("Advanced Options")" HeaderIcon="@AppIcons.ADVANCED_SETTINGS" Class="mb-3 rounded" @bind-Expanded="@this.advancedOptionsExpanded">
@if (loadedTemplate.VariantLabels.Count > 0)
{
<MudSelect T="string" @bind-Value="@this.variantLabel" Label="@T("Color variant")" HelperText="@T("Your template offers its layouts in several colors. Choose one for the presentation.")" Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Palette" Class="mb-3">
<MudSelect T="string" @bind-Value="@this.variantLabel" Label="@T("Color variant")" HelperText="@T("Your template offers its layouts in several colors. Choose one for the presentation.")" Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.COLOR" Class="mb-3">
@foreach (var label in loadedTemplate.VariantLabels)
{
<MudSelectItem T="string" Value="@label">@label</MudSelectItem>
@@ -145,7 +145,7 @@
</MudSelect>
}
<MudTextField T="string" @bind-Text="@this.footerText" Label="@T("(Optional) Footer")" HelperText="@T("Shown on every slide whose layout has a footer, e.g., your name, organization, and date.")" Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ShortText" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.footerText" Label="@T("(Optional) Footer")" HelperText="@T("Shown on every slide whose layout has a footer, e.g., your name, organization, and date.")" Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.SLIDE_FOOTER" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudSwitch T="bool" @bind-Value="@this.keepEmptyPicturePlaceholders" Color="Color.Primary" Class="mx-1">
@T("Keep empty picture placeholders")
@@ -160,7 +160,7 @@
</MudJustifiedText>
<LayoutChoicePanels IsChosen="@(purpose => this.LayoutNameOf(purpose).Length > 0)">
<ChoiceContent Context="purpose">
<MudSelect T="string" Value="@this.LayoutNameOf(purpose)" ValueChanged="@(name => this.SetLayoutName(purpose, name))" Disabled="@this.AreLayoutsLocked" Label="@purpose.Label" HelperText="@purpose.Help" Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.ViewQuilt" Class="mb-3">
<MudSelect T="string" Value="@this.LayoutNameOf(purpose)" ValueChanged="@(name => this.SetLayoutName(purpose, name))" Disabled="@this.AreLayoutsLocked" Label="@purpose.Label" HelperText="@purpose.Help" Variant="Variant.Outlined" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.SLIDE_LAYOUT" Class="mb-3">
<MudSelectItem T="string" Value="@string.Empty">@LayoutPurposeExtensions.NoPreference</MudSelectItem>
@foreach (var layoutName in loadedTemplate.FamilyNames)
{
@@ -178,7 +178,7 @@
</MudJustifiedText>
@foreach (var templateSlide in loadedTemplate.Slides)
{
<EnumSelection T="TemplateSlideUse" NameFunc="@(use => use.Name)" Value="@this.TemplateSlideUseOf(templateSlide.Number)" ValueChanged="@(use => this.SetTemplateSlideUse(templateSlide.Number, use))" ValidateSelection="@(use => this.ValidateTemplateSlideUse(templateSlide, use))" Disabled="@this.AreTemplateSlideUsesLocked" Icon="@Icons.Material.Filled.Slideshow" Label="@templateSlide.Label"/>
<EnumSelection T="TemplateSlideUse" NameFunc="@(use => use.Name)" Value="@this.TemplateSlideUseOf(templateSlide.Number)" ValueChanged="@(use => this.SetTemplateSlideUse(templateSlide.Number, use))" ValidateSelection="@(use => this.ValidateTemplateSlideUse(templateSlide, use))" Disabled="@this.AreTemplateSlideUsesLocked" Icon="@AppIcons.SLIDES" Label="@templateSlide.Label"/>
}
}
</CompactExpansionPanel>
@@ -574,7 +574,7 @@ public partial class SlideAssistant
if (!result.IsWritten)
{
this.Logger.LogWarning("The PowerPoint template '{TemplatePath}' changed since the slides were planned, and they no longer fit it.", this.slideDeckTemplatePath);
await this.MessageBus.SendError(new(Icons.Material.Filled.Slideshow, T("The template has changed since the slides were planned. Please create the slides again.")));
await this.MessageBus.SendError(new(AppIcons.SLIDES, T("The template has changed since the slides were planned. Please create the slides again.")));
return;
}
@@ -583,15 +583,15 @@ public partial class SlideAssistant
if (result.SkippedPictures.Count > 0)
{
var names = result.SkippedPictures.Select(number => this.slideDeckPicturePaths.TryGetValue(number, out var picturePath) ? Path.GetFileName(picturePath) : number.ToString(CultureInfo.InvariantCulture));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.HideImage, string.Format(T("These pictures could not be placed, because PowerPoint cannot show their format or they cannot be read: {0}"), string.Join(", ", names))));
await this.MessageBus.SendWarning(new(AppIcons.IMAGE_NOT_SUPPORTED, string.Format(T("These pictures could not be placed, because PowerPoint cannot show their format or they cannot be read: {0}"), string.Join(", ", names))));
}
await feedback.SucceededAsync(Icons.Material.Filled.Slideshow, T("The PowerPoint file was created."), targetPath, true);
await feedback.SucceededAsync(AppIcons.SLIDES, T("The PowerPoint file was created."), targetPath, true);
}
catch (Exception e)
{
this.Logger.LogError(e, "Creating the PowerPoint file '{FilePath}' failed.", targetPath);
await this.MessageBus.SendError(new(Icons.Material.Filled.Slideshow, T("The PowerPoint file could not be created. Please check that the template can be read and that the target file is not open in another program.")));
await this.MessageBus.SendError(new(AppIcons.SLIDES, T("The PowerPoint file could not be created. Please check that the template can be read and that the target file is not open in another program.")));
}
finally
{
@@ -148,7 +148,7 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
protected override IReadOnlyList<IButtonData> FooterButtons =>
[
new ButtonData(T("Create PowerPoint file"), Icons.Material.Filled.Slideshow, Color.Default, this.CreatePresentationTooltip, this.CreatePresentationFileAsync, () => !this.CanCreatePresentation),
new ButtonData(T("Create PowerPoint file"), AppIcons.SLIDES, Color.Default, this.CreatePresentationTooltip, this.CreatePresentationFileAsync, () => !this.CanCreatePresentation),
];
//
@@ -491,7 +491,7 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
return;
this.loadedDocumentPaths.ExceptWith(displaced);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Warning, string.Format(T("These files are already attached as pictures for the slides and were removed from the documents: {0}"), string.Join(", ", displaced.Select(document => document.FileName)))));
await this.MessageBus.SendWarning(new(AppIcons.WARNING, string.Format(T("These files are already attached as pictures for the slides and were removed from the documents: {0}"), string.Join(", ", displaced.Select(document => document.FileName)))));
}
private string? ValidateCustomLanguage(string language)
@@ -596,21 +596,21 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
if (!extraction.HasUsableContent)
{
this.Logger.LogError("Reading the document '{FilePath}' failed and it will not be used: code={ErrorCode}, message='{ErrorMessage}'.", document.FilePath, extraction.ErrorCode, extraction.ErrorMessage);
await this.MessageBus.SendError(new(Icons.Material.Filled.Description, extraction.ToUserMessage(document.FileName)));
await this.MessageBus.SendError(new(AppIcons.DOCUMENT, extraction.ToUserMessage(document.FileName)));
continue;
}
if (extraction.Outcome is FileExtractionOutcome.PARTIAL)
{
this.Logger.LogWarning("Parts of the document '{FilePath}' could not be read: pages={FailedPages}.", document.FilePath, string.Join(", ", extraction.FailedPages));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Description, extraction.ToPartialUserMessage(document.FileName)));
await this.MessageBus.SendWarning(new(AppIcons.DOCUMENT, extraction.ToPartialUserMessage(document.FileName)));
}
// The file was read correctly, but its extension lies about what it contains:
if (extraction.HasExtensionMismatch)
{
this.Logger.LogWarning("The document '{FilePath}' is actually a '{DetectedFormat}'.", document.FilePath, extraction.DetectedFormat);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.RuleFolder, extraction.ToExtensionMismatchUserMessage(document.FileName)));
await this.MessageBus.SendWarning(new(AppIcons.FILE_TYPE_MISMATCH, extraction.ToExtensionMismatchUserMessage(document.FileName)));
}
var fileContent = extraction.Content;
@@ -777,14 +777,14 @@ public partial class SlideAssistant : AssistantBaseCore<SettingsDialogSlideBuild
if (deck is null || deck.Slides.Count == 0 || deck.Slides.Any(slide => !SlideDeckSpecValidator.CanWrite(slide, catalog, chosenTemplateSlideUses)))
{
this.Logger.LogWarning("The slides the model planned cannot be used: {Issues}", string.Join(" | ", issues));
await this.MessageBus.SendError(new(Icons.Material.Filled.Slideshow, T("The LLM did not describe the slides in a usable form, even after a second request. Please try again, or choose another model.")));
await this.MessageBus.SendError(new(AppIcons.SLIDES, T("The LLM did not describe the slides in a usable form, even after a second request. Please try again, or choose another model.")));
return;
}
if (issues.Count > 0)
{
this.Logger.LogInformation("The slides the model planned still have issues after the repair round: {Issues}", string.Join(" | ", issues));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Slideshow, T("Not every slide fits its layout as planned; for example, a text may run long. Please check the slides before presenting.")));
await this.MessageBus.SendWarning(new(AppIcons.SLIDES, T("Not every slide fits its layout as planned; for example, a text may run long. Please check the slides before presenting.")));
}
this.slideDeck = deck;
@@ -1,8 +1,8 @@
@attribute [Route(Routes.ASSISTANT_SYNONYMS)]
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogSynonyms>
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.Spellcheck" Adornment="Adornment.Start" Label="@T("Your word or phrase")" Variant="Variant.Outlined" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.inputContext" AdornmentIcon="@Icons.Material.Filled.Description" Adornment="Adornment.Start" Lines="2" Sizing="InputSizing.Fixed" Label="@T("(Optional) The context for the given word or phrase")" Variant="Variant.Outlined" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@AppIcons.WORD_OR_PHRASE" Adornment="Adornment.Start" Label="@T("Your word or phrase")" Variant="Variant.Outlined" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" @bind-Text="@this.inputContext" AdornmentIcon="@AppIcons.DESCRIPTION" Adornment="Adornment.Start" Lines="2" Sizing="InputSizing.Fixed" Label="@T("(Optional) The context for the given word or phrase")" Variant="Variant.Outlined" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelectingOptional)" @bind-Value="@this.selectedLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -7,8 +7,8 @@
}
<ReadFileContent @bind-FileContent="@this.inputText" EnableDragDrop="true" CatchAllDocuments="true"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Your input")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.selectedTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
<EnumSelection T="Complexity" NameFunc="@(complexity => complexity.Name)" @bind-Value="@this.selectedComplexity" Icon="@Icons.Material.Filled.Layers" Label="@T("Target complexity")" AllowOther="@true" @bind-OtherInput="@this.expertInField" OtherValue="Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS" LabelOther="@T("Your expertise")" ValidateOther="@this.ValidateExpertInField" />
<MudTextField T="string" Sizing="InputSizing.Auto" Lines="2" @bind-Text="@this.importantAspects" class="mb-3" Label="@T("(Optional) Important Aspects")" HelperText="@T("(Optional) Specify aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.")" ShrinkLabel="true" Variant="Variant.Outlined" AdornmentIcon="@Icons.Material.Filled.List" Adornment="Adornment.Start"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@AppIcons.INPUT_TEXT" Adornment="Adornment.Start" Label="@T("Your input")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.selectedTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" @bind-OtherInput="@this.customTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomLanguage" />
<EnumSelection T="Complexity" NameFunc="@(complexity => complexity.Name)" @bind-Value="@this.selectedComplexity" Icon="@AppIcons.TEXT_COMPLEXITY" Label="@T("Target complexity")" AllowOther="@true" @bind-OtherInput="@this.expertInField" OtherValue="Complexity.SCIENTIFIC_LANGUAGE_OTHER_EXPERTS" LabelOther="@T("Your expertise")" ValidateOther="@this.ValidateExpertInField" />
<MudTextField T="string" Sizing="InputSizing.Auto" Lines="2" @bind-Text="@this.importantAspects" class="mb-3" Label="@T("(Optional) Important Aspects")" HelperText="@T("(Optional) Specify aspects for the LLM to focus on when generating a summary, such as summary length or specific topics to emphasize.")" ShrinkLabel="true" Variant="Variant.Outlined" AdornmentIcon="@AppIcons.IMPORTANT_ASPECTS" Adornment="Adornment.Start"/>
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -11,12 +11,12 @@
<MudTextSwitch Label="@T("Live translation")" @bind-Value="@this.liveTranslation" LabelOn="@T("Live translation")" LabelOff="@T("No live translation")"/>
@if (this.liveTranslation)
{
<DebouncedTextField Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" ValidationFunc="@this.ValidatingText" Icon="@Icons.Material.Filled.DocumentScanner" Label="@T("Your input")" Lines="6" MaxLines="12" DebounceTime="@TimeSpan.FromMilliseconds(this.SettingsManager.ConfigurationData.Translation.DebounceIntervalMilliseconds)" WhenTextChangedAsync="async _ => await this.TranslateText(force: false)" Attributes="@USER_INPUT_ATTRIBUTES"/>
<DebouncedTextField Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" ValidationFunc="@this.ValidatingText" Icon="@AppIcons.INPUT_TEXT" Label="@T("Your input")" Lines="6" MaxLines="12" DebounceTime="@TimeSpan.FromMilliseconds(this.SettingsManager.ConfigurationData.Translation.DebounceIntervalMilliseconds)" WhenTextChangedAsync="async _ => await this.TranslateText(force: false)" Attributes="@USER_INPUT_ATTRIBUTES"/>
}
else
{
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@Icons.Material.Filled.DocumentScanner" Adornment="Adornment.Start" Label="@T("Your input")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
<MudTextField T="string" Disabled="@this.isAgentRunning" @bind-Text="@this.inputText" Validation="@this.ValidatingText" AdornmentIcon="@AppIcons.INPUT_TEXT" Adornment="Adornment.Start" Label="@T("Your input")" Variant="Variant.Outlined" Lines="6" Sizing="InputSizing.Auto" MaxLines="12" Class="mb-3" UserAttributes="@USER_INPUT_ATTRIBUTES"/>
}
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidatingTargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.NameSelecting)" @bind-Value="@this.selectedTargetLanguage" ValidateSelection="@this.ValidatingTargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="@true" OtherValue="CommonLanguages.OTHER" @bind-OtherInput="@this.customTargetLanguage" ValidateOther="@this.ValidateCustomLanguage" LabelOther="@T("Custom target language")" />
<ProviderSelection @bind-ProviderSettings="@this.ProviderSettings" ValidateProvider="@this.ValidatingProvider"/>
@@ -14,7 +14,7 @@
<MudStack Row="true" AlignItems="AlignItems.Center" Class="mb-3 mr-3" StretchItems="StretchItems.Start">
<MudText Typo="Typo.h3">@T("Visual Briefings")</MudText>
<MudSpacer/>
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" OnClick="@this.OpenSettingsDialogAsync"/>
<MudIconButton Variant="Variant.Text" Icon="@AppIcons.SETTINGS" OnClick="@this.OpenSettingsDialogAsync"/>
</MudStack>
<InnerScrolling>
@@ -25,7 +25,7 @@
SelectedValueChanged="@this.SelectBriefingAsync">
@foreach (var project in this.projects)
{
<MudListItem T="Guid" @key="project.BriefingId" Value="@project.BriefingId" Icon="@(project.IsAvailable ? Icons.Material.Filled.Dashboard : Icons.Material.Filled.WarningAmber)">
<MudListItem T="Guid" @key="project.BriefingId" Value="@project.BriefingId" Icon="@(project.IsAvailable ? AppIcons.ASSISTANT_VISUAL_BRIEFING : AppIcons.WARNING)">
<MudStack Spacing="0">
<MudText Typo="Typo.body1">@this.ProjectDisplayName(project)</MudText>
<MudText Typo="Typo.caption">@project.ModifiedAtUtc.ToLocalTime().ToString("g")</MudText>
@@ -47,8 +47,8 @@
</MudList>
<MudStack Row="true" Spacing="1" Class="mt-1" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add" OnClick="@this.CreateBriefingAsync">@T("New briefing")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.FileUpload" OnClick="@this.ImportAsync">@T("Import")</MudButton>
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@AppIcons.ADD" OnClick="@this.CreateBriefingAsync">@T("New briefing")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.IMPORT" OnClick="@this.ImportAsync">@T("Import")</MudButton>
</MudStack>
<MudDivider Style="height: 0.25ch; margin: 1rem 0;" Class="mt-6"/>
@@ -72,8 +72,8 @@
<MudLink Href="https://github.com/MindWorkAI/AI-Studio" Target="_blank">@T("Report a problem?")</MudLink>
</MudText>
<MudStack Row="true" Spacing="1" Wrap="Wrap.Wrap">
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.FolderOpen" OnClick="@this.OpenSelectedProjectDirectoryAsync">@T("Open project folder")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.DeleteForever" Color="Color.Error" OnClick="@this.DeleteAsync">@T("Delete")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.FOLDER_OPEN" OnClick="@this.OpenSelectedProjectDirectoryAsync">@T("Open project folder")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.DELETE" Color="Color.Error" OnClick="@this.DeleteAsync">@T("Delete")</MudButton>
</MudStack>
</MudStack>
</MudPaper>
@@ -90,8 +90,8 @@
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center" Wrap="Wrap.Wrap" Class="mb-3">
<MudText Typo="Typo.h4">@this.editor.Name</MudText>
<MudStack Row="true" Spacing="1">
<MudButton StartIcon="@Icons.Material.Filled.DriveFileRenameOutline" OnClick="@this.RenameAsync" Disabled="@this.IsCurrentBusy">@T("Rename")</MudButton>
<MudButton StartIcon="@Icons.Material.Filled.DeleteForever" Color="Color.Error" OnClick="@this.DeleteAsync" Disabled="@this.IsCurrentBusy">@T("Delete")</MudButton>
<MudButton StartIcon="@AppIcons.RENAME" OnClick="@this.RenameAsync" Disabled="@this.IsCurrentBusy">@T("Rename")</MudButton>
<MudButton StartIcon="@AppIcons.DELETE" Color="Color.Error" OnClick="@this.DeleteAsync" Disabled="@this.IsCurrentBusy">@T("Delete")</MudButton>
</MudStack>
</MudStack>
@@ -109,7 +109,7 @@
<EnumSelection T="VisualBriefingProtectionLevel"
NameFunc="@this.ProtectionLevelName"
@bind-Value="@this.editor.ProtectionLevel"
Icon="@Icons.Material.Filled.Security"
Icon="@AppIcons.PROTECTION_LEVEL"
Label="@T("Protection level")"
AllowOther="true"
OtherValue="VisualBriefingProtectionLevel.OTHER"
@@ -156,7 +156,7 @@
<MudPaper Outlined="true" Class="pa-4 mb-4">
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween" Class="mb-2">
<MudText Typo="Typo.h5">@T("Linked sources")</MudText>
<MudButton StartIcon="@Icons.Material.Filled.Refresh" OnClick="@this.RefreshSourceStatusAsync" Disabled="@this.IsCurrentBusy">@T("Refresh status")</MudButton>
<MudButton StartIcon="@AppIcons.REFRESH" OnClick="@this.RefreshSourceStatusAsync" Disabled="@this.IsCurrentBusy">@T("Refresh status")</MudButton>
</MudStack>
<MudTable Items="@this.selectedBriefing.Sources" Dense="true" Hover="true" Breakpoint="Breakpoint.Sm">
<HeaderContent>
@@ -173,16 +173,16 @@
</MudTd>
<MudTd DataLabel="@T("Actions")">
<MudTooltip Text="@T("Relink")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Link" OnClick="@(() => this.RelinkAsync(context))" Disabled="@this.IsCurrentBusy"/>
<MudIconButton Icon="@AppIcons.RELINK" OnClick="@(() => this.RelinkAsync(context))" Disabled="@this.IsCurrentBusy"/>
</MudTooltip>
@if (context.IsMedia && context.Status is VisualBriefingSourceStatus.TRANSCRIPT_OUTDATED)
{
<MudTooltip Text="@T("Transcribe again")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.RecordVoiceOver" OnClick="@(() => this.RetranscribeAsync(context))" Disabled="@this.IsCurrentBusy"/>
<MudIconButton Icon="@AppIcons.RETRANSCRIBE" OnClick="@(() => this.RetranscribeAsync(context))" Disabled="@this.IsCurrentBusy"/>
</MudTooltip>
}
<MudTooltip Text="@T("Remove")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.RemoveCircle" Color="Color.Error" OnClick="@(() => this.RemoveSourceAsync(context))" Disabled="@this.IsCurrentBusy"/>
<MudIconButton Icon="@AppIcons.REMOVE" Color="Color.Error" OnClick="@(() => this.RemoveSourceAsync(context))" Disabled="@this.IsCurrentBusy"/>
</MudTooltip>
</MudTd>
</RowTemplate>
@@ -215,7 +215,7 @@
</MudStack>
<ProfileFormSelection @bind-Profile="@this.editor.Profile" Disabled="@this.IsCurrentBusy"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.editor.TargetLanguage" Icon="@Icons.Material.Filled.Translate" Label="@T("Target language")" AllowOther="true" @bind-OtherInput="@this.editor.CustomTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomTargetLanguage" SelectionUpdated="@(_ => this.ScheduleFormValidation())" Disabled="@this.IsCurrentBusy"/>
<EnumSelection T="CommonLanguages" NameFunc="@(language => language.Name)" @bind-Value="@this.editor.TargetLanguage" Icon="@AppIcons.LANGUAGE" Label="@T("Target language")" AllowOther="true" @bind-OtherInput="@this.editor.CustomTargetLanguage" OtherValue="CommonLanguages.OTHER" LabelOther="@T("Custom target language")" ValidateOther="@this.ValidateCustomTargetLanguage" SelectionUpdated="@(_ => this.ScheduleFormValidation())" Disabled="@this.IsCurrentBusy"/>
<EnumSelection T="AudienceProfile" NameFunc="@(value => value.Name)" @bind-Value="@this.editor.AudienceProfile" Label="@T("Audience profile")" Disabled="@this.IsCurrentBusy"/>
<EnumSelection T="AudienceAgeGroup" NameFunc="@(value => value.Name)" @bind-Value="@this.editor.AudienceAgeGroup" Label="@T("Audience age group")" Disabled="@this.IsCurrentBusy"/>
<EnumSelection T="AudienceOrganizationalLevel" NameFunc="@(value => value.Name)" @bind-Value="@this.editor.AudienceOrganizationalLevel" Label="@T("Audience organizational level")" Disabled="@this.IsCurrentBusy"/>
@@ -227,30 +227,30 @@
<MudStack Row="true" Spacing="2" Wrap="Wrap.Wrap" Class="mb-4">
@if (this.selectedBriefing.Versions.Count == 0)
{
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.AutoAwesome" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.INITIAL))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.INITIAL)" Style="@this.ConfidenceBorderStyle">@T("Create briefing")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.GENERATE" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.INITIAL))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.INITIAL)" Style="@this.ConfidenceBorderStyle">@T("Create briefing")</MudButton>
}
else
{
<MudTooltip Text="@T("Creates a new version with a different design while keeping the current structure, content, and visual assets.")">
<span>
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Palette" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.CHANGE_DESIGN))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.CHANGE_DESIGN)" Style="@this.ConfidenceBorderStyle">@T("Change design")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.REDESIGN" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.CHANGE_DESIGN))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.CHANGE_DESIGN)" Style="@this.ConfidenceBorderStyle">@T("Change design")</MudButton>
</span>
</MudTooltip>
<MudTooltip Text="@T("Creates a new version from the current sources and instructions while keeping the current structure and design.")">
<span>
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Update" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.UPDATE_CONTENT))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.UPDATE_CONTENT)" Style="@this.ConfidenceBorderStyle">@T("Update content")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.UPDATE_CONTENT" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.UPDATE_CONTENT))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.UPDATE_CONTENT)" Style="@this.ConfidenceBorderStyle">@T("Update content")</MudButton>
</span>
</MudTooltip>
<MudTooltip Text="@T("Creates a new version from the current sources and instructions. The structure, content, and design may all change.")">
<span>
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.AutoAwesome" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.REBUILD))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.REBUILD)" Style="@this.ConfidenceBorderStyle">@T("Rebuild briefing")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.GENERATE" OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.REBUILD))" Disabled="@this.CannotGenerate(VisualBriefingEditMode.REBUILD)" Style="@this.ConfidenceBorderStyle">@T("Rebuild briefing")</MudButton>
</span>
</MudTooltip>
<MudTooltip Text="@(this.SelectedVersionSupportsEdits
? T("Recompile this version with the current AI Studio version without AI model calls.")
: T("This version has no compatible semantic artifacts. Rebuild the briefing instead."))">
<span>
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Filled.Code" OnClick="@(() => this.RecompileAsync())" Disabled="@this.CannotRecompile">@T("Recompile briefing")</MudButton>
<MudButton Variant="Variant.Filled" StartIcon="@AppIcons.RECOMPILE" OnClick="@(() => this.RecompileAsync())" Disabled="@this.CannotRecompile">@T("Recompile briefing")</MudButton>
</span>
</MudTooltip>
}
@@ -258,7 +258,7 @@
{
<MudButton Variant="Variant.Filled"
Color="Color.Error"
StartIcon="@Icons.Material.Filled.Stop"
StartIcon="@AppIcons.STOP"
OnClick="@this.CancelCurrentBuildAsync"
Disabled="@this.IsCurrentBuildCanceling">
@(this.IsCurrentBuildCanceling ? T("Stopping build...") : T("Stop build"))
@@ -281,7 +281,7 @@
<MudText>@T("The updated content no longer fits the current presentation. You can continue as a rebuild without another content model call.")</MudText>
<MudButton Variant="Variant.Filled"
Color="Color.Warning"
StartIcon="@Icons.Material.Filled.Refresh"
StartIcon="@AppIcons.REGENERATE"
OnClick="@(() => this.GenerateAsync(VisualBriefingEditMode.REBUILD, reusableBuildId))"
Disabled="@this.CannotGenerate(VisualBriefingEditMode.REBUILD)">
@T("Continue as rebuild")
@@ -293,7 +293,7 @@
@if (this.lastBuildDiagnostics is not null)
{
<MudButton Variant="Variant.Text"
StartIcon="@Icons.Material.Filled.ContentCopy"
StartIcon="@AppIcons.COPY"
OnClick="@this.CopyTechnicalDetailsAsync"
Class="mb-4">
@T("Copy technical details")
@@ -305,23 +305,23 @@
<MudPaper Outlined="true" Class="pa-3">
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.SpaceBetween" Wrap="Wrap.Wrap" Class="mb-3">
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIconButton Icon="@Icons.Material.Filled.ArrowBack" OnClick="@this.PreviousVersionAsync" Disabled="@(!this.CanGoBackward)"/>
<MudIconButton Icon="@AppIcons.PREVIOUS" OnClick="@this.PreviousVersionAsync" Disabled="@(!this.CanGoBackward)"/>
<MudSelect T="Guid" Value="@this.selectedRevisionId" ValueChanged="@this.SelectRevisionAsync" Label="@T("Version")" Dense="true">
@foreach (var version in this.selectedBriefing.Versions.OrderByDescending(version => version.VersionNumber))
{
<MudSelectItem Value="@version.RevisionId">@($"v{version.VersionNumber} · {version.EditMode} · {version.CreatedAtUtc.ToLocalTime():g}")</MudSelectItem>
}
</MudSelect>
<MudIconButton Icon="@Icons.Material.Filled.ArrowForward" OnClick="@this.NextVersionAsync" Disabled="@(!this.CanGoForward)"/>
<MudIconButton Icon="@AppIcons.NEXT" OnClick="@this.NextVersionAsync" Disabled="@(!this.CanGoForward)"/>
</MudStack>
<MudStack Row="true" Spacing="1">
<MudToggleGroup T="VisualBriefingPreviewDevice" @bind-Value="@this.previewDevice" SelectionMode="SelectionMode.SingleSelection" Color="Color.Primary">
@* MudToggleItem has no Icon parameter; the icon has to be set for both states. *@
<MudToggleItem Value="@VisualBriefingPreviewDevice.DESKTOP" SelectedIcon="@Icons.Material.Filled.DesktopWindows" UnselectedIcon="@Icons.Material.Filled.DesktopWindows"/>
<MudToggleItem Value="@VisualBriefingPreviewDevice.TABLET" SelectedIcon="@Icons.Material.Filled.Tablet" UnselectedIcon="@Icons.Material.Filled.Tablet"/>
<MudToggleItem Value="@VisualBriefingPreviewDevice.MOBILE" SelectedIcon="@Icons.Material.Filled.PhoneIphone" UnselectedIcon="@Icons.Material.Filled.PhoneIphone"/>
<MudToggleItem Value="@VisualBriefingPreviewDevice.DESKTOP" SelectedIcon="@AppIcons.DEVICE_DESKTOP" UnselectedIcon="@AppIcons.DEVICE_DESKTOP"/>
<MudToggleItem Value="@VisualBriefingPreviewDevice.TABLET" SelectedIcon="@AppIcons.PREVIEW_DEVICE_TABLET" UnselectedIcon="@AppIcons.PREVIEW_DEVICE_TABLET"/>
<MudToggleItem Value="@VisualBriefingPreviewDevice.MOBILE" SelectedIcon="@AppIcons.DEVICE_MOBILE" UnselectedIcon="@AppIcons.DEVICE_MOBILE"/>
</MudToggleGroup>
<MudButton StartIcon="@Icons.Material.Filled.SaveAlt" OnClick="@this.ExportAsync">@T("Export")</MudButton>
<MudButton StartIcon="@AppIcons.EXPORT" OnClick="@this.ExportAsync">@T("Export")</MudButton>
</MudStack>
</MudStack>
<div class="@this.PreviewContainerClass">
@@ -105,7 +105,7 @@ public partial class VisualBriefingAssistant
// derived from the stable enums in the current language instead:
terminalIssue = VisualBriefingFailureExtensions.ToUserMessage(result.FailureCode, result.Diagnostics.ValidationRule);
if (terminalStatus is not AssistantSessionStatus.CANCELED)
await this.MessageBus.SendError(new(Icons.Material.Filled.AutoAwesome, terminalIssue));
await this.MessageBus.SendError(new(AppIcons.GENERATE, terminalIssue));
return;
}
@@ -123,7 +123,7 @@ public partial class VisualBriefingAssistant
this.UpdateProject(latest);
}
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.AutoAwesome, successMessage));
await this.MessageBus.SendSuccess(new(AppIcons.GENERATE, successMessage));
terminalStatus = AssistantSessionStatus.COMPLETED;
}
catch (OperationCanceledException)
@@ -135,7 +135,7 @@ public partial class VisualBriefingAssistant
{
terminalIssue = unexpectedFailureMessage;
this.Logger.LogError("Unexpected visual briefing UI failure. BriefingId={BriefingId} Mode={Mode} ExceptionType={ExceptionType}", briefingId, mode, exception.GetType().Name);
await this.MessageBus.SendError(new(Icons.Material.Filled.AutoAwesome, terminalIssue));
await this.MessageBus.SendError(new(AppIcons.GENERATE, terminalIssue));
}
finally
{
@@ -166,7 +166,7 @@ public partial class VisualBriefingAssistant
var path = await this.Store.GetProjectDirectoryPathAsync(this.selectedProject.BriefingId);
if (string.IsNullOrWhiteSpace(path))
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Folder, T("The visual briefing project folder is not available.")));
await this.MessageBus.SendWarning(new(AppIcons.FOLDER_OPEN, T("The visual briefing project folder is not available.")));
return;
}
@@ -178,18 +178,18 @@ public partial class VisualBriefingAssistant
catch (Exception exception)
{
this.Logger.LogWarning(exception, "Could not open the visual briefing project folder. BriefingId={BriefingId}", this.selectedProject.BriefingId);
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, T("Could not open the visual briefing project folder.")));
await this.MessageBus.SendError(new(AppIcons.FOLDER_OPEN, T("Could not open the visual briefing project folder.")));
return;
}
if (response.Success)
{
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.Folder, T("Opened the visual briefing project folder.")));
await this.MessageBus.SendSuccess(new(AppIcons.FOLDER_OPEN, T("Opened the visual briefing project folder.")));
return;
}
var issue = string.IsNullOrWhiteSpace(response.Issue) ? T("Unknown error") : response.Issue;
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, string.Format(T("Could not open the visual briefing project folder: {0}"), issue)));
await this.MessageBus.SendError(new(AppIcons.FOLDER_OPEN, string.Format(T("Could not open the visual briefing project folder: {0}"), issue)));
}
/// <summary>
@@ -36,7 +36,7 @@ public partial class VisualBriefingAssistant
{
this.editor.SourceMaterial.ExceptWith(displaced);
await this.MessageBus.SendWarning(new(
Icons.Material.Filled.Warning,
AppIcons.WARNING,
string.Format(
T("These files are already attached as visual assets and were removed from the source material: {0}"),
string.Join(", ", displaced.Select(attachment => Path.GetFileName(attachment.FilePath))))));
@@ -188,16 +188,16 @@ public partial class VisualBriefingAssistant
return;
if (outcome.Failures.Count > 0)
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, string.Join(Environment.NewLine, outcome.Failures.Select(failure => $"{failure.FileName}: {failure.UserMessage}"))));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, string.Join(Environment.NewLine, outcome.Failures.Select(failure => $"{failure.FileName}: {failure.UserMessage}"))));
else if (outcome.Status is MediaImportStatus.FAILED)
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, T("The media file could not be transcribed.")));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, T("The media file could not be transcribed.")));
if (outcome.Warnings.Count > 0)
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, string.Join(Environment.NewLine, outcome.Warnings.Select(warning => $"{warning.FileName}: {warning.UserMessage}"))));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, string.Join(Environment.NewLine, outcome.Warnings.Select(warning => $"{warning.FileName}: {warning.UserMessage}"))));
if (outcome.Status is MediaImportStatus.CANCELLED)
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, T("The media transcription was canceled.")));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, T("The media transcription was canceled.")));
}
/// <summary>
@@ -118,14 +118,14 @@ public partial class VisualBriefingAssistant
if (PathComparer().Equals(Path.GetFullPath(sourcePath), Path.GetFullPath(response.SaveFilePath)))
{
await this.MessageBus.SendError(new(Icons.Material.Filled.SaveAs, T("Choose a different export location so the immutable briefing version is not overwritten.")));
await this.MessageBus.SendError(new(AppIcons.SAVE_FAILED, T("Choose a different export location so the immutable briefing version is not overwritten.")));
return;
}
var verified = await this.Store.OpenIntegrityCheckedVersionAsync(this.selectedBriefing.BriefingId, this.selectedRevisionId);
if (verified is null)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.GppBad, T("The selected briefing version failed its integrity check and cannot be exported.")));
await this.MessageBus.SendError(new(AppIcons.SECURITY_BLOCKED, T("The selected briefing version failed its integrity check and cannot be exported.")));
return;
}
@@ -152,7 +152,7 @@ public partial class VisualBriefingAssistant
exportedVersion.DocumentHash,
source.Length);
await feedback.SucceededAsync(Icons.Material.Filled.FileDownload, T("The visual briefing was exported."), response.SaveFilePath, true);
await feedback.SucceededAsync(AppIcons.EXPORT, T("The visual briefing was exported."), response.SaveFilePath, true);
}
/// <summary>
@@ -176,7 +176,7 @@ public partial class VisualBriefingAssistant
catch (Exception e)
{
this.Logger.LogError(e, "The visual briefing could not be exported, because the file '{FilePath}' cannot be opened for writing.", targetPath);
await this.MessageBus.SendError(new(Icons.Material.Filled.FileDownload, T("The visual briefing could not be exported. Please check that the target file is not open in another program.")));
await this.MessageBus.SendError(new(AppIcons.EXPORT, T("The visual briefing could not be exported. Please check that the target file is not open in another program.")));
return false;
}
@@ -199,7 +199,7 @@ public partial class VisualBriefingAssistant
this.Logger.LogWarning(deleteFailure, "The incomplete export '{FilePath}' cannot be deleted.", targetPath);
}
await this.MessageBus.SendError(new(Icons.Material.Filled.FileDownload, T("The visual briefing could not be written completely.")));
await this.MessageBus.SendError(new(AppIcons.EXPORT, T("The visual briefing could not be written completely.")));
return false;
}
}
@@ -231,7 +231,7 @@ public partial class VisualBriefingAssistant
if (!imported.Success)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.FileUpload, imported.Issue));
await this.MessageBus.SendError(new(AppIcons.IMPORT, imported.Issue));
return;
}
@@ -245,7 +245,7 @@ public partial class VisualBriefingAssistant
imported.RevisionId,
imported.WasDeduplicated);
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.FileUpload, imported.WasDeduplicated ? T("This briefing revision was already imported.") : T("The visual briefing was imported.")));
await this.MessageBus.SendSuccess(new(AppIcons.IMPORT, imported.WasDeduplicated ? T("This briefing revision was already imported.") : T("The visual briefing was imported.")));
}
/// <summary>
@@ -225,7 +225,7 @@ public partial class VisualBriefingAssistant : MSGComponentBase
"Could not auto-save visual briefing. BriefingId={BriefingId} ExceptionType={ExceptionType}",
this.selectedBriefing.BriefingId,
exception.GetType().Name);
await this.MessageBus.SendError(new(Icons.Material.Filled.SaveAs, T("The visual briefing settings could not be saved.")));
await this.MessageBus.SendError(new(AppIcons.SAVE_FAILED, T("The visual briefing settings could not be saved.")));
}
}
@@ -26,7 +26,7 @@
{
<MudButton Variant="Variant.Filled"
Color="Color.Primary"
StartIcon="@Icons.Material.Filled.PlayArrow"
StartIcon="@AppIcons.RESUME"
Disabled="@this.Disabled"
OnClick="@this.OnResume">
@T("Resume build")
@@ -41,11 +41,11 @@ public static class ChatRoleExtensions
/// <value>The icon of the role.</value>
public string Icon => role switch
{
ChatRole.SYSTEM => Icons.Material.Filled.Settings,
ChatRole.USER => Icons.Material.Filled.Person,
ChatRole.AI => Icons.Material.Filled.AutoAwesome,
ChatRole.SYSTEM => AppIcons.SYSTEM_ROLE,
ChatRole.USER => AppIcons.USER,
ChatRole.AI => AppIcons.AI,
_ => Icons.Material.Filled.Help,
_ => AppIcons.UNKNOWN,
};
/// <summary>
@@ -25,8 +25,8 @@
Style="min-width:auto; border-width:1px; text-transform:none;"
OnClick="@this.ToggleToolTrace">
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIcon Icon="@Icons.Material.Filled.Build" Color="Color.Default" Size="Size.Small" />
<MudIcon Icon="@(this.showToolTrace ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)" Size="Size.Small" />
<MudIcon Icon="@AppIcons.TOOL" Color="Color.Default" Size="Size.Small" />
<MudIcon Icon="@(this.showToolTrace ? AppIcons.EXPAND_LESS : AppIcons.EXPAND_MORE)" Size="Size.Small" />
</MudStack>
</MudButton>
</MudTooltip>
@@ -39,7 +39,7 @@
{
<MudTooltip Text="@T("Number of attachments")" Placement="Placement.Bottom">
<MudBadge Content="@this.Content.FileAttachments.Count" Color="Color.Primary" Overlap="true" BadgeClass="sources-card-header">
<MudIconButton Icon="@Icons.Material.Filled.AttachFile"
<MudIconButton Icon="@AppIcons.ATTACH_FILE"
OnClick="@this.OpenAttachmentsDialog"/>
</MudBadge>
</MudTooltip>
@@ -48,45 +48,45 @@
{
<MudTooltip Text="@T("Number of sources")" Placement="Placement.Bottom">
<MudBadge Content="@this.Content.Sources.Count" Color="Color.Primary" Overlap="true" BadgeClass="sources-card-header">
<MudIconButton Icon="@Icons.Material.Filled.Link" Disabled="@(!this.HasSourcesToShow)" OnClick="@this.ShowSources"/>
<MudIconButton Icon="@AppIcons.SOURCES" Disabled="@(!this.HasSourcesToShow)" OnClick="@this.ShowSources"/>
</MudBadge>
</MudTooltip>
}
@if (this.IsSecondToLastBlock && this.Role is ChatRole.USER && this.EditLastUserBlockFunc is not null)
{
<MudTooltip Text="@T("Edit")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Edit" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.EditLastUserBlock"/>
<MudIconButton Icon="@AppIcons.EDIT" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.EditLastUserBlock"/>
</MudTooltip>
}
@if (this.IsLastContentBlock && this.Role is ChatRole.USER && this.EditLastBlockFunc is not null)
{
<MudTooltip Text="@T("Edit")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Edit" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.EditLastBlock"/>
<MudIconButton Icon="@AppIcons.EDIT" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.EditLastBlock"/>
</MudTooltip>
}
@if (this.IsLastContentBlock && this.Role is ChatRole.AI && this.RegenerateFunc is not null)
{
<MudTooltip Text="@T("Regenerate")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Recycling" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled() || !this.RegenerateEnabled())" OnClick="@this.RegenerateBlock"/>
<MudIconButton Icon="@AppIcons.REGENERATE" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled() || !this.RegenerateEnabled())" OnClick="@this.RegenerateBlock"/>
</MudTooltip>
}
@if (!this.IsLastContentBlock && this.Role is ChatRole.AI && this.RollbackFunc is not null)
{
<MudTooltip Text="@T("Roll back to this response")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Restore" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.RollbackBlock"/>
<MudIconButton Icon="@AppIcons.ROLLBACK" Color="Color.Default" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.RollbackBlock"/>
</MudTooltip>
}
@if (this.RemoveBlockFunc is not null)
{
<MudTooltip Text="@T("Removes this block")" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.RemoveBlock"/>
<MudIconButton Icon="@AppIcons.DELETE" Color="Color.Error" Disabled="@(!this.BlockActionsEnabled())" OnClick="@this.RemoveBlock"/>
</MudTooltip>
}
@if (this.CanExportAnswer)
{
<MudTooltip Text="@this.EffectiveExportTitle" Placement="Placement.Bottom">
<MudMenu Icon="@Icons.Material.Filled.Save" MaxHeight="@MenuDefaults.MAX_HEIGHT">
<MudMenu Icon="@AppIcons.EXPORT" MaxHeight="@MenuDefaults.MAX_HEIGHT">
@foreach (var documentFormat in FileExportFormat.DocumentFormats)
{
<MudMenuItem OnClick="@(() => this.ExportDocument(documentFormat))" Icon="@documentFormat.Icon" Label="@documentFormat.Name"/>
@@ -123,7 +123,7 @@
@if (this.CanSendTo)
{
<MudTooltip Text="@T("Send to ...")" Placement="Placement.Bottom">
<MudMenu Icon="@Icons.Material.Filled.Apps" Disabled="@(!this.IsSendToEnabled)" MaxHeight="@MenuDefaults.MAX_HEIGHT">
<MudMenu Icon="@AppIcons.SEND_TO" Disabled="@(!this.IsSendToEnabled)" MaxHeight="@MenuDefaults.MAX_HEIGHT">
@foreach (var destination in this.SendToDestinations)
{
<MudMenuItem OnClick="@(() => this.SendTo(destination))" Label="@destination.Name"/>
@@ -178,7 +178,7 @@
@this.GetTraceStatusText(invocation)
</MudChip>
</MudStack>
<MudIcon Icon="@(this.IsToolInvocationExpanded(invocation.Order) ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)" Size="Size.Small" />
<MudIcon Icon="@(this.IsToolInvocationExpanded(invocation.Order) ? AppIcons.EXPAND_LESS : AppIcons.EXPAND_MORE)" Size="Size.Small" />
</MudStack>
</MudButton>
@@ -243,7 +243,7 @@
var renderPlan = this.GetMarkdownRenderPlan(textContent.Text);
RenderFragment<MessageFile> saveButton = file =>
@<MudTooltip Text="@this.SaveAsLabel(file)" Placement="Placement.Top">
<MudIconButton Icon="@Icons.Material.Filled.Save" Color="Color.Primary" Variant="Variant.Filled" Class="ma-2" OnClick="@(() => this.ExportFile(file))"/>
<MudIconButton Icon="@AppIcons.EXPORT" Color="Color.Primary" Variant="Variant.Filled" Class="ma-2" OnClick="@(() => this.ExportFile(file))"/>
</MudTooltip>;
}
@foreach (var segment in renderPlan.Segments)
@@ -689,7 +689,7 @@ public partial class ContentBlockComponent : MSGComponentBase
private async Task ReportUnknownExportFormat(ArgumentOutOfRangeException exception, FileExportFormat format)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.Error, string.Format(this.T("Failed to export this message, because the file format '{0}' is unknown."), format)));
await this.MessageBus.SendError(new(AppIcons.ERROR, string.Format(this.T("Failed to export this message, because the file format '{0}' is unknown."), format)));
this.Logger.LogError(exception, "Failed to export the content, because no exporter writes the format {ExportFormat}.", format);
}
+10 -10
View File
@@ -139,7 +139,7 @@ public sealed class ContentText : IContent
}
if (Interlocked.Exchange(ref UNSTORED_CONTENT_REPORTED, 1) is 0)
await MessageBus.INSTANCE.SendWarning(new(Icons.Material.Filled.Storage, TB("AI Studio could not store what the AI received separately from your chat. It remains in the chat itself, so you can still read it.")));
await MessageBus.INSTANCE.SendWarning(new(AppIcons.PROVENANCE_STORE, TB("AI Studio could not store what the AI received separately from your chat. It remains in the chat itself, so you can still read it.")));
}
/// <summary>
@@ -347,7 +347,7 @@ public sealed class ContentText : IContent
// The answer is about to be created without the data the user expected it to use.
// Without this message, that answer is indistinguishable from one that did use it:
//
await MessageBus.INSTANCE.SendWarning(new(Icons.Material.Filled.Source, TB("Your data sources could not be used. This answer was created without them.")));
await MessageBus.INSTANCE.SendWarning(new(AppIcons.DATA_SOURCE, TB("Your data sources could not be used. This answer was created without them.")));
}
}
@@ -491,7 +491,7 @@ public sealed class ContentText : IContent
{
var userMessage = modelLoadResult.FailureReason.ToUserMessage(provider.InstanceName);
if (!string.IsNullOrWhiteSpace(userMessage))
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.CloudOff, userMessage));
await MessageBus.INSTANCE.SendError(new(AppIcons.PROVIDER_ERROR, userMessage));
LOGGER.LogWarning("Skipping selected model availability check for '{ProviderInstanceName}' (provider={ProviderType}) because loading the model list failed with reason {FailureReason}.", provider.InstanceName, provider.Provider, modelLoadResult.FailureReason);
return false;
@@ -516,7 +516,7 @@ public sealed class ContentText : IContent
TB("We could load models from '{0}', but the provider did not return any usable text models."),
provider.InstanceName);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.CloudOff, emptyModelsMessage));
await MessageBus.INSTANCE.SendError(new(AppIcons.PROVIDER_ERROR, emptyModelsMessage));
LOGGER.LogWarning("Skipping AI request because there are no models available from '{ProviderInstanceName}' (provider={ProviderType}).", provider.InstanceName, provider.Provider);
return false;
}
@@ -530,7 +530,7 @@ public sealed class ContentText : IContent
provider.InstanceName,
provider.Provider);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.CloudOff, message));
await MessageBus.INSTANCE.SendError(new(AppIcons.PROVIDER_ERROR, message));
LOGGER.LogWarning("Skipping AI request because model '{ModelId}' is not available from '{ProviderInstanceName}' (provider={ProviderType}).", chatModel.Id, provider.InstanceName, provider.Provider);
return false;
}
@@ -684,14 +684,14 @@ public sealed class ContentText : IContent
if (extraction.Outcome is FileExtractionOutcome.PARTIAL)
{
LOGGER.LogWarning("Parts of the file attachment '{FilePath}' could not be read: pages={FailedPages}.", document.FilePath, string.Join(", ", extraction.FailedPages));
await MessageBus.INSTANCE.SendWarning(new(Icons.Material.Filled.Description, extraction.ToPartialUserMessage(document.FileName)));
await MessageBus.INSTANCE.SendWarning(new(AppIcons.DOCUMENT, extraction.ToPartialUserMessage(document.FileName)));
}
// The file was read correctly, but its extension lies about what it contains:
if (extraction.HasExtensionMismatch)
{
LOGGER.LogWarning("The file attachment '{FilePath}' is actually a '{DetectedFormat}'.", document.FilePath, extraction.DetectedFormat);
await MessageBus.INSTANCE.SendWarning(new(Icons.Material.Filled.RuleFolder, extraction.ToExtensionMismatchUserMessage(document.FileName)));
await MessageBus.INSTANCE.SendWarning(new(AppIcons.FILE_TYPE_MISMATCH, extraction.ToExtensionMismatchUserMessage(document.FileName)));
}
}
@@ -797,7 +797,7 @@ public sealed class ContentText : IContent
foreach (var missingDocument in missingDocuments)
{
LOGGER.LogWarning("File attachment no longer exists and will be skipped: '{MissingDocument}'.", missingDocument.FilePath);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.FindInPage, string.Format(TB("The file '{0}' is currently not available and was not sent."), missingDocument.FileName)));
await MessageBus.INSTANCE.SendError(new(AppIcons.FILE_NOT_FOUND, string.Format(TB("The file '{0}' is currently not available and was not sent."), missingDocument.FileName)));
}
// Only proceed if there are existing, allowed documents:
@@ -840,7 +840,7 @@ public sealed class ContentText : IContent
if (!pandocIsUsable && FileTypes.RequiresPandoc(document.FilePath))
{
LOGGER.LogWarning("The file attachment '{FilePath}' needs Pandoc and will be skipped.", document.FilePath);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Description, FileExtractionErrorCode.PANDOC_UNAVAILABLE.ToUserMessage(document.FileName)));
await MessageBus.INSTANCE.SendError(new(AppIcons.DOCUMENT, FileExtractionErrorCode.PANDOC_UNAVAILABLE.ToUserMessage(document.FileName)));
continue;
}
@@ -848,7 +848,7 @@ public sealed class ContentText : IContent
if (!extraction.HasUsableContent)
{
LOGGER.LogError("Reading the file attachment '{FilePath}' failed and it will not be sent: code={ErrorCode}, message='{ErrorMessage}'.", document.FilePath, extraction.ErrorCode, extraction.ErrorMessage);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.Description, extraction.ToUserMessage(document.FileName)));
await MessageBus.INSTANCE.SendError(new(AppIcons.DOCUMENT, extraction.ToUserMessage(document.FileName)));
continue;
}
@@ -70,7 +70,7 @@ public static class IImageSourceExtensions
var lengthBytes = response.Content.Headers.ContentLength;
if(lengthBytes > MAX_IMAGE_SIZE_BYTES)
{
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("The image at the URL is too large (>10 MB). Skipping the image.")));
await MessageBus.INSTANCE.SendError(new(AppIcons.IMAGE_NOT_SUPPORTED, TB("The image at the URL is too large (>10 MB). Skipping the image.")));
return (success: false, string.Empty);
}
@@ -78,7 +78,7 @@ public static class IImageSourceExtensions
return (success: true, Convert.ToBase64String(bytes));
}
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("Failed to download the image from the URL. Skipping the image.")));
await MessageBus.INSTANCE.SendError(new(AppIcons.IMAGE_NOT_SUPPORTED, TB("Failed to download the image from the URL. Skipping the image.")));
return (success: false, string.Empty);
}
@@ -89,7 +89,7 @@ public static class IImageSourceExtensions
var length = new FileInfo(image.Source).Length;
if(length > MAX_IMAGE_SIZE_BYTES)
{
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("The local image file is too large (>10 MB). Skipping the image.")));
await MessageBus.INSTANCE.SendError(new(AppIcons.IMAGE_NOT_SUPPORTED, TB("The local image file is too large (>10 MB). Skipping the image.")));
return (success: false, string.Empty);
}
@@ -97,7 +97,7 @@ public static class IImageSourceExtensions
return (success: true, Convert.ToBase64String(bytes));
}
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, TB("The local image file does not exist. Skipping the image.")));
await MessageBus.INSTANCE.SendError(new(AppIcons.IMAGE_NOT_SUPPORTED, TB("The local image file does not exist. Skipping the image.")));
return (success: false, string.Empty);
default:
@@ -118,7 +118,7 @@ public static class ListContentBlockExtensions
if (prepared.IsPrepared)
return imageSubContentFactory(prepared);
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ImageNotSupported, prepared.ErrorCode.ToUserMessage(image.FileName)));
await MessageBus.INSTANCE.SendError(new(AppIcons.IMAGE_NOT_SUPPORTED, prepared.ErrorCode.ToUserMessage(image.FileName)));
return null;
}
}
@@ -3,6 +3,6 @@
@if (this.SettingsManager.ConfigurationData.App.ShowAdminSettings)
{
<MudTooltip Text="@T("Export configuration")">
<MudIconButton Variant="@this.Variant" Color="Color.Info" Icon="@Icons.Material.Filled.Dataset" OnClick="@this.Export" aria-label="@T("Export configuration")" />
<MudIconButton Variant="@this.Variant" Color="Color.Info" Icon="@AppIcons.EXPORT_CONFIGURATION" OnClick="@this.Export" aria-label="@T("Export configuration")" />
</MudTooltip>
}
@@ -48,7 +48,7 @@
}
@if (this.HasSettingsPanel)
{
<MudIconButton Variant="Variant.Text" Icon="@Icons.Material.Filled.Settings" Color="Color.Default" OnClick="@this.OpenSettingsDialog"/>
<MudIconButton Variant="Variant.Text" Icon="@AppIcons.SETTINGS" Color="Color.Default" OnClick="@this.OpenSettingsDialog"/>
}
</MudButtonGroup>
@if (this.SecurityBadge is not null || this.AdditionalActions is not null)
@@ -26,7 +26,7 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase, IAssistantCat
public string Description { get; set; } = string.Empty;
[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.DisabledByDefault;
public string Icon { get; set; } = AppIcons.ASSISTANT_FALLBACK;
[Parameter]
public string ButtonText { get; set; } = "Start";
@@ -139,21 +139,21 @@ public partial class AssistantBlock<TSettings> : MSGComponentBase, IAssistantCat
/// </summary>
private AssistantSessionIndicatorData? AssistantSessionIndicator => this.MediaImportSnapshot?.Status switch
{
MediaImportStatus.QUEUED or MediaImportStatus.RUNNING or MediaImportStatus.CANCELING => new(Icons.Material.Filled.ChangeCircle, Color.Info, this.T("Media is still being prepared.")),
MediaImportStatus.SUCCEEDED => new(Icons.Material.Filled.TaskAlt, Color.Success, this.T("The media transcript is ready.")),
MediaImportStatus.WARNING => new(Icons.Material.Filled.WarningAmber, Color.Warning, this.T("Media transcription completed with a warning. Open the assistant to review it.")),
MediaImportStatus.FAILED => new(Icons.Material.Filled.Error, Color.Error, this.T("Media transcription failed. Open the assistant to review it.")),
MediaImportStatus.CANCELLED => new(Icons.Material.Filled.Cancel, Color.Warning, this.T("Media transcription was canceled. Open the assistant to review it.")),
MediaImportStatus.QUEUED or MediaImportStatus.RUNNING or MediaImportStatus.CANCELING => new(AppIcons.RUNNING, Color.Info, this.T("Media is still being prepared.")),
MediaImportStatus.SUCCEEDED => new(AppIcons.SUCCESS, Color.Success, this.T("The media transcript is ready.")),
MediaImportStatus.WARNING => new(AppIcons.WARNING, Color.Warning, this.T("Media transcription completed with a warning. Open the assistant to review it.")),
MediaImportStatus.FAILED => new(AppIcons.ERROR, Color.Error, this.T("Media transcription failed. Open the assistant to review it.")),
MediaImportStatus.CANCELLED => new(AppIcons.CANCELED, Color.Warning, this.T("Media transcription was canceled. Open the assistant to review it.")),
_ => this.AssistantSessionIndicatorWithoutMedia,
};
private AssistantSessionIndicatorData? AssistantSessionIndicatorWithoutMedia => this.AssistantSessionSnapshot?.Status switch
{
AssistantSessionStatus.RUNNING or AssistantSessionStatus.CANCELING => new(Icons.Material.Filled.ChangeCircle, Color.Info, this.T("Assistant is still running.")),
AssistantSessionStatus.COMPLETED => new(Icons.Material.Filled.TaskAlt, Color.Success, this.T("The result is ready.")),
AssistantSessionStatus.FAILED => new(Icons.Material.Filled.Error, Color.Error, this.T("Assistant failed. Open it to review the result.")),
AssistantSessionStatus.CANCELED => new(Icons.Material.Filled.Cancel, Color.Warning, this.T("Assistant was canceled. Open it to review the result.")),
AssistantSessionStatus.RUNNING or AssistantSessionStatus.CANCELING => new(AppIcons.RUNNING, Color.Info, this.T("Assistant is still running.")),
AssistantSessionStatus.COMPLETED => new(AppIcons.SUCCESS, Color.Success, this.T("The result is ready.")),
AssistantSessionStatus.FAILED => new(AppIcons.ERROR, Color.Error, this.T("Assistant failed. Open it to review the result.")),
AssistantSessionStatus.CANCELED => new(AppIcons.CANCELED, Color.Warning, this.T("Assistant was canceled. Open it to review the result.")),
_ => null,
};
@@ -50,7 +50,7 @@
@if (this.PluginToolIds.Count > 0)
{
<MudChip T="string" Size="Size.Small" Variant="Variant.Outlined" Color="Color.Info" Icon="@Icons.Material.Filled.Handyman">
<MudChip T="string" Size="Size.Small" Variant="Variant.Outlined" Color="Color.Info" Icon="@AppIcons.TOOL">
@this.GetToolCountLabel()
</MudChip>
}
@@ -61,7 +61,7 @@
</CardHeaderContent>
<CardHeaderActions>
<MudTooltip Text="@T("Show or hide the detailed security information.")">
<MudIconButton Icon="@Icons.Material.Filled.ExpandMore" OnClick="@this.ToggleDetails" />
<MudIconButton Icon="@AppIcons.EXPAND_MORE" OnClick="@this.ToggleDetails" />
</MudTooltip>
</CardHeaderActions>
</MudCardHeader>
@@ -71,7 +71,7 @@
@if (state.IsEnterpriseApproved)
{
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIcon Icon="@Icons.Material.Filled.Business" Size="Size.Small" Color="@state.SourceColor" />
<MudIcon Icon="@AppIcons.ORGANIZATION" Size="Size.Small" Color="@state.SourceColor" />
<MudText Typo="Typo.body2">@T("Enterprise approval is active")</MudText>
</MudStack>
@@ -79,7 +79,7 @@
{
<MudDivider Vertical="@true" FlexItem="@true" />
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIcon Icon="@Icons.Material.Filled.Lock" Size="Size.Small" Color="Color.Success" />
<MudIcon Icon="@AppIcons.LOCK" Size="Size.Small" Color="Color.Success" />
<MudText Typo="Typo.body2">@T("Your organization requires this assistant to stay enabled")</MudText>
</MudStack>
}
@@ -87,7 +87,7 @@
else
{
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIcon Icon="@Icons.Material.Filled.Speed" Size="Size.Small" />
<MudIcon Icon="@AppIcons.AUDIT_CONFIDENCE" Size="Size.Small" />
<MudText Typo="Typo.body2">@T("Confidence"):</MudText>
<MudProgressLinear Color="@state.AuditColor"
Value="@this.GetConfidencePercentage()"
@@ -101,12 +101,12 @@
}
<MudDivider Vertical="@true" FlexItem="@true" />
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIcon Icon="@Icons.Material.Filled.BugReport" Size="Size.Small" Color="@state.AuditColor" />
<MudIcon Icon="@AppIcons.SECURITY_FINDINGS" Size="Size.Small" Color="@state.AuditColor" />
<MudText Typo="Typo.body2">@this.GetFindingSummary()</MudText>
</MudStack>
<MudDivider Vertical="@true" FlexItem="@true" />
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="1">
<MudIcon Icon="@Icons.Material.Filled.Schedule" Size="Size.Small" />
<MudIcon Icon="@AppIcons.TIME" Size="Size.Small" />
<MudText Typo="Typo.body2" Class="mud-text-secondary">
@this.GetAuditTimestampLabel()
</MudText>
@@ -125,7 +125,7 @@
<MudPaper Outlined="true" Class="pa-2">
<div class="d-flex align-center justify-space-between gap-2">
<MudText Typo="Typo.subtitle2">@T("Technical Details")</MudText>
<MudIconButton Icon="@(this.showMetadata ? Icons.Material.Filled.ExpandLess : Icons.Material.Filled.ExpandMore)"
<MudIconButton Icon="@(this.showMetadata ? AppIcons.EXPAND_LESS : AppIcons.EXPAND_MORE)"
Size="Size.Small"
OnClick="@this.ToggleMetadata" />
</div>
@@ -21,7 +21,7 @@
<MudTextField T="string"
Text="@DROP_FILES_HERE_TEXT"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.AttachFile"
AdornmentIcon="@AppIcons.ATTACH_FILE"
Typo="Typo.body2"
Variant="Variant.Outlined"
ReadOnly="true"
@@ -40,7 +40,7 @@
Class="cursor-pointer"
OnClick="@this.OpenAttachmentsDialog">
<MudIconButton
Icon="@Icons.Material.Filled.AttachFile"
Icon="@AppIcons.ATTACH_FILE"
Color="Color.Default"
Disabled="@this.IsUnavailable"
OnClick="@this.AddFilesManually"/>
@@ -51,7 +51,7 @@
{
<MudTooltip Text="@T("Click here to attach files.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton
Icon="@Icons.Material.Filled.AttachFile"
Icon="@AppIcons.ATTACH_FILE"
Color="Color.Default"
Disabled="@this.IsUnavailable"
OnClick="@this.AddFilesManually"/>
@@ -74,7 +74,7 @@ else
</MudText>
<MudButton
Variant="Variant.Filled"
StartIcon="@Icons.Material.Filled.Add"
StartIcon="@AppIcons.ADD"
Color="Color.Primary"
OnClick="@(() => this.AddFilesManually())"
Style="vertical-align: top; margin-top: -2px;"
@@ -98,17 +98,17 @@ else
{
@if (this.IsUnavailable)
{
<MudChip T="string" Color="Color.Dark" Text="@fileAttachment.FileName" tabindex="-1" Icon="@Icons.Material.Filled.Search" OnClick="@(() => this.InvestigateFile(fileAttachment))"/>
<MudChip T="string" Color="Color.Dark" Text="@fileAttachment.FileName" tabindex="-1" Icon="@AppIcons.FILE_CONTENT_PREVIEW" OnClick="@(() => this.InvestigateFile(fileAttachment))"/>
}
else
{
<MudChip T="string" Color="Color.Dark" Text="@fileAttachment.FileName" tabindex="-1" Icon="@Icons.Material.Filled.Search" OnClick="@(() => this.InvestigateFile(fileAttachment))" OnClose="@(() => this.RemoveDocument(fileAttachment))"/>
<MudChip T="string" Color="Color.Dark" Text="@fileAttachment.FileName" tabindex="-1" Icon="@AppIcons.FILE_CONTENT_PREVIEW" OnClick="@(() => this.InvestigateFile(fileAttachment))" OnClose="@(() => this.RemoveDocument(fileAttachment))"/>
}
}
</PathDropZone>
@if (!this.IsUnavailable)
{
<MudButton OnClick="@(async () => await this.ClearAllFiles())" Variant="Variant.Filled" Color="Color.Info" Class="mt-2" StartIcon="@Icons.Material.Filled.Delete">
<MudButton OnClick="@(async () => await this.ClearAllFiles())" Variant="Variant.Filled" Color="Color.Info" Class="mt-2" StartIcon="@AppIcons.DELETE">
@T("Clear file list")
</MudButton>
}
@@ -172,22 +172,22 @@ public partial class AttachDocuments : MSGComponentBase
if (outcome.Failures.Count > 0)
{
var message = string.Join(Environment.NewLine, outcome.Failures.Select(failure => $"{failure.FileName}: {failure.UserMessage}"));
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, message));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, message));
}
else if (outcome.Status is MediaImportStatus.FAILED)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, this.T("The media file could not be transcribed.")));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, this.T("The media file could not be transcribed.")));
}
if (outcome.Warnings.Count > 0)
{
var message = string.Join(Environment.NewLine, outcome.Warnings.Select(warning => $"{warning.FileName}: {warning.UserMessage}"));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, message));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, message));
}
if (outcome.Status is MediaImportStatus.CANCELLED)
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, this.T("The media transcription was canceled.")));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, this.T("The media transcription was canceled.")));
}
}
@@ -358,7 +358,7 @@ public partial class AttachDocuments : MSGComponentBase
var rejectedPaths = pathList.Where(path => !FileTypes.IsAllowedPath(path, this.AllowedFileTypes)).ToArray();
pathList.RemoveAll(path => rejectedPaths.Contains(path, StringComparer.Ordinal));
if (rejectedPaths.Length > 0)
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Warning, this.T("Some files do not use an allowed format and were not attached.")));
await this.MessageBus.SendWarning(new(AppIcons.WARNING, this.T("Some files do not use an allowed format and were not attached.")));
}
var inaccessiblePaths = pathList.Where(path => !File.Exists(path)).ToList();
@@ -366,7 +366,7 @@ public partial class AttachDocuments : MSGComponentBase
{
this.Logger.LogWarning("Could not access {Count} dropped or selected file(s): {Paths}", inaccessiblePaths.Count, string.Join(", ", inaccessiblePaths));
await this.MessageBus.SendWarning(new(
Icons.Material.Filled.Warning,
AppIcons.WARNING,
this.T("Some files could not be accessed. Please select them with the file chooser instead.")));
}
@@ -421,7 +421,7 @@ public partial class AttachDocuments : MSGComponentBase
if (string.IsNullOrWhiteSpace(this.SettingsManager.ConfigurationData.App.UseTranscriptionProvider))
{
await this.MessageBus.SendWarning(new(
Icons.Material.Filled.VoiceChat,
AppIcons.VOICE_TRANSCRIPTION,
this.T("Media files require a configured transcription provider. Configure one in the transcription settings.")));
return attached;
}
@@ -1,5 +1,5 @@
@inherits MSGComponentBase
<MudSelect T="Log" @bind-Value="@this.SelectedLog" Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Schedule" Margin="Margin.Dense" Label="@T("Changelog")" Class="mb-2 rounded-lg" Variant="Variant.Outlined" SelectedValuesChanged="() => this.ReadLogAsync()" OnKeyUp="() => this.ReadLogAsync()">
<MudSelect T="Log" @bind-Value="@this.SelectedLog" Adornment="Adornment.Start" AdornmentIcon="@AppIcons.CHANGELOG" Margin="Margin.Dense" Label="@T("Changelog")" Class="mb-2 rounded-lg" Variant="Variant.Outlined" SelectedValuesChanged="() => this.ReadLogAsync()" OnKeyUp="() => this.ReadLogAsync()">
@foreach (var log in LOGS)
{
<MudSelectItem Value="@log"/>
@@ -52,7 +52,7 @@
Label="@this.InputLabel"
Placeholder="@this.ProviderPlaceholder"
Adornment="Adornment.End"
AdornmentIcon="@(this.MediaTranscriptionService.IsBusy(this.CurrentMediaImportOwner) ? Icons.Material.Filled.HourglassTop : Icons.Material.Filled.Send)"
AdornmentIcon="@(this.MediaTranscriptionService.IsBusy(this.CurrentMediaImportOwner) ? AppIcons.PENDING : AppIcons.SEND)"
OnAdornmentClick="() => this.SendMessage()"
Disabled="@this.IsInputForbidden()"
Immediate="@true"
@@ -69,25 +69,25 @@
&& this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.TOGGLE_OVERLAY)
{
<MudTooltip Text="@T("Show your workspaces")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.SnippetFolder" OnClick="@(() => this.ToggleWorkspaceOverlay())"/>
<MudIconButton Icon="@AppIcons.WORKSPACES" OnClick="@(() => this.ToggleWorkspaceOverlay())"/>
</MudTooltip>
}
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_MANUALLY)
{
<MudTooltip Text="@T("Save chat")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.Save" OnClick="@(() => this.SaveThread())" Disabled="@(!this.CanThreadBeSaved || this.IsCurrentChatStreaming)"/>
<MudIconButton Icon="@AppIcons.SAVE" OnClick="@(() => this.SaveThread())" Disabled="@(!this.CanThreadBeSaved || this.IsCurrentChatStreaming)"/>
</MudTooltip>
}
<MudTooltip Text="@T("Start temporary chat")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.AddComment" OnClick="@(() => this.StartNewChat(useSameWorkspace: false))"/>
<MudIconButton Icon="@AppIcons.NEW_TEMPORARY_CHAT" OnClick="@(() => this.StartNewChat(useSameWorkspace: false))"/>
</MudTooltip>
@if (!string.IsNullOrWhiteSpace(this.currentWorkspaceName))
{
<MudTooltip Text="@this.TooltipAddChatToWorkspace" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.CommentBank" OnClick="@(() => this.StartNewChat(useSameWorkspace: true))"/>
<MudIconButton Icon="@AppIcons.NEW_CHAT" OnClick="@(() => this.StartNewChat(useSameWorkspace: true))"/>
</MudTooltip>
}
@@ -97,49 +97,49 @@
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
{
<MudTooltip Text="@T("Delete this chat & start a new one.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.DeleteSweep" Color="Color.Error" OnClick="@(() => this.StartNewChat(useSameWorkspace: true, deletePreviousChat: true))" Disabled="@(!this.CanThreadBeSaved || this.IsCurrentChatStreaming)"/>
<MudIconButton Icon="@AppIcons.DELETE_CHAT_AND_START_NEW" Color="Color.Error" OnClick="@(() => this.StartNewChat(useSameWorkspace: true, deletePreviousChat: true))" Disabled="@(!this.CanThreadBeSaved || this.IsCurrentChatStreaming)"/>
</MudTooltip>
}
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES)
{
<MudTooltip Text="@T("Move the chat to a workspace, or to another if it is already in one.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeMoved)" OnClick="@this.MoveChatToWorkspace"/>
<MudIconButton Icon="@AppIcons.MOVE_TO_WORKSPACE" Disabled="@(!this.CanThreadBeMoved)" OnClick="@this.MoveChatToWorkspace"/>
</MudTooltip>
<MudTooltip Text="@T("Copy this chat & continue in the copy.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Disabled="@(!this.CanThreadBeCopied)" OnClick="@this.CopyCurrentChat"/>
<MudIconButton Icon="@AppIcons.DUPLICATE" Disabled="@(!this.CanThreadBeCopied)" OnClick="@this.CopyCurrentChat"/>
</MudTooltip>
}
<AttachDocuments Name="File Attachments" DocumentPaths="@this.ComposerState.FileAttachments" DocumentPathsChanged="@this.ComposerAttachmentsChanged" CatchAllDocuments="true" UseSmallForm="true" ShowMediaStatus="false" Provider="@this.Provider" OwnerChat="@this.ChatThread" EnsureOwnerChatAsync="@this.EnsureMediaImportChatAsync" KeepPreviewedText="@this.KeepPreviewedTextAsync" Disabled="@(!this.CanAttachFiles)"/>
<MudTooltip Text="@T("Show all files attached to this chat")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.LibraryBooks" Disabled="@(!this.HasSentFileAttachments)" OnClick="@this.ShowSentFileAttachments"/>
<MudIconButton Icon="@AppIcons.ATTACHED_FILES" Disabled="@(!this.HasSentFileAttachments)" OnClick="@this.ShowSentFileAttachments"/>
</MudTooltip>
<MudDivider Vertical="true" Style="height: 24px; align-self: center;"/>
<MudTooltip Text="@T("Bold")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.FormatBold" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_BOLD))" Disabled="@this.IsInputForbidden()"/>
<MudIconButton Icon="@AppIcons.FORMAT_BOLD" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_BOLD))" Disabled="@this.IsInputForbidden()"/>
</MudTooltip>
<MudTooltip Text="@T("Italic")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.FormatItalic" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_ITALIC))" Disabled="@this.IsInputForbidden()"/>
<MudIconButton Icon="@AppIcons.FORMAT_ITALIC" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_ITALIC))" Disabled="@this.IsInputForbidden()"/>
</MudTooltip>
<MudTooltip Text="@T("Heading")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.TextFields" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_HEADING))" Disabled="@this.IsInputForbidden()"/>
<MudIconButton Icon="@AppIcons.HEADING" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_HEADING))" Disabled="@this.IsInputForbidden()"/>
</MudTooltip>
<MudTooltip Text="@T("Bulleted List")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.FormatListBulleted" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_BULLET_LIST))" Disabled="@this.IsInputForbidden()"/>
<MudIconButton Icon="@AppIcons.FORMAT_BULLET_LIST" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_BULLET_LIST))" Disabled="@this.IsInputForbidden()"/>
</MudTooltip>
<MudTooltip Text="@T("Code")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.Code" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_CODE))" Disabled="@this.IsInputForbidden()"/>
<MudIconButton Icon="@AppIcons.FORMAT_CODE" OnClick="@(() => this.ApplyMarkdownFormat(MARKDOWN_CODE))" Disabled="@this.IsInputForbidden()"/>
</MudTooltip>
<MudDivider Vertical="true" Style="height: 24px; align-self: center;"/>
<MudTooltip Text="@T("Show the complete system prompt the AI receives")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.Visibility" OnClick="@this.ShowSystemPrompt"/>
<MudIconButton Icon="@AppIcons.PREVIEW" OnClick="@this.ShowSystemPrompt"/>
</MudTooltip>
<ProfileSelection MarginLeft="" CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" Disabled="@(!this.CanProfileBeChanged)" DisabledText="@this.ProfileDisabledText"/>
@@ -162,14 +162,14 @@
@if (this.IsCurrentChatStreaming)
{
<MudTooltip Text="@T("Stop generation")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="@this.CancelStreaming"/>
<MudIconButton Icon="@AppIcons.STOP" Color="Color.Error" OnClick="@this.CancelStreaming"/>
</MudTooltip>
}
@if (!this.ChatThread.IsLLMProviderAllowed(this.Provider))
{
<MudTooltip Text="@(this.SettingsManager.IsProviderProhibited(this.Provider.UsedLLMProvider) ? T("The use of this provider has been prohibited by your organization. Please select a different provider.") : T("The selected provider is not allowed in this chat due to data security or confidence-level requirements."))" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
<MudIconButton Icon="@Icons.Material.Filled.Error" Color="Color.Error"/>
<MudIconButton Icon="@AppIcons.WARNING" Color="Color.Error"/>
</MudTooltip>
}
@@ -533,22 +533,22 @@ public partial class ChatComponent : MSGComponentBase
if (outcome.Failures.Count > 0)
{
var message = string.Join(Environment.NewLine, outcome.Failures.Select(failure => $"{failure.FileName}: {failure.UserMessage}"));
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, message));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, message));
}
else if (outcome.Status is MediaImportStatus.FAILED)
{
await this.MessageBus.SendError(new(Icons.Material.Filled.VoiceChat, this.T("The media file could not be transcribed.")));
await this.MessageBus.SendError(new(AppIcons.VOICE_TRANSCRIPTION, this.T("The media file could not be transcribed.")));
}
if (outcome.Warnings.Count > 0)
{
var message = string.Join(Environment.NewLine, outcome.Warnings.Select(warning => $"{warning.FileName}: {warning.UserMessage}"));
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, message));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, message));
}
if (outcome.Status is MediaImportStatus.CANCELLED)
{
await this.MessageBus.SendWarning(new(Icons.Material.Filled.VoiceChat, this.T("The media transcription was canceled.")));
await this.MessageBus.SendWarning(new(AppIcons.VOICE_TRANSCRIPTION, this.T("The media transcription was canceled.")));
}
}
@@ -12,13 +12,13 @@
}
else
{
<MudIconButton Icon="@Icons.Material.Filled.RateReview" OnClick="@context.ToggleAsync" />
<MudIconButton Icon="@AppIcons.CHAT_TEMPLATE" OnClick="@context.ToggleAsync" />
}
</ActivatorContent>
<ChildContent>
<MudMenuItem Icon="@Icons.Material.Filled.Settings" Label="@T("Manage your templates")" OnClick="@(async () => await this.OpenSettingsDialog())" />
<MudMenuItem Icon="@AppIcons.SETTINGS" Label="@T("Manage your templates")" OnClick="@(async () => await this.OpenSettingsDialog())" />
<MudDivider/>
<MudMenuItem Icon="@Icons.Material.Filled.AddComment" Label="@T("Create template from current chat")" OnClick="@(async () => await this.CreateNewChatTemplateFromChat())" Disabled="@(!this.CanChatThreadBeUsedForTemplate)"/>
<MudMenuItem Icon="@AppIcons.CREATE_CHAT_TEMPLATE" Label="@T("Create template from current chat")" OnClick="@(async () => await this.CreateNewChatTemplateFromChat())" Disabled="@(!this.CanChatThreadBeUsedForTemplate)"/>
<MudDivider/>
@foreach (var chatTemplate in this.SettingsManager.ConfigurationData.ChatTemplates.GetAllChatTemplates())
{
@@ -45,9 +45,9 @@ public partial class ChatTemplateSelection : MSGComponentBase
private string ChatTemplateIcon(ChatTemplate chatTemplate)
{
if (chatTemplate.IsEnterpriseConfiguration)
return Icons.Material.Filled.Business;
return AppIcons.ORGANIZATION;
return Icons.Material.Filled.RateReview;
return AppIcons.CHAT_TEMPLATE;
}
private async Task SelectionChanged(ChatTemplate chatTemplate)
@@ -48,7 +48,7 @@ public sealed class CodeBlockCopyButton : ComponentBase
builder.OpenComponent<MudIconButton>(0);
builder.AddComponentParameter(1, nameof(MudIconButton.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, this.CopyAsync));
builder.AddComponentParameter(2, nameof(MudIconButton.Class), CSS_CLASS);
builder.AddComponentParameter(3, nameof(MudIconButton.Icon), Icons.Material.Rounded.ContentCopy);
builder.AddComponentParameter(3, nameof(MudIconButton.Icon), AppIcons.COPY);
builder.AddComponentParameter(4, nameof(MudIconButton.Color), Color.Primary);
builder.AddComponentParameter(5, nameof(MudIconButton.Variant), Variant.Filled);
builder.AddComponentParameter(6, nameof(MudIconButton.Size), Size.Medium);
@@ -68,7 +68,7 @@ public sealed class CodeBlockCopyButton : ComponentBase
builder.AddComponentParameter(19, nameof(MudTooltip.ChildContent), (RenderFragment)(content =>
{
content.OpenComponent<MudIconButton>(0);
content.AddComponentParameter(1, nameof(MudIconButton.Icon), Icons.Material.Rounded.DoneAll);
content.AddComponentParameter(1, nameof(MudIconButton.Icon), AppIcons.COPIED);
content.AddComponentParameter(2, nameof(MudIconButton.Color), Color.Success);
content.AddComponentParameter(3, nameof(MudIconButton.Variant), Variant.Filled);
content.AddComponentParameter(4, nameof(MudIconButton.Size), Size.Medium);
@@ -17,7 +17,7 @@ public partial class CompactExpansionPanel : ComponentBase
public string HeaderText { get; set; } = string.Empty;
[Parameter]
public string HeaderIcon { get; set; } = Icons.Material.Filled.Tune;
public string HeaderIcon { get; set; } = AppIcons.ADVANCED_SETTINGS;
[Parameter]
public Color IconColor { get; set; } = Color.Inherit;
@@ -3,7 +3,7 @@
<div class="d-flex">
<MudTooltip Text="@T("Shows and hides the confidence card with information about the selected LLM provider.")" Placement="Placement.Top">
<MudIconButton Icon="@Icons.Material.Filled.Security" Class="confidence-icon" Style="@this.LLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager)" OnClick="@this.ToggleConfidence"/>
<MudIconButton Icon="@AppIcons.PROVIDER_CONFIDENCE" Class="confidence-icon" Style="@this.LLMProvider.GetConfidence(this.SettingsManager).SetColorStyle(this.SettingsManager)" OnClick="@this.ToggleConfidence"/>
</MudTooltip>
<MudPopover Open="@this.showConfidence" AnchorOrigin="Origin.TopLeft" TransformOrigin="Origin.BottomLeft" Style="@this.GetPopoverStyle()" DropShadow="@true" Class="border-solid border-4 rounded-lg">
@@ -29,7 +29,7 @@
<MudList T="@string">
@foreach (var sourceTuple in this.GetConfidenceSources())
{
<MudListItem Icon="@Icons.Material.Filled.Link" Href="@sourceTuple.Source" Target="_blank" Text="@sourceTuple.Index"/>
<MudListItem Icon="@AppIcons.LINK" Href="@sourceTuple.Source" Target="_blank" Text="@sourceTuple.Index"/>
}
</MudList>
}
@@ -5,5 +5,5 @@ namespace AIStudio.Components;
public partial class ConfigInfoRow : ComponentBase
{
[Parameter]
public ConfigInfoRowItem Item { get; set; } = new(Icons.Material.Filled.ArrowRightAlt, string.Empty, string.Empty, string.Empty, string.Empty);
public ConfigInfoRowItem Item { get; set; } = new(AppIcons.INFO_ROW, string.Empty, string.Empty, string.Empty, string.Empty);
}
@@ -14,7 +14,7 @@
@if (this.ShowWarning)
{
<div style="display: flex; align-items: center; gap: 8px; margin-top: 4px;">
<MudIcon Icon="@Icons.Material.Filled.Warning" Size="Size.Small" Color="Color.Warning"/>
<MudIcon Icon="@AppIcons.WARNING" Size="Size.Small" Color="Color.Warning"/>
<MudText Typo="Typo.subtitle2">@this.WarningText</MudText>
</div>
}
@@ -5,7 +5,7 @@ namespace AIStudio.Components;
public partial class ConfigPluginInfoCard : ComponentBase
{
[Parameter]
public string HeaderIcon { get; set; } = Icons.Material.Filled.Extension;
public string HeaderIcon { get; set; } = AppIcons.PLUGIN;
[Parameter]
public string HeaderText { get; set; } = string.Empty;
@@ -8,7 +8,7 @@
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.FlexStart" Wrap="Wrap.NoWrap" StretchItems="this.StretchItems">
@* MudTooltip.RootStyle is set as a workaround for issue -> https://github.com/MudBlazor/MudBlazor/issues/10882 *@
<MudTooltip Text="@TB("This feature is managed by your organization and has therefore been disabled.")" Arrow="true" Placement="Placement.Right" RootStyle="display:inline-flex;">
<MudIcon Icon="@Icons.Material.Filled.Lock" Color="Color.Error" Size="Size.Small" Class="mr-1"/>
<MudIcon Icon="@AppIcons.LOCK" Color="Color.Error" Size="Size.Small" Class="mr-1"/>
</MudTooltip>
@this.Body
</MudStack>
@@ -17,7 +17,7 @@
Class="flex-grow-1"
/>
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen"
<MudButton StartIcon="@AppIcons.BROWSE"
Variant="Variant.Outlined"
Color="Color.Primary"
Size="Size.Small"
@@ -24,7 +24,7 @@ public partial class ConfigurationDirectory : ConfigurationBaseCore
/// The icon to display next to the textfield.
/// </summary>
[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.Folder;
public string Icon { get; set; } = AppIcons.FOLDER;
/// <summary>
/// The color of the icon to use.
@@ -118,7 +118,7 @@ public partial class ConfigurationDirectory : ConfigurationBaseCore
if (path is null)
{
this.Logger.LogWarning("None of the {Count} dropped path(s) could be used as a directory.", paths.Count);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Warning, DroppedFolder.WarningFor(paths)));
await this.MessageBus.SendWarning(new(AppIcons.WARNING, DroppedFolder.WarningFor(paths)));
return;
}
@@ -19,7 +19,7 @@
Class="flex-grow-1"
/>
<MudButton StartIcon="@Icons.Material.Filled.FolderOpen"
<MudButton StartIcon="@AppIcons.BROWSE"
Variant="Variant.Outlined"
Color="Color.Primary"
Size="Size.Small"
@@ -25,7 +25,7 @@ public partial class ConfigurationFile : ConfigurationBaseCore
/// The icon to display next to the textfield.
/// </summary>
[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.AttachFile;
public string Icon { get; set; } = AppIcons.FILE;
/// <summary>
/// The color of the icon to use.
@@ -135,7 +135,7 @@ public partial class ConfigurationFile : ConfigurationBaseCore
if (path is null)
{
this.Logger.LogWarning("None of the {Count} dropped path(s) could be used as a file.", paths.Count);
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Warning, DroppedFile.WarningFor(paths)));
await this.MessageBus.SendWarning(new(AppIcons.WARNING, DroppedFile.WarningFor(paths)));
return;
}
@@ -21,7 +21,7 @@
<MudStack Row="true" AlignItems="AlignItems.Center" Justify="Justify.FlexStart" Wrap="Wrap.NoWrap">
@* MudTooltip.RootStyle is set as a workaround for issue -> https://github.com/MudBlazor/MudBlazor/issues/10882 *@
<MudTooltip Text="@this.LockedTooltip()" Arrow="true" Placement="Placement.Right" RootStyle="display:inline-flex;">
<MudIcon Icon="@Icons.Material.Filled.Lock" Color="Color.Error" Size="Size.Small" Class="mr-1"/>
<MudIcon Icon="@AppIcons.LOCK" Color="Color.Error" Size="Size.Small" Class="mr-1"/>
</MudTooltip>
@data.Name
</MudStack>
@@ -17,7 +17,7 @@
<MudButton Variant="Variant.Outlined"
Color="Color.Primary"
Size="Size.Small"
StartIcon="@Icons.Material.Filled.Edit"
StartIcon="@AppIcons.EDIT"
OnClick="@this.OpenDialog"
Disabled="@this.IsDisabled"
Class="mb-1">
Loaded 100 of 352 files, more files were not shown because too many files have changed in this diff. Show more