1 <% include('/elements/header.html', "$action Export", '', ' onLoad="visualize()"') %>
3 <% include('/elements/error.html') %>
5 <SCRIPT TYPE="text/javascript">
6 function svc_machine_changed (what, layer) {
8 var machine = document.getElementById(layer + "_machine");
9 var part_export_machine =
10 document.getElementById(layer + "_part_export_machine");
11 if ( what.value == 'Y' ) {
12 machine.disabled = true;
13 part_export_machine.disabled = false;
14 } else if ( what.value == 'N' ) {
15 machine.disabled = false;
16 part_export_machine.disabled = true;
21 function part_export_machine_changed (what, layer) {
22 var select_default = document.getElementById(layer + '_default_machine');
23 var selected = select_default.value;
24 select_default.options.length = 0;
25 var choices = what.value.split("\n");
26 for (var i = 0; i < choices.length; i++) {
27 select_default.options[i] = new Option(choices[i]);
29 select_default.value = selected;
34 <INPUT TYPE="hidden" NAME="exportnum" VALUE="<% $part_export->exportnum %>">
36 <% ntable("#cccccc",2) %>
38 <TD ALIGN="right">Export name</TD>
40 <INPUT TYPE="text" NAME="exportname" VALUE="<% $part_export->exportname %>">
44 <TD ALIGN="right">Export</TD>
45 <TD><% $widget->html %>
47 <% include('/elements/footer.html') %>
51 unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
53 #if ( $cgi->param('clone') && $cgi->param('clone') =~ /^(\d+)$/ ) {
54 # $cgi->param('clone', $1);
56 # $cgi->param('clone', '');
59 my($query) = $cgi->keywords;
62 if ( $cgi->param('error') ) {
63 $part_export = new FS::part_export ( {
64 map { $_, scalar($cgi->param($_)) } fields('part_export')
66 } elsif ( $cgi->param('exportnum') ) {
67 $part_export = qsearchs('part_export', { 'exportnum' => $cgi->param('exportnum') } );
68 } elsif ( $query =~ /^(\d+)$/ ) {
69 $part_export = qsearchs('part_export', { 'exportnum' => $1 } );
71 $part_export = new FS::part_export;
73 $action ||= $part_export->exportnum ? 'Edit' : 'Add';
75 #my $exports = FS::part_export::export_info($svcdb);
76 my $exports = FS::part_export::export_info();
78 tie my %layers, 'Tie::IxHash',
80 map { $_ => "$_ - ". $exports->{$_}{desc} }
85 my $widget = new HTML::Widgets::SelectLayers(
86 'selected_layer' => $part_export->exporttype,
87 'options' => \%layers,
88 'form_name' => 'dummy',
89 'form_action' => 'process/part_export.cgi',
90 'form_text' => [qw( exportnum exportname )],
91 'html_between' => "</TD></TR></TABLE>\n",
92 'layer_callback' => sub {
94 # create 'config_element' to generate the whole layer with a Mason component
95 if ( my $include = $exports->{$layer}{config_element} ) {
96 # might need to adjust the scope of this at some point
97 return $m->scomp($include,
98 part_export => $part_export,
100 export_info => $exports->{$layer}
103 my $html = qq!<INPUT TYPE="hidden" NAME="exporttype" VALUE="$layer">!.
107 $html .= '<TR><TD ALIGN="right">Description</TD><TD BGCOLOR=#ffffff>'.
108 $exports->{$layer}{notes}. '</TD></TR>';
110 if ( $exports->{$layer}{no_machine} ) {
111 $html .= '<INPUT TYPE="hidden" NAME="machine" VALUE="">'.
112 '<INPUT TYPE="hidden" NAME="svc_machine" VALUE=N">';
114 $html .= '<TR><TD ALIGN="right">Hostname or IP</TD><TD>';
115 my $machine = $part_export->machine;
116 if ( $exports->{$layer}{svc_machine} ) {
117 my( $N_CHK, $Y_CHK) = ( 'CHECKED', '' );
118 my( $machine_DISABLED, $pem_DISABLED) = ( '', 'DISABLED' );
119 my @part_export_machine;
120 my $default_machine = '';
121 if ( $cgi->param('svc_machine') eq 'Y'
122 || $machine eq '_SVC_MACHINE'
127 $machine_DISABLED = 'DISABLED';
130 @part_export_machine = $cgi->param('part_export_machine');
131 if (!@part_export_machine) {
132 @part_export_machine =
135 $part_export->part_export_machine;
138 $cgi->param('default_machine_name')
139 || $part_export->default_export_machine;
141 my $oc = qq(onChange="svc_machine_changed(this, '$layer')");
143 <INPUT TYPE="radio" NAME="svc_machine" VALUE="N" $N_CHK $oc>
144 <INPUT TYPE="text" NAME="machine" ID="${layer}_machine" VALUE="$machine" $machine_DISABLED>
146 <INPUT TYPE="radio" NAME="svc_machine" VALUE="Y" $Y_CHK $oc>
147 <DIV STYLE="display:inline-block; vertical-align: top; text-align: right">
148 Selected in each customer service from these choices:
149 <TEXTAREA STYLE="vertical-align: top" NAME="part_export_machine"
150 ID="${layer}_part_export_machine"
151 onchange="part_export_machine_changed(this, '$layer')"
154 join("\n", @part_export_machine) .
159 <SELECT NAME="default_machine_name" ID="${layer}_default_machine">
161 foreach (@part_export_machine) {
162 $_ = encode_entities($_); # oh noes, XSS
163 my $sel = ($default_machine eq $_) ? ' SELECTED' : '';
164 $html .= qq!<OPTION VALUE="$_"$sel>$_</OPTION>\n!;
166 $html .= '</DIV></SELECT>'
168 $html .= qq(<INPUT TYPE="text" NAME="machine" VALUE="$machine">).
169 '<INPUT TYPE="hidden" NAME="svc_machine" VALUE=N">';
171 $html .= "</TD></TR>";
176 foreach my $option ( keys %{$exports->{$layer}{options}} ) {
177 my $optinfo = $exports->{$layer}{options}{$option};
178 die "Retreived non-ref export info option from $layer export: $optinfo"
179 unless ref($optinfo);
180 my $label = $optinfo->{label};
181 my $type = defined($optinfo->{type}) ? $optinfo->{type} : 'text';
182 my $value = $cgi->param($option)
183 || ( $part_export->exportnum && $part_export->option($option) )
184 || ( (exists $optinfo->{default} && !$part_export->exportnum)
185 ? $optinfo->{default}
189 #handle these with post_config_element
190 next if $type eq 'custom';
192 if ( $type eq 'title' ) {
193 $html .= qq!<TR><TH COLSPAN=1 ALIGN="right"><FONT SIZE="+1">! .
199 # 'freeform': disables table formatting of options. Instead, each
200 # option can define "before" and "after" strings which are inserted
201 # around the selector.
202 my $freeform = $optinfo->{freeform};
204 $html .= $optinfo->{before} || '';
207 $html .= qq!<TR><TD ALIGN="right">$label</TD><TD>!;
209 if ( $type eq 'select' ) {
211 # 'select' options can specify options one of two ways:
212 # the "preferred" way:
213 # options: arrayref of allowed option values
214 # option_labels: hashref of option value => label
215 # OR the weird and semi-deprecated way:
216 # option_values: coderef to return a list of allowed option values
217 # option_label: coderef to take an option value and return its label
219 my $size = defined($optinfo->{size}) ? " SIZE=" . $optinfo->{size} : '';
220 my $multi = ($optinfo->{multi} || $optinfo->{multiple})
222 $html .= qq!<SELECT NAME="$option"$multi$size>!;
223 my @values = split '\s+', $value if $multi;
225 if (defined($optinfo->{option_values})) {
226 my $valsub = $optinfo->{option_values};
227 @options = &$valsub();
228 } elsif (defined($optinfo->{options})) {
229 @options = @{$optinfo->{options}};
231 foreach my $select_option ( @options ) {
232 #if ( ref($select_option) ) {
234 my $selected = ($multi ? grep {$_ eq $select_option} @values : $select_option eq $value ) ? ' SELECTED' : '';
235 my $label = $select_option;
236 if ( defined $optinfo->{option_label} ) {
237 my $labelsub = $optinfo->{option_label};
238 $label = &$labelsub($select_option);
239 } elsif ( defined $optinfo->{option_labels} ) {
240 if (exists $optinfo->{option_labels}->{$select_option}) {
241 $label = $optinfo->{option_labels}->{$select_option};
245 $html .= qq!<OPTION VALUE="$select_option"$selected>!.
249 $html .= '</SELECT>';
250 } elsif ( $type eq 'textarea' ) {
251 $html .= qq!<TEXTAREA NAME="$option" COLS=80 ROWS=8 WRAP="virtual">!.
252 encode_entities($value). '</TEXTAREA>';
253 } elsif ( $type eq 'text' ) {
254 $html .= qq!<INPUT TYPE="text" NAME="$option" VALUE="!. #"
255 encode_entities($value). '" SIZE=64>';
256 } elsif ( $type eq 'checkbox' ) {
257 $html .= qq!<INPUT TYPE="checkbox" NAME="$option" VALUE="1"!;
258 $html .= ' CHECKED' if $value;
261 $html .= "unknown type $type";
264 $html .= $optinfo->{after} || '';
267 $html .= '</TD></TR>';
271 if ( $exports->{$layer}{nas} and qsearch('nas',{}) ) {
272 # show NAS checkboxes
273 $html .= '<TR><TD ALIGN="right">Export RADIUS clients</TD><TD>';
275 $html .= include('/elements/checkboxes-table.html',
276 'source_obj' => $part_export,
277 'link_table' => 'export_nas',
278 'target_table' => 'nas',
280 'name_callback' => sub {
281 $_[0]->shortname . ' (' . $_[0]->nasname . ')',
284 'target_link' => $p.'edit/nas.html?',
287 $html .= '</TD></TR>';
290 $html .= '<TR><TD ALIGN="right">Do not suspend services</TD>' .
291 '<TD><INPUT TYPE="checkbox" NAME="no_suspend" VALUE="Y"';
292 $html .= ' CHECKED' if $part_export->no_suspend eq 'Y';
293 $html .= '></TD></TR>';
295 foreach my $script ( keys %{$exports->{$layer}{scripts}} ) {
296 $html .= '<TR><TD ALIGN="left" COLSPAN=2>' .
297 include('/elements/progress-init.html',
298 $part_export->exporttype,
299 [ $script.'_exportnum' ],
300 rooturl().'view/svc_export/run_script.cgi',
302 'error_url' => rooturl().$exports->{$layer}{scripts}{$script}->{error_url}."exportnum=".$part_export->{Hash}->{exportnum},
303 'reload_with_error' => '1',
304 'url' => rooturl().'edit/part_export.cgi?'.$part_export->{Hash}->{exportnum},
305 'message' => $exports->{$layer}{scripts}{$script}->{success_message},
309 '<INPUT TYPE="hidden" NAME="'.$script.'_exportnum" VALUE="'.$part_export->{Hash}->{exportnum}.'">
310 <A HREF="#" onClick="'.$script.'process();">'.$exports->{$layer}{scripts}{$script}->{html_label}.'</A></TD></TR>';
315 # false laziness with config_element above
316 # create 'post_config_element' to generate the whole layer with a Mason component
317 if ( my $include = $exports->{$layer}{post_config_element} ) {
318 # might need to adjust the scope of this at some point
319 $html .= $m->scomp($include,
320 part_export => $part_export,
322 export_info => $exports->{$layer}
326 $html .= '<INPUT TYPE="hidden" NAME="options" VALUE="'.
327 join(',', keys %{$exports->{$layer}{options}} ). '">';
329 $html .= '<INPUT TYPE="hidden" NAME="nodomain" VALUE="'.
330 $exports->{$layer}{nodomain}. '">';
332 $html .= '<INPUT TYPE="submit" VALUE="'.
333 ( $part_export->exportnum ? "Apply changes" : "Add export" ).