about summary refs log tree commit diff
path: root/MatrixRoomUtils.Web/Shared/PolicyEditorComponents/PolicyEditorModal.razor
blob: 4fd151d13c9d0b65f25b4a6c9f30ffd398a7c6d4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
@using LibMatrix.EventTypes.Spec.State.Policy
@using System.Reflection
@using ArcaneLibs.Attributes
@using ArcaneLibs.Extensions
@using LibMatrix
@using System.Collections.Frozen
@using LibMatrix.EventTypes
<ModalWindow Title="@((string.IsNullOrWhiteSpace(PolicyEvent.EventId) ? "Creating new " : "Editing ") + (PolicyEvent.MappedType.GetFriendlyNameOrNull()?.ToLower() ?? "event"))"
             OnCloseClicked="@OnClose" X="60" Y="60" MinWidth="300">
    @{
        var policyData = (PolicyEvent.TypedContent as PolicyRuleEventContent)!;
    }
    @if (string.IsNullOrWhiteSpace(PolicyEvent.EventId)) {
        <span>Policy type:</span>
        <select @bind="@PolicyEvent.Type">
            <option>Select a value</option>
            @foreach (var (type, mappedType) in PolicyTypes) {
                <option value="@type">@mappedType.GetFriendlyName().ToLower()</option>
            }
        </select>
    }


    @{
        // enumerate all properties with friendly name
        var props = PolicyEvent.MappedType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            .Where(x => (x.GetFriendlyNameOrNull() ?? x.GetJsonPropertyNameOrNull()) is not null)
            .Where(x => x.GetCustomAttribute<TableHideAttribute>() is null)
            .ToFrozenSet();
        var propNames = props.Select(x => x.GetFriendlyNameOrNull() ?? x.GetJsonPropertyName()!).ToFrozenSet();
    }
    <table>
        <thead style="border-bottom: solid #ffffff44 1px;">
            <tr>
                <th>Property</th>
                <th>Value</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var prop in props) {
                <tr>
                    <td style="padding-right: 8px;">
                        <span>@prop.GetFriendlyName()</span>
                        @if (Nullable.GetUnderlyingType(prop.PropertyType) is not null) {
                            <span style="color: red;">*</span>
                        }
                    </td>
                    @{
                        var getter = prop.GetGetMethod();
                        var setter = prop.GetSetMethod();
                    }
                    @switch (Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType) {
                        case Type t when t == typeof(string):
                            <FancyTextBox Value="@(getter?.Invoke(policyData, null) as string)" ValueChanged="@(e => { Console.WriteLine($"{prop.Name} ({setter is not null}) -> {e}"); setter?.Invoke(policyData, [e]); StateHasChanged(); })"></FancyTextBox>
                            break;
                        default:
                            <p style="color: red;">Unsupported type: @prop.PropertyType</p>
                            break;
                    }
                </tr>
            }
        </tbody>
    </table>
    <br/>
    <pre>
        @PolicyEvent.ToJson(true, false)
    </pre>
    <LinkButton OnClick="@(() => { OnClose.Invoke(); return Task.CompletedTask; })">Cancel</LinkButton>
    <LinkButton OnClick="@(() => { OnSave.Invoke(PolicyEvent); return Task.CompletedTask; })">Save</LinkButton>
    @* <span>Target entity: </span> *@
    @* <FancyTextBox @bind-Value="@policyData.Entity"></FancyTextBox><br/> *@
    @* <span>Reason: </span> *@
    @* <FancyTextBox @bind-Value="@policyData.Reason"></FancyTextBox> *@
</ModalWindow>

@code {

    [Parameter]
    public StateEventResponse? PolicyEvent { get; set; }

    [Parameter]
    public required Action OnClose { get; set; }
    
    [Parameter]
    public required Action<StateEventResponse> OnSave { get; set; }

    private static FrozenSet<Type> KnownPolicyTypes = StateEvent.KnownStateEventTypes.Where(x => x.IsAssignableTo(typeof(PolicyRuleEventContent))).ToFrozenSet();

    private static Dictionary<string, Type> PolicyTypes = KnownPolicyTypes
        .ToDictionary(x => x.GetCustomAttributes<MatrixEventAttribute>().First(y => !string.IsNullOrWhiteSpace(y.EventName)).EventName, x => x);

}