2026-03-10 15:45:01 +00:00
|
|
|
@attribute [Route(Routes.ASSISTANT_DYNAMIC)]
|
2026-02-23 14:01:00 +00:00
|
|
|
@using AIStudio.Components
|
|
|
|
|
@using AIStudio.Settings
|
2025-09-30 19:53:56 +00:00
|
|
|
@using AIStudio.Tools.PluginSystem.Assistants.DataModel
|
2026-03-10 17:57:48 +00:00
|
|
|
@using AIStudio.Tools.PluginSystem.Assistants.DataModel.Layout
|
2025-09-30 19:53:56 +00:00
|
|
|
@inherits AssistantBaseCore<AIStudio.Dialogs.Settings.SettingsDialogDynamic>
|
|
|
|
|
|
|
|
|
|
@foreach (var component in this.RootComponent!.Children)
|
|
|
|
|
{
|
2026-03-10 15:45:01 +00:00
|
|
|
@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)
|
2026-02-24 10:31:16 +00:00
|
|
|
{
|
2026-03-10 15:45:01 +00:00
|
|
|
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)
|
|
|
|
|
{
|
2026-03-13 00:51:48 +00:00
|
|
|
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)" />
|
|
|
|
|
}
|
2026-03-10 15:45:01 +00:00
|
|
|
}
|
|
|
|
|
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;
|
2026-03-10 17:57:48 +00:00
|
|
|
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;
|
2026-03-10 15:45:01 +00:00
|
|
|
case AssistantComponentType.PROVIDER_SELECTION:
|
|
|
|
|
if (component is AssistantProviderSelection providerSelection)
|
|
|
|
|
{
|
|
|
|
|
<div class="@providerSelection.Class" style="@providerSelection.Style">
|
|
|
|
|
<ProviderSelection @bind-ProviderSettings="@this.providerSettings" ValidateProvider="@this.ValidatingProvider" />
|
2026-02-24 10:31:16 +00:00
|
|
|
</div>
|
|
|
|
|
}
|
2026-03-10 15:45:01 +00:00
|
|
|
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" />
|
2026-02-24 16:44:04 +00:00
|
|
|
</div>
|
2026-03-10 15:45:01 +00:00
|
|
|
}
|
|
|
|
|
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)
|
2026-03-10 15:12:00 +00:00
|
|
|
{
|
2026-03-10 15:45:01 +00:00
|
|
|
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;
|
2026-03-10 15:12:00 +00:00
|
|
|
}
|
2026-03-10 15:45:01 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case AssistantComponentType.TEXT:
|
|
|
|
|
if (component is AssistantText assistantText)
|
2026-02-10 15:12:59 +00:00
|
|
|
{
|
2026-03-10 15:45:01 +00:00
|
|
|
var text = assistantText;
|
|
|
|
|
<MudText Typo="Typo.body1" Class='@MergeClass(text.Class, "mb-3")' Style="@this.GetOptionalStyle(text.Style)">@text.Content</MudText>
|
2026-02-10 15:12:59 +00:00
|
|
|
}
|
2026-03-10 15:45:01 +00:00
|
|
|
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
|
|
|
{
|
2026-03-10 15:45:01 +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
|
|
|
}
|
2026-03-10 15:45:01 +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")" />
|
2026-03-09 12:23:35 +00:00
|
|
|
</MudItem>
|
2026-03-10 15:45:01 +00:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
</text>;
|
2026-03-10 17:57:48 +00:00
|
|
|
|
|
|
|
|
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(';')}");
|
|
|
|
|
}
|
2026-02-23 14:01:00 +00:00
|
|
|
}
|