-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathApi.cs
More file actions
207 lines (171 loc) · 5.9 KB
/
Copy pathApi.cs
File metadata and controls
207 lines (171 loc) · 5.9 KB
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
using CodeEffects.Demo.Asp.AdaptiveSource;
using CodeEffects.Rule.Common.Models;
using CodeEffects.Rule.Editor;
using CodeEffects.Rule.Editor.Client;
using CodeEffects.Rule.Editor.Models;
using CodeEffects.Rule.Engine;
using Microsoft.AspNetCore.Mvc;
namespace CodeEffects.Demo.Asp;
public static class Api
{
public static void MapEndpoints(this WebApplication app)
{
// Returns client settings for the editor
app.MapGet("/api/settings", () =>
{
var settings = new Settings();
var editor = GetControl(settings);
// Set all evaluation type rules to be used by the
// editor as bool properties (i.e. reusable rules) in menus
editor.ContextMenuRules = [.. RuleStorage.Storage
.Where(r => r.Value.Eval)
.Select(r => new MenuItem(r.Key, r.Value.Name))];
// Load all available rules into the Rules menu of the Toolbar (if Toolbar is used on the client)
editor.ToolBarRules = [.. RuleStorage.Storage.Select(r => new MenuItem(r.Key, r.Value.Name))];
// Set UI settings for the editor (Help String, etc)
settings.GlobalData = editor.GetGlobalData();
// Set the source-related settings for the editor
settings.EditorData = editor.GetEditorData();
return Results.Ok(settings);
});
app.MapPost("/api/menu", (MenuRequest req) =>
{
var editor = GetControl(new Settings());
var data = editor.GetAdaptiveData(req.Type, req.Context); // Load rule context into the editor
return Results.Ok(data);
});
// Loads a rule by its ID
app.MapGet("/api/load/{ruleId}", (string ruleId) =>
{
RuleStorage.Storage.TryGetValue(ruleId, out var value);
var editor = GetControl(new Settings());
editor.LoadRuleXml(value?.Xml);
return Results.Ok(editor.GetRuleData());
});
app.MapPost("/api/save", ([FromBody] string rule) =>
{
var editor = GetControl(new Settings());
editor.LoadRuleData(rule);
var response = new Response();
if(editor.IsEmpty)
{
response.IsRuleEmpty = true;
}
else if(!editor.IsValid)
{
response.IsRuleValid = false;
// Load invalid elements into the editor
response.ClientInvalidData = editor.GetInvalidData();
}
else
{
RuleStorage.Storage[editor.Rule.ID] = new AdaptiveSource.Rule
{
Eval = editor.Rule.IsEvalType.HasValue && editor.Rule.IsEvalType.Value,
Name = editor.Rule.Name,
Xml = editor.GetRuleXml()
};
response.Output = editor.Rule.ID;
}
return Results.Ok(response);
});
app.MapPost("/api/delete", ([FromBody] string ruleId) =>
{
RuleStorage.Storage.TryRemove(ruleId, out _);
});
app.MapPost("/api/evaluate", ([FromBody] string data) =>
{
var editor = GetControl(new Settings());
editor.RuleNameIsRequired = false; // No need to validate the rule name
editor.LoadRuleData(data); // Load rule data into the editor
var response = new Response();
if(editor.IsEmpty)
{
response.IsRuleEmpty = true;
response.Output = "The rule is empty";
}
else if(!editor.IsValid)
{
response.IsRuleValid = false;
response.Output = "The rule is invalid";
// Load invalid rule elements into the editor
response.ClientInvalidData = editor.GetInvalidData();
}
else
{
// Init the source object with some test data
var patient = new Patient
{
FirstName = "John",
LastName = "Smith",
DOB = new DateTime(1990, 04, 22),
Gender = Gender.Male,
EducationID = "Two",
IsActive = true,
Salary = 100000,
TotalInvoiced = 2500,
TotalPaid = 800,
Home = new Address
{
Street = "123 Main Dr",
City = "Atlanta",
State = State.Georgia,
Zip = "30530"
},
Work = new Address
{
Street = "999 Imaginary Str",
City = "Roswel",
State = State.Georgia,
Zip = "30075"
},
Nicknames = new List<string> { "Jonny", "Dude" },
Visits = new List<Visit> { new Visit { Date = new DateTime(2026, 02, 15), DoctorID = "xyz", ID = 101, Type = VisitType.CheckUp } },
Hospitals = new List<Hospital> { new Hospital { ID = 202, ManagerID = 29, Name = "Northside Hospital" } }
};
// Get the rule XML
var ruleXml = editor.GetRuleXml();
// At this point, the evaluator no longer depends on the editor and can reside in an entirely separate
// project or application. It only requires the XML representation of your rule(s) and the data object
// against which the rules will be evaluated. In this demo, the editor is used solely as a convenient
// way to generate and provide the rule XML.
// Create an instanve of the Evaluator
// This compiles your rule into IL
var ev = new Evaluator<Patient>(ruleXml);
// Evaluate the rule
bool success = ev.Evaluate(patient);
// Output the evaluation result (all action methods set the Patient.Output value)
response.Output = success ?
"The rule evaluated to TRUE. " + patient.Output :
"The rule evaluated to FALSE. " + patient.Output;
}
return Results.Ok(response);
});
}
private static Control GetControl(Settings settings)
{
var editor = new Control();
// Set the editor to use the Adaptive Source
editor.MenuProvider = new MenuProvider(typeof(Patient));
editor.EvaluationMode = settings.Mode;
return editor;
}
}
public class Settings
{
public string? GlobalData { get; set; }
public string? EditorData { get; set; }
public EvaluationMode Mode { get; set; } = EvaluationMode.Execution;
}
public class MenuRequest
{
public RuleSectionType Type { get; set; } = RuleSectionType.Conditions;
public Context? Context { get; set; }
}
public class Response
{
public bool IsRuleEmpty { get; set; } = false;
public bool IsRuleValid { get; set; } = true;
public string? Output { get; set; }
public string? ClientInvalidData { get; set; }
}