AI-Studio/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor

373 lines
20 KiB
Plaintext
Raw Normal View History

@attribute [Route(Routes.ASSISTANT_DYNAMIC)]
@using AIStudio.Components
@using AIStudio.Settings
@using AIStudio.Tools.PluginSystem.Assistants.DataModel
@using AIStudio.Tools.PluginSystem.Assistants.DataModel.Layout
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogDynamic>
@foreach (var component in this.RootComponent!.Children)
{
@this.RenderComponent(component)
}
@code {
private RenderFragment RenderChildren(IEnumerable<IAssistantComponent> children) => @<text>
@foreach (var child in children)
{
@this.RenderComponent(child)
}
</text>;
private RenderFragment RenderComponent(IAssistantComponent component) => @<text>
@switch (component.Type)
{
case AssistantComponentType.TEXT_AREA:
if (component is AssistantTextArea textArea)
{
var lines = textArea.IsSingleLine ? 1 : 6;
<MudTextField T="string"
@bind-Text="@this.inputFields[textArea.Name]"
Label="@textArea.Label"
HelperText="@textArea.HelperText"
HelperTextOnFocus="@textArea.HelperTextOnFocus"
ReadOnly="@textArea.ReadOnly"
Counter="@textArea.Counter"
MaxLength="@textArea.MaxLength"
Immediate="@textArea.IsImmediate"
Adornment="@textArea.GetAdornmentPos()"
AdornmentIcon="@textArea.GetIconSvg()"
AdornmentText="@textArea.AdornmentText"
AdornmentColor="@textArea.GetAdornmentColor()"
Variant="Variant.Outlined"
Lines="@lines"
AutoGrow="@true"
MaxLines="12"
Class='@MergeClass(textArea.Class, "mb-3")'
Style="@this.GetOptionalStyle(textArea.Style)" />
}
break;
case AssistantComponentType.IMAGE:
if (component is AssistantImage assistantImage)
{
var resolvedSource = this.ResolveImageSource(assistantImage);
if (!string.IsNullOrWhiteSpace(resolvedSource))
{
var image = assistantImage;
<div Class="mb-4">
<MudImage Fluid="true" Src="@resolvedSource" Alt="@image.Alt" Class='@MergeClass(image.Class, "rounded-lg mb-2")' Style="@this.GetOptionalStyle(image.Style)" Elevation="20" />
@if (!string.IsNullOrWhiteSpace(image.Caption))
{
<MudText Typo="Typo.caption" Align="Align.Center">@image.Caption</MudText>
}
</div>
}
}
break;
case AssistantComponentType.WEB_CONTENT_READER:
if (component is AssistantWebContentReader webContent && this.webContentFields.TryGetValue(webContent.Name, out var webState))
{
<div class="@webContent.Class" style="@webContent.Style">
<ReadWebContent @bind-Content="@webState.Content"
ProviderSettings="@this.providerSettings"
@bind-AgentIsRunning="@webState.AgentIsRunning"
@bind-Preselect="@webState.Preselect"
@bind-PreselectContentCleanerAgent="@webState.PreselectContentCleanerAgent" />
</div>
}
break;
case AssistantComponentType.FILE_CONTENT_READER:
if (component is AssistantFileContentReader fileContent && this.fileContentFields.TryGetValue(fileContent.Name, out var fileState))
{
<div class="@fileContent.Class" style="@fileContent.Style">
<ReadFileContent @bind-FileContent="@fileState.Content" />
</div>
}
break;
case AssistantComponentType.DROPDOWN:
if (component is AssistantDropdown assistantDropdown)
{
<DynamicAssistantDropdown Items="@assistantDropdown.Items"
@bind-Value="@this.dropdownFields[assistantDropdown.Name]"
Default="@assistantDropdown.Default"
Label="@assistantDropdown.Label"
HelperText="@assistantDropdown.HelperText"
OpenIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.OpenIcon)"
CloseIcon="@AssistantComponentPropHelper.GetIconSvg(assistantDropdown.CloseIcon)"
IconColor="@AssistantComponentPropHelper.GetColor(assistantDropdown.IconColor, Color.Default)"
IconPosition="@AssistantComponentPropHelper.GetAdornment(assistantDropdown.IconPositon, Adornment.End)"
Variant="@AssistantComponentPropHelper.GetVariant(assistantDropdown.Variant, Variant.Outlined)"
IsMultiselect="@assistantDropdown.IsMultiselect"
HasSelectAll="@assistantDropdown.HasSelectAll"
SelectAllText="@assistantDropdown.SelectAllText"
Class="@assistantDropdown.Class"
Style="@this.GetOptionalStyle(assistantDropdown.Style)"
/>
}
break;
case AssistantComponentType.BUTTON:
if (component is AssistantButton assistantButton)
{
var button = assistantButton;
<div>
<MudButton Variant="@button.GetButtonVariant()"
Color="@AssistantComponentPropHelper.GetColor(button.Color, Color.Default)"
OnClick="@(() => this.ExecuteButtonActionAsync(button))"
Size="@AssistantComponentPropHelper.GetComponentSize(button.Size, Size.Medium)"
FullWidth="@button.IsFullWidth"
StartIcon="@AssistantComponentPropHelper.GetIconSvg(button.StartIcon)"
EndIcon="@AssistantComponentPropHelper.GetIconSvg(button.EndIcon)"
IconColor="@AssistantComponentPropHelper.GetColor(button.IconColor, Color.Inherit)"
IconSize="@AssistantComponentPropHelper.GetComponentSize(button.IconSize, Size.Medium)"
Disabled="@this.IsButtonActionRunning(button.Name)"
Class='@MergeClass(button.Class, "mb-3")'
Style="@this.GetOptionalStyle(button.Style)">
@button.Text
</MudButton>
</div>
}
break;
case AssistantComponentType.BUTTON_GROUP:
if (component is AssistantButtonGroup assistantButtonGroup)
{
var buttonGroup = assistantButtonGroup;
<MudButtonGroup Variant="@buttonGroup.GetVariant()"
Color="@AssistantComponentPropHelper.GetColor(buttonGroup.Color, Color.Default)"
Size="@AssistantComponentPropHelper.GetComponentSize(buttonGroup.Size, Size.Medium)"
OverrideStyles="@buttonGroup.OverrideStyles"
Vertical="@buttonGroup.Vertical"
DropShadow="@buttonGroup.DropShadow"
Class='@MergeClass(buttonGroup.Class, "mb-3")'
Style="@this.GetOptionalStyle(buttonGroup.Style)">
@this.RenderChildren(buttonGroup.Children)
</MudButtonGroup>
}
break;
case AssistantComponentType.LAYOUT_GRID:
if (component is AssistantGrid assistantGrid)
{
var grid = assistantGrid;
<MudGrid Justify="@(AssistantComponentPropHelper.GetJustify(grid.Justify) ?? Justify.FlexStart)"
Spacing="@grid.Spacing"
Class="@grid.Class"
Style="@this.GetOptionalStyle(grid.Style)">
@this.RenderChildren(grid.Children)
</MudGrid>
}
break;
case AssistantComponentType.LAYOUT_ITEM:
if (component is AssistantItem assistantItem)
{
@this.RenderLayoutItem(assistantItem)
}
break;
case AssistantComponentType.LAYOUT_PAPER:
if (component is AssistantPaper assistantPaper)
{
var paper = assistantPaper;
<MudPaper Elevation="@paper.Elevation"
Outlined="@paper.IsOutlined"
Square="@paper.IsSquare"
Class="@paper.Class"
Style="@this.BuildPaperStyle(paper)">
@this.RenderChildren(paper.Children)
</MudPaper>
}
break;
case AssistantComponentType.LAYOUT_STACK:
if (component is AssistantStack assistantStack)
{
var stack = assistantStack;
<MudStack Row="@stack.IsRow"
Reverse="@stack.IsReverse"
Breakpoint="@AssistantComponentPropHelper.GetBreakpoint(stack.Breakpoint, Breakpoint.None)"
AlignItems="@(AssistantComponentPropHelper.GetAlignment(stack.Align) ?? AlignItems.Stretch)"
Justify="@(AssistantComponentPropHelper.GetJustify(stack.Justify) ?? Justify.FlexStart)"
StretchItems="@(AssistantComponentPropHelper.GetStretching(stack.Stretch) ?? StretchItems.None)"
Wrap="@(AssistantComponentPropHelper.GetWrap(stack.Wrap) ?? Wrap.Wrap)"
Spacing="@stack.Spacing"
Class="@stack.Class"
Style="@this.GetOptionalStyle(this.GetRawStyle(stack))">
@this.RenderChildren(stack.Children)
</MudStack>
}
break;
case AssistantComponentType.PROVIDER_SELECTION:
if (component is AssistantProviderSelection providerSelection)
{
<div class="@providerSelection.Class" style="@providerSelection.Style">
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider" />
</div>
}
break;
case AssistantComponentType.PROFILE_SELECTION:
if (component is AssistantProfileSelection profileSelection)
{
var selection = profileSelection;
<div class="@selection.Class" style="@selection.Style">
<ProfileFormSelection Validation="@((Profile profile) => this.ValidateProfileSelection(selection, profile))" @bind-Profile="@this.currentProfile" />
</div>
}
break;
case AssistantComponentType.SWITCH:
if (component is AssistantSwitch switchComponent)
{
var assistantSwitch = switchComponent;
var currentValue = this.switchFields[assistantSwitch.Name];
<MudField Label="@assistantSwitch.Label" Variant="Variant.Outlined" Class="mb-3" Disabled="@assistantSwitch.Disabled">
<MudSwitch T="bool"
Value="@currentValue"
ValueChanged="@((bool value) => this.switchFields[assistantSwitch.Name] = value)"
LabelPlacement="@assistantSwitch.GetLabelPlacement()"
Color="@assistantSwitch.GetColor(assistantSwitch.CheckedColor)"
UncheckedColor="@assistantSwitch.GetColor(assistantSwitch.UncheckedColor)"
ThumbIcon="@assistantSwitch.GetIconSvg()"
ThumbIconColor="@assistantSwitch.GetColor(assistantSwitch.IconColor)"
Disabled="@assistantSwitch.Disabled"
Class="@assistantSwitch.Class"
Style="@this.GetOptionalStyle(assistantSwitch.Style)">
@(currentValue ? assistantSwitch.LabelOn : assistantSwitch.LabelOff)
</MudSwitch>
</MudField>
}
break;
case AssistantComponentType.HEADING:
if (component is AssistantHeading assistantHeading)
{
var heading = assistantHeading;
@switch (assistantHeading.Level)
{
case 1:
<MudText Typo="Typo.h4" Class="@heading.Class" Style="@this.GetOptionalStyle(heading.Style)">@heading.Text</MudText>
break;
case 2:
<MudText Typo="Typo.h5" Class="@heading.Class" Style="@this.GetOptionalStyle(heading.Style)">@heading.Text</MudText>
break;
case 3:
<MudText Typo="Typo.h6" Class="@heading.Class" Style="@this.GetOptionalStyle(heading.Style)">@heading.Text</MudText>
break;
default:
<MudText Typo="Typo.h4" Class="@heading.Class" Style="@this.GetOptionalStyle(heading.Style)">@heading.Text</MudText>
break;
}
}
break;
case AssistantComponentType.TEXT:
if (component is AssistantText assistantText)
{
var text = assistantText;
<MudText Typo="Typo.body1" Class='@MergeClass(text.Class, "mb-3")' Style="@this.GetOptionalStyle(text.Style)">@text.Content</MudText>
}
break;
case AssistantComponentType.LIST:
if (component is AssistantList assistantList)
{
var list = assistantList;
<MudList T="string" Class='@MergeClass(list.Class, "mb-6")' Style="@this.GetOptionalStyle(list.Style)">
@foreach (var item in list.Items)
2026-02-10 16:06:45 +00:00
{
@if (item.Type == "LINK")
{
<MudListItem T="string" Icon="@Icons.Material.Filled.Link" Target="_blank" Href="@item.Href">@item.Text</MudListItem>
}
else
{
<MudListItem T="string">@item.Text</MudListItem>
}
2026-02-10 16:06:45 +00:00
}
</MudList>
}
break;
case AssistantComponentType.COLOR_PICKER:
if (component is AssistantColorPicker assistantColorPicker)
{
var colorPicker = assistantColorPicker;
var variant = colorPicker.GetPickerVariant();
var elevation = variant == PickerVariant.Static ? 6 : 0;
var rounded = variant == PickerVariant.Static;
<MudItem Class="d-flex">
<MudColorPicker @bind-Text="@this.colorPickerFields[colorPicker.Name]"
Label="@colorPicker.Label"
Placeholder="@colorPicker.Placeholder"
ShowAlpha="@colorPicker.ShowAlpha"
ShowToolbar="@colorPicker.ShowToolbar"
ShowModeSwitch="@colorPicker.ShowModeSwitch"
PickerVariant="@variant"
Rounded="@rounded"
Elevation="@elevation"
Style="@($"color: {this.colorPickerFields[colorPicker.Name]};")"
Class="@MergeClass(colorPicker.Class, "mb-3")" />
</MudItem>
}
break;
}
</text>;
private string? GetRawStyle(IAssistantComponent component)
{
if (!component.Props.TryGetValue("Style", out var rawStyle) || rawStyle is null)
return null;
return rawStyle as string ?? rawStyle.ToString();
}
private string? BuildPaperStyle(AssistantPaper paper)
{
List<string> styles = [];
this.AddStyle(styles, "height", paper.Height);
this.AddStyle(styles, "max-height", paper.MaxHeight);
this.AddStyle(styles, "min-height", paper.MinHeight);
this.AddStyle(styles, "width", paper.Width);
this.AddStyle(styles, "max-width", paper.MaxWidth);
this.AddStyle(styles, "min-width", paper.MinWidth);
var customStyle = this.GetRawStyle(paper);
if (!string.IsNullOrWhiteSpace(customStyle))
styles.Add(customStyle.Trim().TrimEnd(';'));
return styles.Count == 0 ? null : string.Join("; ", styles);
}
private RenderFragment RenderLayoutItem(AssistantItem item) => builder =>
{
builder.OpenComponent<MudItem>(0);
if (item.Xs.HasValue)
builder.AddAttribute(1, "xs", item.Xs.Value);
if (item.Sm.HasValue)
builder.AddAttribute(2, "sm", item.Sm.Value);
if (item.Md.HasValue)
builder.AddAttribute(3, "md", item.Md.Value);
if (item.Lg.HasValue)
builder.AddAttribute(4, "lg", item.Lg.Value);
if (item.Xl.HasValue)
builder.AddAttribute(5, "xl", item.Xl.Value);
if (item.Xxl.HasValue)
builder.AddAttribute(6, "xxl", item.Xxl.Value);
var itemClass = item.Class;
if (!string.IsNullOrWhiteSpace(itemClass))
builder.AddAttribute(7, nameof(MudItem.Class), itemClass);
var itemStyle = this.GetOptionalStyle(item.Style);
if (!string.IsNullOrWhiteSpace(itemStyle))
builder.AddAttribute(8, nameof(MudItem.Style), itemStyle);
builder.AddAttribute(9, nameof(MudItem.ChildContent), this.RenderChildren(item.Children));
builder.CloseComponent();
};
private void AddStyle(List<string> styles, string key, string value)
{
if (!string.IsNullOrWhiteSpace(value))
styles.Add($"{key}: {value.Trim().TrimEnd(';')}");
}
}