summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael DeHaan <mdehaan@redhat.com>2007-10-11 18:11:49 -0400
committerMichael DeHaan <mdehaan@redhat.com>2007-10-11 18:11:49 -0400
commit3c5d9204a16a489c823712f278892592c75d97a6 (patch)
tree9324be6ec55a3de043e788375a22ffb5296d9816
parent2c45ec8a448fba315b5e7ac4204e467ff74a679d (diff)
downloadthird_party-cobbler-3c5d9204a16a489c823712f278892592c75d97a6.tar.gz
third_party-cobbler-3c5d9204a16a489c823712f278892592c75d97a6.tar.xz
third_party-cobbler-3c5d9204a16a489c823712f278892592c75d97a6.zip
Work on making the NICs on the system page expandable/collapseable. Still need to write the onload
function that sets things by default and wire up the links that do the expanding. Save code still also needs to be aware of the new variable names and also needs to know how to delete interfaces and not save "empty" interfaces.
-rw-r--r--cobbler.spec1
-rw-r--r--setup.py1
-rw-r--r--webui_content/showhide.js191
-rw-r--r--webui_templates/system_edit.tmpl205
-rw-r--r--webui_templates/system_list.tmpl12
5 files changed, 351 insertions, 59 deletions
diff --git a/cobbler.spec b/cobbler.spec
index 2e68bed..d24acd8 100644
--- a/cobbler.spec
+++ b/cobbler.spec
@@ -102,6 +102,7 @@ test "x$RPM_BUILD_ROOT" != "x" && rm -rf $RPM_BUILD_ROOT
%dir /var/www/cobbler/webui
%defattr(444,apache,apache)
/var/www/cobbler/webui/*.css
+/var/www/cobbler/webui/*.js
/var/www/cobbler/webui/*.png
/var/www/cobbler/webui/*.html
%defattr(-,root,root)
diff --git a/setup.py b/setup.py
index 9533127..4e2a7e3 100644
--- a/setup.py
+++ b/setup.py
@@ -155,6 +155,7 @@ if __name__ == "__main__":
(wwwgfx, ['docs/cobbler.html']),
(wwwgfx, []),
(wwwgfx, ['webui_content/icon_16_sync.png']),
+ (wwwgfx, ['webui_content/showhide.js']),
(wwwgfx, ['webui_content/style.css']),
(wwwgfx, ['webui_content/logo-cobbler.png']),
(wwwgfx, ['webui_content/cobblerweb.css']),
diff --git a/webui_content/showhide.js b/webui_content/showhide.js
new file mode 100644
index 0000000..d2f39e1
--- /dev/null
+++ b/webui_content/showhide.js
@@ -0,0 +1,191 @@
+// Javascript code by Máirín Duffy <duffy@redhat.com>
+
+
+IMAGE_COLLAPSED_PATH = '/img/list-expand.gif';
+IMAGE_EXPANDED_PATH = '/img/list-collapse.gif';
+IMAGE_CHILDLESS_PATH = '/img/rhn-bullet-parentchannel.gif';
+
+var rowHash = new Array();
+var browserType;
+var columnsPerRow;
+
+// tip of the Red Hat to Mar Orlygsson for this little IE detection script
+var is_ie/*@cc_on = {
+ quirksmode : (document.compatMode=="BackCompat"),
+ version : parseFloat(navigator.appVersion.match(/MSIE (.+?);/)[1])
+}@*/;
+browserType = is_ie;
+
+function onLoadStuff(columns) {
+ columnsPerRow = columns;
+ var channelTable = document.getElementById('channel-list');
+ createParentRows(channelTable, rowHash);
+ reuniteChildrenWithParents(channelTable, rowHash);
+ iconifyChildlessParents(rowHash);
+}
+
+function iconifyChildlessParents(rowHash) {
+ for (var i in rowHash) {
+ if (!rowHash[i].hasChildren && rowHash[i].image) { rowHash[i].image.src = IMAGE_CHILDLESS_PATH; }
+ }
+}
+
+// called from clicking the show/hide button on individual rows in the page
+function toggleRowVisibility(id) {
+ if (!rowHash[id]) { return; }
+ if (!rowHash[id].hasChildren) { return; }
+ rowHash[id].toggleVisibility();
+ return;
+}
+
+function showAllRows() {
+ var row;
+ for (var i in rowHash) {
+ row = rowHash[i];
+ if (!row) { continue; }
+ if (!row.hasChildren) { continue; }
+ row.show();
+ }
+ return;
+}
+
+function hideAllRows() {
+ var row;
+ for (var i in rowHash) {
+ row = rowHash[i];
+ if (!row) { continue; }
+ if (!row.hasChildren) { continue; }
+ row.hide();
+ }
+ return;
+}
+
+function Row(cells, image) {
+ this.cells = new Array();
+ for (var i = 0; i < cells.length; i++) { this.cells[i] = cells[i]; }
+ this.image = image;
+ this.hasChildren = 0;
+ this.isHidden = 1; // 1 = hidden; 0 = visible. all rows are hidden by default
+
+// Row object methods below!
+ this.toggleVisibility = function() {
+ if (this.isHidden == 1) { this.show(); }
+ else if (this.isHidden == 0) { this.hide(); }
+ return;
+ }
+
+ this.hide = function hide() {
+ this.image.src = IMAGE_COLLAPSED_PATH;
+// we start with columnsPerRow, because we want to skip the td cells of the parent tr.
+ for (var i = columnsPerRow; i < this.cells.length; i++) {
+ this.cells[i].parentNode.style.display = 'none';
+ this.cells[i].style.display = 'none';
+ }
+ this.isHidden = 1;
+ return;
+ }
+
+ this.show = function() {
+ displayType = '';
+ this.image.src = IMAGE_EXPANDED_PATH;
+
+ for (var i = 0; i < this.cells.length; i++) {
+ this.cells[i].style.display = displayType;
+ this.cells[i].parentNode.style.display = displayType;
+ }
+ this.isHidden = 0;
+ return;
+ }
+}
+
+function createParentRows(channelTable, rowHash) {
+ for (var i = 0; i < channelTable.rows.length; i++) {
+ tableRowNode = channelTable.rows[i];
+ if (isParentRowNode(tableRowNode)) {
+ if (!tableRowNode.id) { continue; }
+ id = tableRowNode.id;
+ var cells = tableRowNode.cells;
+ var image = findRowImageFromCells(cells, id)
+ if (!image) { continue; }
+ rowHash[id] = new Row(cells, image);
+ }
+ }
+ return;
+}
+
+function reuniteChildrenWithParents(channelTable, rowHash) {
+ var parentNode;
+ var childId;
+ var tableChildRowNode;
+ for (var i = 0; i < channelTable.rows.length; i++) {
+ tableChildRowNode = channelTable.rows[i];
+// when we find a parent, set it as parent for the children after it
+ if (isParentRowNode(tableChildRowNode) && tableChildRowNode.id) {
+ parentNode = tableChildRowNode;
+ continue;
+ }
+ if (!parentNode) { continue; }
+
+ // it its not a child node we bail here
+ if (!isChildRowNode(tableChildRowNode)) { continue; }
+ // FIXME: chceck child id against parent id
+ if (!rowHash[parentNode.id]) { /*alert('bailing, cant find parent in hash');*/ continue; }
+ for (var j = 0; j < tableChildRowNode.cells.length; j++) {
+ rowHash[parentNode.id].cells.push(tableChildRowNode.cells[j]);
+ rowHash[parentNode.id].hasChildren = 1;
+ }
+ }
+ return;
+}
+
+
+function getNodeTagName(node) {
+ var tagName;
+ var nodeId;
+ tagName = new String(node.tagName);
+ return tagName.toLowerCase();
+}
+
+function isParentRowNode(node) {
+ var nodeInLowercase = getNodeTagName(node);
+ if (nodeInLowercase != 'tr') { return 0; }
+ nodeId = node.id;
+ if ((nodeId.indexOf('id')) && !(nodeId.indexOf('child'))) { return 0; }
+ return 1;
+}
+
+function isChildRowNode(node) {
+ var nodeInLowercase = getNodeTagName(node);
+ var nodeId;
+ if (nodeInLowercase != 'tr') { return 0; }
+ nodeId = node.id;
+ if (nodeId.indexOf('child')) { return 0; }
+ return 1;
+}
+
+
+function findRowImageFromCells(cells, id) {
+ var imageId = id + '-image';
+ var childNodes; // first level child
+ var grandchildNodes; // second level child
+ for (var i = 0; i < cells.length; i++) {
+ childNodes = null;
+ grandchildNodes = null;
+
+ if (!cells[i].hasChildNodes()) { continue; }
+
+ childNodes = cells[i].childNodes;
+
+ for (var j = 0; j < childNodes.length; j++) {
+ if (!childNodes[j].hasChildNodes()) { continue; }
+ if (getNodeTagName(childNodes[j]) != 'a') { continue; }
+ grandchildNodes = childNodes[j].childNodes;
+
+ for (var k = 0; k < grandchildNodes.length; k++) {
+ if (grandchildNodes[k].name != imageId) { continue; }
+ if (grandchildNodes[k].nodeName == 'IMG' || grandchildNodes[k].nodeName == 'img') { return grandchildNodes[k]; }
+ }
+ }
+ }
+ return null;
+}
diff --git a/webui_templates/system_edit.tmpl b/webui_templates/system_edit.tmpl
index d3a763c..65310ae 100644
--- a/webui_templates/system_edit.tmpl
+++ b/webui_templates/system_edit.tmpl
@@ -3,7 +3,10 @@
#block body
+<script language=javascript" src="/cobbler/webui/showhide.js"/>
+
<script language="javascript">
+
#if $system
function disablename(value)
{
@@ -31,6 +34,25 @@ function get_random_mac()
#end if
</script>
+##
+## determine a bit about what interfaces should be shown and which should not.
+##
+
+#set $all_interfaces = [ "intf0", "intf1", "intf2", "intf3", "intf4", "intf5", "intf6", "intf7" ]
+#if $system
+ #set $interfaces = $system.interfaces.keys()
+ #set $defined_interfaces = []
+ #for $potential in $all_interfaces
+ #if $potential in $interfaces
+ #set $rc = $defined_interfaces.append($potential)
+ #end if
+ #end for
+#else
+ #set $interfaces = [ "intf0", "intf1", "intf2", "intf3", "intf4", "intf5", "intf6", "intf7" ]
+ #set $defined_interfaces = [ "intf0" ]
+#end if
+
+
<form method="post" action="$base_url/system_save">
<fieldset id="cform">
@@ -95,50 +117,139 @@ function get_random_mac()
</td>
</tr>
- <tr>
- <td>
- <label for="mac">MAC</label>
- </td>
- <td>
- <input type="text" size="64" style="width: 150px;" name="mac" id="mac"
- #if $system
- value="$system.mac_address"
+ ## ====================================== start of looping through interfaces
+
+ #for $interface in $all_interfaces
+
+ ## ----------------------------------
+ ## calculate some initial CSS visibility
+ ## ----------------------------------
+
+ #if $interface in $defined_interfaces
+ #set $toggler_visibile = "hidden"
+ #set $panel_visibile = "visible"
+ #else
+ #set $toggler_visibile = "visible"
+ #set $panel_visibile = "hidden"
#end if
- />
- #if not $system
- <a href="javascript: get_random_mac()" style="font-size: 0.8em;">random</a>
- #end if
- <p class="context-tip">Example: AA:BB:CC:DD:EE:FF</p>
- </td>
- </tr>
- <tr>
- <td>
- <label for="ip">IP</label>
- </td>
- <td>
- <input type="text" size="64" style="width: 150px;" name="ip" id="ip"
- #if $system
- value="$system.ip_address"
+ ## ----------------------------------
+ ## load up initial variable values
+ ## ----------------------------------
+
+ #if $system and $interface in $defined_interfaces
+ #set $macaddress = $system.interfaces[$interface]["mac_address"]
+ #set $ipaddress = $system.interfaces[$interface]["ip_address"]
+ #set $hostname = $system.interfaces[$interface]["hostname"]
+ #set $dhcptag = $system.interfaces[$interface]["dhcp_tag"]
+ #set $virtbridge = $system.interfaces[$interface]["virt_bridge"]
+ #set $subnet = $system.interfaces[$interface]["subnet"]
+ #set $gateway = $system.interfaces[$interface]["gateway"]
+ #else
+ #set $macaddress = ""
+ #set $ipaddress = ""
+ #set $hostname = ""
+ #set $dhcptag = ""
+ #set $virtbridge = ""
+ #set $subnet = ""
+ #set $gateway = ""
#end if
- />
- <p class="context-tip">Optional. Example: 192.168.10.15</p>
- </td>
- </tr>
- <tr>
- <td>
- <label for="hostname">Hostname</label>
- </td>
- <td>
- <input type="text" size="255" style="width: 150px;" name="hostname" id="hostname"
- #if $system
- value="$system.hostname"
+ ## ----------------------------------------
+ ## render the toggle link to hide the interfaces not yet defined
+ ## ----------------------------------------
+
+ ## FIXME: these tables need CSS classes, don't they?
+ <tr class="listrow" id="$interface">
+ <td>
+ <label>Interface ($interface)
+ </td>
+ <td>
+ <hr width="95%">
+ </td>
+ </tr>
+
+ <tr class="listrow" id="toggle_$interface">
+ <td>
+ <label>Expand</label>
+ </td>
+ <td>
+ <A href="javascript:void('')" onclick="show_interface('$interface');">Click to expand $interface</A>
+ </td>
+ </tr>
+
+
+ ## ----------------------------------------
+ ## now show all of the interface fields which may or may not
+ ## be hidden but are always there
+ ## ----------------------------------------
+
+ <tr class="listrow" id="panel_${interface}_mac">
+ <td>
+ <label for="mac-$interface">MAC</label>
+ </td>
+ <td>
+ <input type="text" size="64" style="width: 150px;" name="mac-$interface" id="mac-$interface"
+ value="$macaddress"
+ />
+ #if not $system
+ <a href="javascript: get_random_mac()" style="font-size: 0.8em;">random</a>
#end if
- />
- <p class="context-tip">Optional. Example: vanhalen.example.org</p>
- </td>
- </tr>
+ <p class="context-tip">Example: AA:BB:CC:DD:EE:FF</p>
+ </td>
+ </tr>
+
+ <tr class="listrow" id="panel_${interface}_ip">
+ <td>
+ <label for="ip-$interface">IP</label>
+ </td>
+ <td>
+ <input type="text" size="64" style="width: 150px;" name="ip-$interface" id="ip-$interface"
+ value="$ipaddress"
+ />
+ <p class="context-tip">Optional. Example: 192.168.10.15</p>
+ </td>
+ </tr>
+
+ <tr class="listrow" id="panel_${interface}_hostname">
+ <td>
+ <label for="hostname-$interface">Hostname</label>
+ </td>
+ <td>
+ <input type="text" size="255" style="width: 150px;" name="hostname-$interface" id="hostname-$interface"
+ value="$hostname"
+ />
+ <p class="context-tip">Optional. Example: vanhalen.example.org</p>
+ </td>
+ </tr>
+
+ <tr class="listrow" id="panel_${interface}_dhcptag">
+ <td>
+ <label for="dhcptag-$interface">DHCP Tag</label>
+ </td>
+ <td>
+ <input type="text" size="128" style="width: 150px;" name="dhcptag-$interface" id="dhcptag-$interface"
+ value="$dhcptag"
+ />
+ <p class="context-tip">Selects alternative subnets, see manpage or leave blank</p>
+ </td>
+ </tr>
+
+ ## FIXME: add virt_bridge editing (like above)
+ ## FIXME: add subnet editing (like above)
+ ## FIXME: add gateway editing (like above)
+ ## FIXME: make the save function understand the new fieldname-$interface variables
+ ## only enable an interface for saving if one of it's fields is non-empty
+ ## FIXME: delete checkboxes and accompanying API method. No delete for intf0.
+
+ #end for
+ ## ====================================== end of looping through interfaces
+
+ ## now we're back to doing regular fields
+ ## FIXME: should all of these be moved up before the interface section?
+ ## FIXME: make entire interface block seperately collapseable?
+
+ ## restart the table that we un-started for the DIVs
<tr>
<td>
@@ -182,20 +293,6 @@ function get_random_mac()
</td>
</tr>
- <tr>
- <td>
- <label for="dhcp_tag">DHCP Tag</label>
- </td>
- <td>
- <input type="text" size="128" style="width: 150px;" name="dhcp_tag" id="dhcp_tag"
- #if $system
- value="$system.dhcp_tag"
- #end if
- />
- <p class="context-tip">Selects alternative subnets, see manpage or leave blank</p>
- </td>
- </tr>
-
#if $system
<tr>
<td>
@@ -218,6 +315,8 @@ function get_random_mac()
</td>
</tr>
+ </table>
+
</fieldset>
</form>
diff --git a/webui_templates/system_list.tmpl b/webui_templates/system_list.tmpl
index 246ac6b..e74f313 100644
--- a/webui_templates/system_list.tmpl
+++ b/webui_templates/system_list.tmpl
@@ -7,9 +7,9 @@
<tr>
<th class="text">Name</th>
<th class="text">Profile</th>
- <th class="text">MAC</th>
- <th class="text">IP</th>
- <th class="text">Hostname</th>
+ ## FIXME: how to handle for multiple interface listing? <th class="text">MAC</th>
+ ## <th class="text">IP</th>
+ ## <th class="text">Hostname</th>
</tr>
</thead>
<tbody>
@@ -29,9 +29,9 @@
<td>
<a href="$base_url/profile_edit?name=${system.profile}">${system.profile}</a>
</td>
- <td> ${system.mac_address} </td>
- <td> ${system.ip_address} </td>
- <td> ${system.hostname} </td>
+ ## <td> ${system.mac_address} </td>
+ ## <td> ${system.ip_address} </td>
+ ## <td> ${system.hostname} </td>
</tr>
#end for
</tbody>