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
70
71parameters(List) :-
72 include(not_filled, List, ToFill),
73 debug(dashboard(param), 'ToFill: ~p', [ToFill]),
74 fill(ToFill).
75
76not_filled(Var:_) :-
77 var(Var).
78
79fill([]) :-
80 !.
81fill(NotFilled) :-
82 maplist(input, NotFilled, FieldWidgets),
83 !,
84 buttons(Buttons),
85 append(FieldWidgets, Buttons, Widgets),
86 html_string(\bt_form(Widgets,
87 [ class('form-horizontal'),
88 label_columns(sm-3)
89 ]), HTML),
90 Prompt = _{ type: form,
91 html: HTML
92 },
93 pengine_input(Prompt, Reply),
94 bind_form_reply(NotFilled, Reply).
95
96buttons(
97 [ button_group(
98 [ button(run, submit,
99 [ type(primary),
100 data([action(run)])
101 ]),
102 button(cancel, button,
103 [ type(danger),
104 data([action(cancel)])
105 ])
106 ],
107 [])
108 ]).
109
110
111bind_form_reply(_NotFilled, cancel) :-
112 !,
113 fail.
114bind_form_reply(NotFilled, Reply) :-
115 maplist(form_field, NotFilled, Fields),
116 validate_form(Reply, Fields).
117
118form_field(Var:Opts, field(Name, Var, [Type|Extra])) :-
119 opt_list(Opts, Options),
120 option(name(Name), Options),
121 option(type(Type), Options),
122 ( option(default(Default), Options)
123 -> Extra = [default(Default)]
124 ; Extra = []
125 ).
126
127
131
132input(_Var:Opts, Input) :-
133 opt_list(Opts, Options),
134 select_option(type(Type), Options, Options1),
135 select_option(name(Name), Options1, Options2),
136 input(Type, Name, Options2, Input).
137
138input(Type, Name, Options,
139 input(Name, text,
140 [ data('search-in'=Set),
141 class(typeahead)
142 | Options
143 ])) :-
144 typeahead(Type, Set),
145 !.
146input(string, Name, Options,
147 textarea(Name, Options)) :-
148 option(rows(_Rows), Options),
149 !.
150input(_, Name, Options,
151 input(Name, text, Options)).
152
157
158typeahead(user, users).
159
160:- multifile error:has_type/2. 161
162error:has_type(user, _Dict) :-
163 true.
164
165
166 169
170:- multifile
171 swish:goal_expansion/2. 172
173swish:goal_expansion(parameters(Params0), parameters(Params)) :-
174 add_var_names(Params0, 1, Params),
175 Params0 \== Params.
176
177add_var_names([], _, []).
178add_var_names([H0|T0], N0, [H|T]) :-
179 add_var_name(H0, N0, H),
180 N is N0 + 1,
181 add_var_names(T0, N, T).
182
183
184add_var_name(Var:Options, _, Var:Options) :-
185 opt(name(_), Options),
186 !.
187add_var_name(Var:Options, N, Var:name(Name)+Options) :-
188 ( var_property(Var, name(Name))
189 -> true
190 ; atom_concat('Param', N, Name)
191 ).
192
193
194 197
198opt_list(Opts, List) :-
199 phrase(opts(Opts), List0),
200 add_type(List0, List).
201
202opts(OptA+OptB) -->
203 !,
204 opts(OptA),
205 opts(OptB).
206opts(Opt) -->
207 [Opt].
208
209add_type(Options, Options) :-
210 option(type(_), Options), !.
211add_type(List, Options) :-
212 select(Type, List, Options1),
213 current_type(Type, _, _),
214 !,
215 Options = [type(Type)|Options1].
216add_type(Options, [type(term)|Options]).
217
218
222
223opt(Opt, Opts) :-
224 \+ functor(Opts, +, 2), !,
225 Opt = Opts.
226opt(Opt, Opt+_).
227opt(Opt, _+Opts) :-
228 opt(Opt, Opts).
229
230html_string(HTML, String) :-
231 phrase(html(HTML), Tokens),
232 !,
233 delete(Tokens, nl(_), SingleLine),
234 with_output_to(string(String), print_html(SingleLine)).
235
236
237 240
241:- multifile sandbox:safe_primitive/1. 242
243sandbox:safe_primitive(swish_dashboard:parameters(_))