-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathinputStrings.ur
139 lines (118 loc) · 5.81 KB
/
inputStrings.ur
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
open Bootstrap
functor Make(M : sig
con const :: {Type}
con given :: {Type}
con fixed :: {Type}
con chosen :: {Unit}
constraint const ~ given
constraint (const ++ given) ~ fixed
constraint (const ++ given ++ fixed) ~ chosen
val const : $const
table tab : (const ++ given ++ fixed ++ mapU string chosen)
val chosenLabels : $(mapU string chosen)
val constFl : folder const
val givenFl : folder given
val chosenFl : folder chosen
val constInj : $(map sql_injectable const)
val givenInj : $(map sql_injectable given)
val givenEq : $(map eq given)
val textLabel : string
(* Authentication *)
val amGiven : transaction (option $given)
end) = struct
open M
val givenEq : eq $given = @Record.eq givenEq givenFl
type input = _
type a = _
con chosen' = mapU string chosen
val chosenFl' = @Folder.mp chosenFl
val chosenInj = @map0 [fn _ => sql_injectable string] (fn [u ::_] => _) chosenFl
fun create gv =
vs <- oneRow1 (SELECT tab.{{chosen'}}
FROM tab
WHERE {@@Sql.easy_where [#Tab] [const ++ given] [_] [_] [_] [_]
! ! (constInj ++ givenInj) (@Folder.concat ! constFl givenFl) (const ++ gv)});
vs <- @foldR [fn _ => string] [fn r => transaction $(mapU (id * source string) r)]
(fn [nm ::_] [u ::_] [r ::_] [[nm] ~ r] v acc =>
id <- fresh;
v <- source v;
vs <- acc;
return ({nm = (id, v)} ++ vs))
(return {}) chosenFl vs;
editing <- source False;
return {Given = gv, Values = vs, Editing = editing}
fun ensure gv =
user <- amGiven;
case user of
None => error <xml>Must be authenticated to access this page</xml>
| Some user =>
if user = gv then
return ()
else
error <xml>Wrong user to be accessing this page</xml>
fun choose gv ch =
ensure gv;
@@Sql.easy_update'' [const ++ given] [chosen'] [_] [fixed]
! ! (constInj ++ givenInj) chosenInj
(@Folder.concat ! constFl givenFl) chosenFl'
tab (const ++ gv) ch
fun render t = <xml>
<h2>
<button class="btn btn-secondary"
onclick={fn _ =>
exp <- get t.Editing;
set t.Editing (not exp)}>
<span dynClass={exp <- signal t.Editing;
return (if exp then
CLASS "glyphicon glyphicon-trash"
else
CLASS "glyphicon glyphicon-pencil-alt")}/>
</button>
{[textLabel]}
</h2>
<dyn signal={exp <- signal t.Editing;
return (if exp then
<xml><div>
{@mapX2 [fn _ => string] [fn _ => _ * source string] [body]
(fn [nm ::_] [u ::_] [r ::_] [[nm] ~ r] lab (id, src) => <xml>
<div class="form-group">
<label class="control-label" for={id}>{[lab]}</label>
<ctextbox id={id} class="form-control" source={src}/>
</div>
</xml>)
chosenFl' chosenLabels t.Values}
<button class="btn btn-primary"
value="Save"
onclick={fn _ =>
vs <- @foldR [fn _ => _ * source string]
[fn r => transaction $(mapU string r)]
(fn [nm ::_] [u ::_] [r ::_] [[nm] ~ r] (_, src) acc =>
v <- get src;
vs <- acc;
return ({nm = v} ++ vs))
(return {}) chosenFl t.Values;
set t.Editing False;
rpc (choose t.Given vs)}/>
</div></xml>
else
<xml><div>
{@mapX2 [fn _ => string] [fn _ => _ * source string] [body]
(fn [nm ::_] [u ::_] [r ::_] [[nm] ~ r] lab (id, src) => <xml>
<div class="form-group">
<label class="control-label" for={id}>{[lab]}</label>
<div id={id}>
<dyn signal={src <- signal src; return <xml>{[src]}</xml>}/>
</div>
</div>
</xml>)
chosenFl chosenLabels t.Values}
</div></xml>)}/>
</xml>
fun notification _ _ = <xml></xml>
fun buttons _ _ = <xml></xml>
fun ui x = {Create = create x,
Onload = fn _ => return (),
Render = fn _ => render,
Notification = notification,
Buttons = buttons}
end