35
36:- module(swish_dashboard,
37 [ parameters/1 38 ]). 39:- use_module(library(pengines)). 40:- use_module(library(apply)). 41:- use_module(library(error)). 42:- use_module(library(debug)). 43:- use_module(library(option)). 44:- use_module(library(lists)). 45:- use_module(library(http/html_write)). 46
47:- use_module(bootstrap). 48:- use_module(form). 49
54
73
74parameters(List) :-
75 include(not_filled, List, ToFill),
76 debug(dashboard(param), 'ToFill: ~p', [ToFill]),
77 fill(ToFill).
78
79not_filled(Var) :-
80 var(Var), !.
81not_filled(Var:_) :-
82 var(Var).
83
84fill([]) :-
85 !.
86fill(NotFilled) :-
87 maplist(input, NotFilled, FieldWidgets),
88 !,
89 buttons(Buttons),
90 append(FieldWidgets, Buttons, Widgets),
91 html_string(\bt_form(Widgets,
92 [ class('form-horizontal'),
93 label_columns(sm-3)
94 ]), HTML),
95 Prompt = _{ type: form,
96 html: HTML
97 },
98 pengine_input(Prompt, Reply),
99 debug(dashboard(param), 'Reply = ~p', [Reply]),
100 bind_form_reply(NotFilled, Reply).
101
102buttons(
103 [ button_group(
104 [ button(run, submit,
105 [ type(primary),
106 data([action(run)])
107 ]),
108 button(cancel, button,
109 [ type(danger),
110 data([action(cancel)])
111 ])
112 ],
113 [])
114 ]).
115
116
117bind_form_reply(_NotFilled, cancel) :-
118 !,
119 fail.
120bind_form_reply(NotFilled, Reply) :-
121 maplist(form_field, NotFilled, Fields),
122 validate_form(Reply, Fields).
123
124form_field(Var:Opts, field(Name, Var, [Type|Extra])) :-
125 opt_list(Opts, Options),
126 option(name(Name), Options),
127 option(type(Type), Options),
128 ( option(default(Default), Options)
129 -> Extra = [default(Default)]
130 ; Extra = []
131 ).
132
133
137
138input(Var, Input) :-
139 var(Var),
140 !,
141 input(Var:[], Input).
142input(_Var:Opts, Input) :-
143 opt_list(Opts, Options),
144 select_option(type(Type), Options, Options1),
145 select_option(name(Name), Options1, Options2),
146 input(Type, Name, Options2, Input).
147
148input(Type, Name, Options,
149 input(Name, text,
150 [ data('search-in'=Set),
151 class(typeahead)
152 | Options
153 ])) :-
154 typeahead(Type, Set),
155 !.
156input(string, Name, Options,
157 textarea(Name, Options)) :-
158 option(rows(_Rows), Options),
159 !.
160input(oneof(Values), Name, Options,
161 select(Name, Values, Options)) :-
162 !.
163input(_, Name, Options,
164 input(Name, text, Options)).
165
170
171typeahead(user, users).
172
173:- multifile error:has_type/2. 174
175error:has_type(user, _Dict) :-
176 true.
177
178
179 182
183:- multifile
184 swish:goal_expansion/2. 185
186swish:goal_expansion(parameters(Params0), parameters(Params)) :-
187 add_var_names(Params0, 1, Params),
188 Params0 \== Params.
189
190add_var_names([], _, []).
191add_var_names([H0|T0], N0, [H|T]) :-
192 add_var_name(H0, N0, H),
193 N is N0 + 1,
194 add_var_names(T0, N, T).
195
196
197add_var_name(Var:Options, _, Var:Options) :-
198 opt(name(_), Options),
199 !.
200add_var_name(Var:Options, N, Var:name(Name)+Options) :-
201 ( var_property(Var, name(Name))
202 -> true
203 ; atom_concat('Param', N, Name)
204 ).
205
206
207 210
211opt_list(Opts, List) :-
212 phrase(opts(Opts), List0),
213 add_type(List0, List).
214
215opts(OptA+OptB) -->
216 !,
217 opts(OptA),
218 opts(OptB).
219opts(Opt) -->
220 [Opt].
221
222add_type(Options, Options) :-
223 option(type(_), Options), !.
224add_type(List, Options) :-
225 select(Type, List, Options1),
226 current_type(Type, _, _),
227 !,
228 Options = [type(Type)|Options1].
229add_type(Options, [type(term)|Options]).
230
231
235
236opt(Opt, Opts) :-
237 \+ functor(Opts, +, 2), !,
238 Opt = Opts.
239opt(Opt, Opt+_).
240opt(Opt, _+Opts) :-
241 opt(Opt, Opts).
242
243html_string(HTML, String) :-
244 phrase(html(HTML), Tokens),
245 !,
246 delete(Tokens, nl(_), SingleLine),
247 with_output_to(string(String), print_html(SingleLine)).
248
249
250 253
254:- multifile sandbox:safe_primitive/1. 255
256sandbox:safe_primitive(swish_dashboard:parameters(_))