XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEWorkflow

【WinUI】XFE基于windows的工作流

公开
关注 0 Fork 0 Star 0
UTF-8
using XFEWorkflow.Abstractions;
using XFEWorkflow.Infrastructure.Execution;
using XFEWorkflow.Services;

namespace XFEWorkflow.Controls;

public sealed class WorkflowLibrary : UserControl
{
    private readonly TextBox search = new() { PlaceholderText = "搜索所有工作流", Margin = new(0, 0, 0, 8) };
    private readonly StackPanel items = new() { Spacing = 6 };
    private IReadOnlyList<WorkflowDefinition> workflows = [];
    public event Action<WorkflowDefinition, bool>? Invoked;
    public WorkflowLibrary()
    {
        var root = new Grid(); root.RowDefinitions.Add(new() { Height = GridLength.Auto }); root.RowDefinitions.Add(new());
        root.Children.Add(search); var scroll = new ScrollViewer { Content = items, MaxHeight = 280, HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled }; Grid.SetRow(scroll, 1); root.Children.Add(scroll); Content = root;
        search.TextChanged += (_, _) => Render();
    }
    public void SetWorkflows(IEnumerable<WorkflowDefinition> source) { workflows = source.ToArray(); Render(); }
    private void Render()
    {
        var expanded = items.Children.OfType<Expander>().Where(x => x.IsExpanded).Select(x => x.Tag as string).ToHashSet();
        items.Children.Clear();
        foreach (var workflow in workflows.Where(x => x.Name.Contains(search.Text.Trim(), StringComparison.OrdinalIgnoreCase)))
        {
            var content = new StackPanel { Spacing = 8 };
            var triggers = AppServices.Current.Scheduler.StatusFor(workflow);
            content.Children.Add(new TextBlock { Text = workflow.Kind == WorkflowKind.CSharp ? "C# 代码工作流" : "图形化工作流", Opacity = .7, FontSize = 12 });
            if (triggers.Count == 0) content.Children.Add(new TextBlock { Text = "仅手动运行 · 添加触发器即可自动执行", TextWrapping = TextWrapping.Wrap, FontSize = 12 });
            foreach (var trigger in triggers) content.Children.Add(new TextBlock { Text = trigger.Label + (!trigger.Enabled ? " · 已停用" : trigger.Error is { } error ? " · " + error : AppServices.Current.Scheduler.IsSuspended ? " · 调度已暂停" : trigger.NextRun is { } next ? $" · 下次 {next.ToLocalTime():MM-dd HH:mm:ss}" : " · 监听中"), TextWrapping = TextWrapping.Wrap, FontSize = 12 });
            var actions = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 8 };
            var open = new Button { Content = "打开工作流" }; open.Click += (_, _) => Invoked?.Invoke(workflow, false);
            var configure = new Button { Content = "查看触发节点" }; configure.Click += (_, _) => Invoked?.Invoke(workflow, true);
            actions.Children.Add(open); actions.Children.Add(configure); content.Children.Add(actions);
            var header = new StackPanel { Orientation = Orientation.Horizontal, Spacing = 10 };
            header.Children.Add(new FontIcon { Glyph = "\uEF90", FontSize = 16 });
            header.Children.Add(new TextBlock { Text = workflow.Name, TextTrimming = TextTrimming.CharacterEllipsis });
            header.Children.Add(new TextBlock { Text = $"{triggers.Count(x => x.Enabled)} 个触发器", Opacity = .6, FontSize = 12 });
            items.Children.Add(new Expander { Header = header, Tag = workflow.Id, Content = content, IsExpanded = expanded.Contains(workflow.Id), HorizontalAlignment = HorizontalAlignment.Stretch, HorizontalContentAlignment = HorizontalAlignment.Stretch });
        }
        if (items.Children.Count == 0) items.Children.Add(new TextBlock { Text = "没有匹配的工作流", Margin = new(12) });
    }
}