diff --git a/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor b/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor index 75f769b9..7bf99ef9 100644 --- a/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor +++ b/app/MindWork AI Studio/Assistants/Dynamic/AssistantDynamic.razor @@ -20,7 +20,22 @@ else } @code { - private RenderFragment RenderChildren(IEnumerable children) => @ + private RenderFragment RenderSwitch(AssistantSwitch assistantSwitch) => @ + @(switchFields[assistantSwitch.Name] ? assistantSwitch.LabelOn : assistantSwitch.LabelOff) + ; +} + +@code {private RenderFragment RenderChildren(IEnumerable children) => @ @foreach (var child in children) { @this.RenderComponent(child) @@ -145,12 +160,11 @@ else 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 buttonClass = MergeClass(button.Class, ""); var style = this.GetOptionalStyle(button.Style); if (!button.IsIconButton) { -
@button.Text -
} else { @@ -314,23 +327,17 @@ else if (component is AssistantSwitch switchComponent) { var assistantSwitch = switchComponent; - var currentValue = this.switchFields[assistantSwitch.Name]; - var disabled = assistantSwitch.Disabled || this.IsSwitchActionRunning(assistantSwitch.Name); - - - @(currentValue ? assistantSwitch.LabelOn : assistantSwitch.LabelOff) - - + + if (string.IsNullOrEmpty(assistantSwitch.Label)) + { + @this.RenderSwitch(assistantSwitch) + } + else + { + + @this.RenderSwitch(assistantSwitch) + + } } break; case AssistantComponentType.HEADING: @@ -368,13 +375,16 @@ else @foreach (var item in list.Items) { + var iconColor = AssistantComponentPropHelper.GetColor(item.IconColor, Color.Default); + @if (item.Type == "LINK") { - @item.Text + @item.Text } else { - @item.Text + var icon = !string.IsNullOrEmpty(item.Icon) ? AssistantComponentPropHelper.GetIconSvg(item.Icon) : string.Empty; + @item.Text } } @@ -385,7 +395,6 @@ else { var colorPicker = assistantColorPicker; var variant = colorPicker.GetPickerVariant(); - var elevation = variant == PickerVariant.Static ? 6 : 0; var rounded = variant == PickerVariant.Static; @@ -397,8 +406,8 @@ else ShowModeSwitch="@colorPicker.ShowModeSwitch" PickerVariant="@variant" Rounded="@rounded" - Elevation="@elevation" - Style="@($"color: {this.colorPickerFields[colorPicker.Name]};")" + Elevation="@colorPicker.Elevation" + Style="@($"color: {this.colorPickerFields[colorPicker.Name]};{colorPicker.Style}")" Class="@MergeClass(colorPicker.Class, "mb-3")" /> } @@ -417,6 +426,7 @@ else Placeholder="@datePicker.Placeholder" HelperText="@datePicker.HelperText" DateFormat="@format" + Elevation="@datePicker.Elevation" PickerVariant="@AssistantComponentPropHelper.GetPickerVariant(datePicker.PickerVariant, PickerVariant.Static)" Variant="Variant.Outlined" Class='@MergeClass(datePicker.Class, "mb-3")' @@ -441,6 +451,7 @@ else HelperText="@dateRangePicker.HelperText" DateFormat="@format" PickerVariant="@AssistantComponentPropHelper.GetPickerVariant(dateRangePicker.PickerVariant, PickerVariant.Static)" + Elevation="@dateRangePicker.Elevation" Variant="Variant.Outlined" Class='@MergeClass(dateRangePicker.Class, "mb-3")' Style="@this.GetOptionalStyle(dateRangePicker.Style)" @@ -464,6 +475,7 @@ else TimeFormat="@format" AmPm="@timePicker.AmPm" PickerVariant="@AssistantComponentPropHelper.GetPickerVariant(timePicker.PickerVariant, PickerVariant.Static)" + Elevation="@timePicker.Elevation" Variant="Variant.Outlined" Class='@MergeClass(timePicker.Class, "mb-3")' Style="@this.GetOptionalStyle(timePicker.Style)"/> diff --git a/app/MindWork AI Studio/Plugins/assistants/README.md b/app/MindWork AI Studio/Plugins/assistants/README.md index fcc7c967..6074030b 100644 --- a/app/MindWork AI Studio/Plugins/assistants/README.md +++ b/app/MindWork AI Studio/Plugins/assistants/README.md @@ -130,7 +130,8 @@ Images referenced via the `plugin://` scheme must exist in the plugin directory | `TIME_PICKER` | `Name`, `Label` | `Value`, `Placeholder`, `HelperText`, `TimeFormat`, `AmPm`, `PickerVariant`, `UserPrompt`, `Class`, `Style` | [MudTimePicker](https://www.mudblazor.com/components/timepicker) | | `HEADING` | `Text` | `Level` | [MudText Typo="Typo."](https://www.mudblazor.com/components/typography) | | `TEXT` | `Content` | `None` | [MudText Typo="Typo.body1"](https://www.mudblazor.com/components/typography) | -| `LIST` | `Type`, `Text` | `Href` | [MudList](https://www.mudblazor.com/componentss/list) | +| `LIST` | `None` | `Items (LIST_ITEM)`, `Class`, `Style` | [MudList](https://www.mudblazor.com/componentss/list) | +| `LIST_ITEM` | `Type`, `Text` | `Href`, `Icon`, `IconColor` | [MudList](https://www.mudblazor.com/componentss/list) | | `IMAGE` | `Src` | `Alt`, `Caption`,`Src` | [MudImage](https://www.mudblazor.com/components/image) | | `BUTTON_GROUP` | `None` | `Variant`, `Color`, `Size`, `OverrideStyles`, `Vertical`, `DropShadow`, `Class`, `Style` | [MudButtonGroup](https://www.mudblazor.com/components/buttongroup) | | `LAYOUT_PAPER` | `None` | `Elevation`, `Height`, `MaxHeight`, `MinHeight`, `Width`, `MaxWidth`, `MinWidth`, `IsOutlined`, `IsSquare`, `Class`, `Style` | [MudPaper](https://www.mudblazor.com/components/paper) | @@ -402,9 +403,9 @@ More information on rendered components can be found [here](https://www.mudblazo - Use `Type = "SWITCH"` to render a boolean toggle. - Required props: - `Name`: unique state key used in prompt assembly and `BuildPrompt(input.fields)`. - - `Label`: visible label for the switch field. - `Value`: initial boolean state (`true` or `false`). - Optional props: + - `Label`: If set, renders the switch inside an outlines Box, otherwise renders it raw. Visible label for the switch field. - `OnChanged`: Lua callback invoked after the switch value changes. It receives the same `input` table as `BUTTON.Action(input)` and may return `{ fields = { ... } }` to update component state. The new switch value is already reflected in `input.fields[Name]`. - `Disabled`: defaults to `false`; disables user interaction while still allowing the value to be included in prompt assembly. - `UserPrompt`: prompt context text for this field. diff --git a/app/MindWork AI Studio/Plugins/assistants/plugin.lua b/app/MindWork AI Studio/Plugins/assistants/plugin.lua index 5d95d86c..ea9ecc7f 100644 --- a/app/MindWork AI Studio/Plugins/assistants/plugin.lua +++ b/app/MindWork AI Studio/Plugins/assistants/plugin.lua @@ -114,7 +114,7 @@ ASSISTANT = { ["Type"] = "SWITCH", ["Props"] = { ["Name"] = "", -- required - ["Label"] = "", -- required + ["Label"] = "", -- Switches render mode between boxed switch and normal switch ["Value"] = true, -- initial switch state ["OnChanged"] = function(input) -- optional; same input and return contract as BUTTON.Action(input) return nil @@ -297,13 +297,18 @@ ASSISTANT = { { ["Type"] = "LINK", -- required ["Text"] = "", - ["Href"] = "" -- required + ["Href"] = "", -- required + ["IconColor"] = "", }, { ["Type"] = "TEXT", -- required - ["Text"] = "" + ["Text"] = "", + ["Icon"] = "Icons.Material.Filled.HorizontalRule", + ["IconColor"] = "", } - } + }, + ["Class"] = "", + ["Style"] = "", } }, { diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantColorPicker.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantColorPicker.cs index 6a8680f7..e77a45eb 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantColorPicker.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantColorPicker.cs @@ -52,6 +52,12 @@ internal sealed class AssistantColorPicker : AssistantComponentBase get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.UserPrompt)); set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.UserPrompt), value); } + + public int Elevation + { + get => AssistantComponentPropHelper.ReadInt(this.Props, nameof(this.Elevation), 6); + set => AssistantComponentPropHelper.WriteInt(this.Props, nameof(this.Elevation), value); + } public string Class { diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDatePicker.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDatePicker.cs index f67fdac0..4be09a79 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDatePicker.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDatePicker.cs @@ -59,6 +59,12 @@ internal sealed class AssistantDatePicker : AssistantComponentBase get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.UserPrompt)); set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.UserPrompt), value); } + + public int Elevation + { + get => AssistantComponentPropHelper.ReadInt(this.Props, nameof(this.Elevation), 6); + set => AssistantComponentPropHelper.WriteInt(this.Props, nameof(this.Elevation), value); + } public string Class { diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDateRangePicker.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDateRangePicker.cs index 814b1184..f80db2dc 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDateRangePicker.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantDateRangePicker.cs @@ -65,6 +65,12 @@ internal sealed class AssistantDateRangePicker : AssistantComponentBase get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.UserPrompt)); set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.UserPrompt), value); } + + public int Elevation + { + get => AssistantComponentPropHelper.ReadInt(this.Props, nameof(this.Elevation), 6); + set => AssistantComponentPropHelper.WriteInt(this.Props, nameof(this.Elevation), value); + } public string Class { diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantListItem.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantListItem.cs index 43bd60e1..49b2864f 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantListItem.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantListItem.cs @@ -4,5 +4,7 @@ public class AssistantListItem { public string Type { get; set; } = "TEXT"; public string Text { get; set; } = string.Empty; + public string Icon { get; set; } = string.Empty; + public string IconColor { get; set; } = string.Empty; public string? Href { get; set; } } \ No newline at end of file diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantTimePicker.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantTimePicker.cs index 281d7a2b..17b610c6 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantTimePicker.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/AssistantTimePicker.cs @@ -65,6 +65,12 @@ internal sealed class AssistantTimePicker : AssistantComponentBase get => AssistantComponentPropHelper.ReadString(this.Props, nameof(this.UserPrompt)); set => AssistantComponentPropHelper.WriteString(this.Props, nameof(this.UserPrompt), value); } + + public int Elevation + { + get => AssistantComponentPropHelper.ReadInt(this.Props, nameof(this.Elevation), 6); + set => AssistantComponentPropHelper.WriteInt(this.Props, nameof(this.Elevation), value); + } public string Class { diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs index 7e083b12..88f4ea17 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/DataModel/ComponentPropSpecs.cs @@ -18,9 +18,9 @@ public static class ComponentPropSpecs ] ), [AssistantComponentType.BUTTON] = new( - required: ["Name", "Text", "Action"], + required: ["Name", "Action"], optional: [ - "IsIconButton", "Variant", "Color", "IsFullWidth", "Size", + "Text", "IsIconButton", "Variant", "Color", "IsFullWidth", "Size", "StartIcon", "EndIcon", "IconColor", "IconSize", "Class", "Style" ] ), @@ -44,10 +44,10 @@ public static class ComponentPropSpecs optional: ["ValidationMessage", "Class", "Style"] ), [AssistantComponentType.SWITCH] = new( - required: ["Name", "Label", "Value"], + required: ["Name", "Value"], optional: [ - "OnChanged", "LabelOn", "LabelOff", "LabelPlacement", "Icon", "IconColor", "UserPrompt", - "CheckedColor", "UncheckedColor", "Disabled", "Class", "Style", + "Label", "OnChanged", "LabelOn", "LabelOff", "LabelPlacement", "Icon", "IconColor", + "UserPrompt", "CheckedColor", "UncheckedColor", "Disabled", "Class", "Style", ] ), [AssistantComponentType.HEADING] = new( @@ -84,7 +84,7 @@ public static class ComponentPropSpecs [AssistantComponentType.DATE_PICKER] = new( required: ["Name", "Label"], optional: [ - "Value", "Placeholder", "HelperText", "DateFormat", "Color", + "Value", "Placeholder", "HelperText", "DateFormat", "Color", "Elevation", "PickerVariant", "UserPrompt", "Class", "Style" ] ), @@ -92,14 +92,14 @@ public static class ComponentPropSpecs required: ["Name", "Label"], optional: [ "Value", "PlaceholderStart", "PlaceholderEnd", "HelperText", "DateFormat", - "Color", "PickerVariant", "UserPrompt", "Class", "Style" + "Elevation", "Color", "PickerVariant", "UserPrompt", "Class", "Style" ] ), [AssistantComponentType.TIME_PICKER] = new( required: ["Name", "Label"], optional: [ "Value", "Placeholder", "HelperText", "TimeFormat", "AmPm", "Color", - "PickerVariant", "UserPrompt", "Class", "Style" + "Elevation", "PickerVariant", "UserPrompt", "Class", "Style" ] ), [AssistantComponentType.LAYOUT_ITEM] = new( diff --git a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs index 1df3bc69..d7a45658 100644 --- a/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs +++ b/app/MindWork AI Studio/Tools/PluginSystem/Assistants/PluginAssistants.cs @@ -1,6 +1,7 @@ using AIStudio.Tools.PluginSystem.Assistants.DataModel; using AIStudio.Tools.PluginSystem.Assistants.DataModel.Layout; using Lua; +using System.Text; namespace AIStudio.Tools.PluginSystem.Assistants; @@ -468,9 +469,20 @@ public sealed class PluginAssistants(bool isInternal, LuaState state, PluginType if (!table.TryGetValue("Type", out var typeVal) || !typeVal.TryRead(out var type)) return false; + + table.TryGetValue("Icon", out var iconVal); + iconVal.TryRead(out var icon); + icon ??= string.Empty; + table.TryGetValue("IconColor", out var iconColorVal); + iconColorVal.TryRead(out var iconColor); + iconColor ??= string.Empty; + + item.Text = text; item.Type = type; + item.Icon = icon; + item.IconColor = iconColor; if (table.TryGetValue("Href", out var hrefVal) && hrefVal.TryRead(out var href)) {