new tower/sector UI, mapping features, and network monitoring, #37802
[freeside.git] / httemplate / elements / tr-tower_sectors.html
1 <%init>
2 my %opt = @_;
3 my $tower = $opt{'object'};
4 my $towernum = $tower->towernum;
5 my $cgi = $opt{'cgi'};
6
7 my $tabcounter = 0;
8
9 my @fields = qw(
10   sectorname ip_addr height freq_mhz direction width tilt v_width db_high
11   db_low sector_range
12 );
13
14 my @sectors;
15 if ( $cgi->param('error') ) {
16   foreach my $k ($cgi->param) {
17     if ($k =~ /^sectornum\d+$/) {
18       my $sectornum = $cgi->param($k);
19       my $sector = FS::tower_sector->new({
20         'sectornum' => $sectornum,
21         'towernum'  => $towernum,
22         map { $_ => scalar($cgi->param($k.'_'.$_)) } @fields,
23       });
24       push @sectors, $sector if length($sector->sectorname);
25     }
26   }
27 } elsif ( $towernum ) {
28   @sectors = $tower->tower_sector;
29 } # else new mode, no sectors yet
30
31 my $id = $opt{id} || $opt{field} || 'sectornum';
32
33 </%init>
34 <& tablebreak-tr-title.html, value => 'Sectors' &>
35
36 <style>
37   .ui-tabs-nav a {
38     padding: 6px 9px;
39     font-weight: bold;
40   }
41   .ui-tabs-nav li {
42     border-top-left-radius: 0.5em;
43     border-top-right-radius: 0.5em;
44   }
45   .ui-tabs-active li {
46     border-bottom-color: #fff;
47   }
48   .ui-tabs {
49     font-weight: bold;
50   }
51   .ui-tabs label {
52     padding-top: 3px;
53     width: 140px;
54     display: inline-block;
55     text-align: right;
56   }
57   .ui-tabs input, .ui-spinner {
58     border: 1px solid #666;
59     border-radius: 2px;
60     font-size: 13.3px;
61     text-align: right;
62     font-weight: normal;
63     padding: 1px;
64   }
65   .ui-tabs input { /* but not spinner, messes it up */
66     margin-left: 1px;
67     margin-right: 1px;
68   }
69   .ui-tabs input:focus {
70     border-color: #7e0079;
71     background-color: #ffffdd;
72   }
73   .ui-spinner input { /* use the spinner's border and padding */
74     border: none;
75     text-align: left;
76   }
77 </style>
78
79
80 <tr>
81   <td colspan=2>
82 %# prototypes
83     <div style="display: none">
84 <& .tab, id => $id . '_P' &>
85 <& .panel, id => $id . '_P' &>
86     </div>
87
88 %# main container
89     <div id="<% $id %>_tabs">
90       <ul>
91 % foreach my $sector (@sectors) {
92 <& .tab, sector => $sector, id => $id . $tabcounter &>
93 %   $tabcounter++;
94 % }
95       </ul>
96
97 % $tabcounter = 0;
98 % foreach my $sector (@sectors) {
99 <& .panel, sector => $sector, id => $id . $tabcounter &>
100 %   $tabcounter++;
101 % }
102     </div>
103   </td>
104 </tr>
105 <script>
106 $(function() {
107   var tabcounter = <% $tabcounter %>;
108   var id = <% $id |js_string %>;
109   //create tab bar
110   var tabs = $( '#'+id+'_tabs' ).tabs();
111
112   function changedSectorName() {
113     var this_panel = $(this).closest('div');
114     var this_tab = tabs.find('#' + this_panel.prop('id') + '_tab');
115     // if this is the last panel, make a new one
116     if (this_panel.next().length == 0) {
117       addSector();
118     }
119     // and update the current tab's text with the sector name
120     this_tab.find('a').text($(this).val());
121   }
122
123   var tab_proto = $('#'+id+'_P_tab');
124   var panel_proto = $('#'+id+'_P');
125
126   function addSector() {
127     var new_tab = tab_proto.clone();
128     var new_panel = panel_proto.clone();
129     // replace proto placeholder with the counter value, in all id and
130     // name properties in new_panel and its children
131     new_panel.add( new_panel.find('*') ).each(function() {
132       this.id = this.id.replace('_P', tabcounter);
133       if (this.name) {
134         this.name = this.name.replace('_P', tabcounter);
135       }
136     });
137     tabcounter++;
138     // and set the handler up on it
139     new_panel.find('.input-sectorname').on('change', changedSectorName);
140     
141     // also update the tab itself
142     new_tab.find('a').prop('href', '#' + new_panel.prop('id'));
143     new_tab.prop('id', new_panel.prop('id') + '_tab');
144
145     tabs.append(new_panel);
146     tabs.children('ul:first').append(new_tab);
147
148     tabs.tabs('refresh');
149   }
150
151   $('.dbspinner').spinner({ step: 5 });
152
153   $('.input-sectorname').on('change', changedSectorName);
154   addSector();
155
156 });
157 </script>
158 <%def .tab>
159 % my %opt = @_;
160 % my $sector = $opt{sector};
161 % my $id = $opt{id};
162 % my $title = $sector ? $sector->sectorname : mt('Add new');
163       <li id="<% $id %>_tab">
164         <a href="#<% $id %>"><% $title |h %></a>
165       </li>
166 </%def>
167 <%def .panel>
168 % my %opt = @_;
169 % my $sector = $opt{sector} || FS::tower_sector->new({});
170 % my $id = $opt{id}; # sectornumX
171 <div id="<% $id %>">
172 % # no id on this one, the panel gets the "sectornumX" id
173   <input type="hidden" name="<% $id %>" value="<% $sector->sectornum |h %>">
174   <p>
175     <label><% emt('Sector name') %></label>
176     <input style="text-align: left"
177            class="input-sectorname"
178            id="<% $id %>_sectorname"
179            name="<% $id %>_sectorname"
180            value="<% $sector->sectorname |h %>">
181
182     <label><% emt('IP address') %></label>
183     <input style="text-align: left"
184            id="<% $id %>_ip_addr"
185            name="<% $id %>_ip_addr"
186            value="<% $sector->ip_addr |h %>">
187   </p>
188   <p>
189     <label for="<% $id %>_height"><% emt('Antenna height') %></label>
190     <input size="3"
191            id="<% $id %>_height"
192            name="<% $id %>_height"
193            value="<% $sector->height |h %>">
194     <% emt('feet above ground') %>
195   </p>
196   <p>
197     <label for="<% $id %>_direction"><% emt('Azimuth') %></label>
198     <input size="3"
199            id="<% $id %>_direction"
200            name="<% $id %>_direction"
201            value="<% $sector->direction |h %>">&deg;
202     <label for="<% $id %>_downtilt"><% emt('Down tilt') %></label>
203     <input size="2"
204            id="<% $id %>_downtilt"
205            name="<% $id %>_downtilt"
206            value="<% $sector->downtilt |h %>">&deg;
207   </p>
208
209   <p>
210     <label for="<% $id %>_freq_mhz"><% emt('Frequency') %></label>
211     <input size="4"
212            id="<% $id %>_freq_mhz"
213            name="<% $id %>_freq_mhz"
214            value="<% $sector->freq_mhz |h %>">
215     <% emt('MHz') %>
216   </p>
217
218   <p>
219     <label for="<% $id %>_width"><% emt('Horizontal beam') %></label>
220     <input size="3"
221            id="<% $id %>_width"
222            name="<% $id %>_width"
223            value="<% $sector->width |h %>">&deg;
224     <label for="<% $id %>_v_width"><% emt('Vertical beam') %></label>
225     <input size="2"
226            id="<% $id %>_v_width"
227            name="<% $id %>_v_width"
228            value="<% $sector->v_width |h %>">&deg;
229   </p>
230
231   <label><% emt('Signal margin') %></label>
232       <div style="display: inline-block; vertical-align: top">
233       <input class="dbspinner"
234              size="4"
235              id="<% $id %>_db_high"
236              name="<% $id %>_db_high"
237              value="<% $sector->db_high |h %>">
238       <% emt('dB (high quality)') %>
239       <br>
240
241       <input class="dbspinner"
242              size="4"
243              id="<% $id %>_db_low"
244              name="<% $id %>_db_low"
245              value="<% $sector->db_low |h %>">
246       <% emt('dB (low quality)') %>
247       </div>
248
249 </div>
250 </%def>