mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-03-29 13:51:37 +00:00
458 lines
26 KiB
Plaintext
458 lines
26 KiB
Plaintext
@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="@this.GetOptionalStyle(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="@this.GetOptionalStyle(fileContent.Style)">
|
|
<ReadFileContent @bind-FileContent="@fileState.Content" />
|
|
</div>
|
|
}
|
|
break;
|
|
case AssistantComponentType.DROPDOWN:
|
|
if (component is AssistantDropdown assistantDropdown)
|
|
{
|
|
if (assistantDropdown.IsMultiselect)
|
|
{
|
|
<DynamicAssistantDropdown Items="@assistantDropdown.Items"
|
|
SelectedValues="@this.multiselectDropdownFields[assistantDropdown.Name]"
|
|
SelectedValuesChanged="@this.CreateMultiselectDropdownChangedCallback(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="@true"
|
|
HasSelectAll="@assistantDropdown.HasSelectAll"
|
|
SelectAllText="@assistantDropdown.SelectAllText"
|
|
Class="@assistantDropdown.Class"
|
|
Style="@this.GetOptionalStyle(assistantDropdown.Style)" />
|
|
}
|
|
else
|
|
{
|
|
<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)"
|
|
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;
|
|
var icon = AssistantComponentPropHelper.GetIconSvg(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);
|
|
var iconSize = AssistantComponentPropHelper.GetComponentSize(button.IconSize, Size.Medium);
|
|
var variant = button.GetButtonVariant();
|
|
var disabled = this.IsButtonActionRunning(button.Name);
|
|
var buttonClass = MergeClass(button.Class, "mb-3");
|
|
var style = this.GetOptionalStyle(button.Style);
|
|
|
|
if (!button.IsIconButton)
|
|
{
|
|
<div>
|
|
<MudButton Variant="@variant"
|
|
Color="@color"
|
|
OnClick="@(() => this.ExecuteButtonActionAsync(button))"
|
|
Size="@size"
|
|
FullWidth="@button.IsFullWidth"
|
|
StartIcon="@icon"
|
|
EndIcon="@AssistantComponentPropHelper.GetIconSvg(button.EndIcon)"
|
|
IconColor="@iconColor"
|
|
IconSize="@iconSize"
|
|
Disabled="@disabled"
|
|
Class="@buttonClass"
|
|
Style="@style">
|
|
@button.Text
|
|
</MudButton>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<MudIconButton Icon="@icon"
|
|
Color="@color"
|
|
Variant="@variant"
|
|
Size="@size"
|
|
OnClick="@(() => this.ExecuteButtonActionAsync(button))"
|
|
Disabled="@disabled"
|
|
Class="@buttonClass"
|
|
Style="@style" />
|
|
}
|
|
|
|
}
|
|
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.GetItemsAlignment(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(stack.Style)">
|
|
@this.RenderChildren(stack.Children)
|
|
</MudStack>
|
|
}
|
|
break;
|
|
case AssistantComponentType.LAYOUT_ACCORDION:
|
|
if (component is AssistantAccordion assistantAccordion)
|
|
{
|
|
var accordion = assistantAccordion;
|
|
<MudExpansionPanels MultiExpansion="@accordion.AllowMultiSelection"
|
|
Dense="@accordion.IsDense"
|
|
Outlined="@accordion.HasOutline"
|
|
Square="@accordion.IsSquare"
|
|
Elevation="@accordion.Elevation"
|
|
Gutters="@accordion.HasSectionPaddings"
|
|
Class="@MergeClass(accordion.Class, "my-6")"
|
|
Style="@this.GetOptionalStyle(accordion.Style)">
|
|
@this.RenderChildren(accordion.Children)
|
|
</MudExpansionPanels>
|
|
}
|
|
break;
|
|
case AssistantComponentType.LAYOUT_ACCORDION_SECTION:
|
|
if (component is AssistantAccordionSection assistantAccordionSection)
|
|
{
|
|
var accordionSection = assistantAccordionSection;
|
|
var textColor = accordionSection.IsDisabled ? Color.Info : AssistantComponentPropHelper.GetColor(accordionSection.HeaderColor, Color.Inherit);
|
|
<MudExpansionPanel KeepContentAlive="@accordionSection.KeepContentAlive"
|
|
disabled="@accordionSection.IsDisabled"
|
|
Expanded="@accordionSection.IsExpanded"
|
|
Dense="@accordionSection.IsDense"
|
|
Gutters="@accordionSection.HasInnerPadding"
|
|
HideIcon="@accordionSection.HideIcon"
|
|
Icon="@AssistantComponentPropHelper.GetIconSvg(accordionSection.ExpandIcon)"
|
|
MaxHeight="@accordionSection.MaxHeight"
|
|
Class="@accordionSection.Class"
|
|
Style="@this.GetOptionalStyle(accordionSection.Style)">
|
|
<TitleContent>
|
|
<div class="d-flex">
|
|
<MudIcon Icon="@AssistantComponentPropHelper.GetIconSvg(accordionSection.HeaderIcon)" class="mr-3"></MudIcon>
|
|
<MudText Align="@AssistantComponentPropHelper.GetAlignment(accordionSection.HeaderAlign)"
|
|
Color="@textColor"
|
|
Typo="@AssistantComponentPropHelper.GetTypography(accordionSection.HeaderTypo)">
|
|
@accordionSection.HeaderText
|
|
</MudText>
|
|
</div>
|
|
</TitleContent>
|
|
<ChildContent>
|
|
@this.RenderChildren(accordionSection.Children)
|
|
</ChildContent>
|
|
</MudExpansionPanel>
|
|
}
|
|
break;
|
|
case AssistantComponentType.PROVIDER_SELECTION:
|
|
if (component is AssistantProviderSelection providerSelection)
|
|
{
|
|
<div class="@providerSelection.Class" style="@this.GetOptionalStyle(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="@this.GetOptionalStyle(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];
|
|
var disabled = assistantSwitch.Disabled || this.IsSwitchActionRunning(assistantSwitch.Name);
|
|
<MudField Label="@assistantSwitch.Label" Variant="Variant.Outlined" Class="mb-3" Disabled="@disabled">
|
|
<MudSwitch T="bool"
|
|
Value="@currentValue"
|
|
ValueChanged="@((bool value) => this.ExecuteSwitchChangedAsync(assistantSwitch, value))"
|
|
LabelPlacement="@assistantSwitch.GetLabelPlacement()"
|
|
Color="@assistantSwitch.GetColor(assistantSwitch.CheckedColor)"
|
|
UncheckedColor="@assistantSwitch.GetColor(assistantSwitch.UncheckedColor)"
|
|
ThumbIcon="@assistantSwitch.GetIconSvg()"
|
|
ThumbIconColor="@assistantSwitch.GetColor(assistantSwitch.IconColor)"
|
|
Disabled="@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)
|
|
{
|
|
@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>
|
|
}
|
|
}
|
|
</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? 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 = paper.Style;
|
|
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(';')}");
|
|
}
|
|
}
|