[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] conga/luci/homebase form-chooser form-macros i ...



CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	rmccabe sourceware org	2006-06-20 21:21:47

Modified files:
	luci/homebase  : form-chooser form-macros index_html 
	                 luci_homebase.css main_logo main_pathbar 
	                 main_personalbar main_sections portlet_homebase 
Added files:
	luci/homebase  : main_footer x.png 

Log message:
	

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/main_footer.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/x.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/form-chooser.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/form-macros.diff?cvsroot=cluster&r1=1.21&r2=1.22
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/index_html.diff?cvsroot=cluster&r1=1.6&r2=1.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/luci_homebase.css.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/main_logo.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/main_pathbar.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/main_personalbar.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/main_sections.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/portlet_homebase.diff?cvsroot=cluster&r1=1.6&r2=1.7

/cvs/cluster/conga/luci/homebase/main_footer,v  -->  standard output
revision 1.1
--- conga/luci/homebase/main_footer
+++ -	2006-06-20 21:21:48.674641000 +0000
@@ -0,0 +1,31 @@
+<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
+<body>
+<div id="portal-footer" metal:define-macro="portal_footer">
+
+<p>
+    <span i18n:translate="description_copyright" tal:omit-tag="">
+    The 
+    <span>
+        <a href="http://redhat.com";>Conga&trade; Cluster and Storage Management System</a>
+    </span>
+    is Copyright
+    <acronym title="Copyright" i18n:name="copyright" i18n:attributes="title title_copyright;">&copy;</acronym>
+    2000-<span i18n:name="current_year" 
+               tal:define="now modules/DateTime/DateTime" 
+               tal:content="now/year" />
+    <a href="http://www.redhat.com/";>Red Hat, Inc.</a>
+    </span>
+</p>
+
+<p>
+    <span i18n:translate="description_license">
+    Distributed under the 
+        <span i18n:name="license">
+            <a href="http://creativecommons.org/licenses/GPL/2.0/"; i18n:translate="label_gnu_gpl_licence">GNU GPL license</a>
+        </span>.
+    </span>
+</p>
+
+</div>
+</body>
+</html>
/cvs/cluster/conga/luci/homebase/x.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/homebase/x.png and - differ
--- conga/luci/homebase/form-chooser	2006/05/18 17:47:15	1.7
+++ conga/luci/homebase/form-chooser	2006/06/20 21:21:47	1.8
@@ -5,12 +5,13 @@
 </head>
 
 <tal:comment replace="nothing">
-	$Id: form-chooser,v 1.7 2006/05/18 17:47:15 rmccabe Exp $
+	$Id: form-chooser,v 1.8 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
 <body>
-  <metal:choose-form metal:define-macro="main-form">
-	<span tal:omit-tag="" tal:define="global ptype request/pagetype | request/form/pagetype |nothing"/>  
+
+<metal:choose-form metal:define-macro="main-form">
+	<span tal:omit-tag="" tal:define="global ptype request/pagetype | request/form/pagetype |nothing"/>
 
 	<span tal:omit-tag="" tal:condition="python: not ptype or ptype == '0'">
 		<div metal:use-macro="here/form-macros/macros/entry-form"/>
@@ -39,6 +40,7 @@
 	<span tal:omit-tag="" tal:condition="python: ptype == '6'">
 		<div metal:use-macro="here/form-macros/macros/cluster-add-form" />
 	</span>
-  </metal:choose-form>
+</metal:choose-form>
+
 </body>
 </html>
--- conga/luci/homebase/form-macros	2006/05/25 22:34:24	1.21
+++ conga/luci/homebase/form-macros	2006/06/20 21:21:47	1.22
@@ -1,7 +1,7 @@
 <html>
 
 <tal:comment replace="nothing">
-	$Id: form-macros,v 1.21 2006/05/25 22:34:24 rmccabe Exp $
+	$Id: form-macros,v 1.22 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
 <head>
@@ -11,24 +11,22 @@
 <body>
 
 <tal:comment replace="nothing">
+
+
 !###########################
 # ENTRY FORM               #
 ############################
-</tal:comment>
 
-	<div metal:define-macro="entry-form" tal:omit-tag="">
 
-		<div tal:condition="python:here.userAuthenticated()">
-			<h2 class="homebase">Luci Homebase</h2>
-			<p class="hbText">Welcome to Luci, <span tal:replace="string: ${user/getUserName}" />.</p>
-			<p class="hbText">Select an action from the list on the left.</p>
-		</div>
+</tal:comment>
 
-		<div tal:condition="python:not here.userAuthenticated()">
-			<p style="font-size:18px;font-weight:bold">Not Logged In</p>
-			<p class="hbText">Please <a tal:attributes="href python: here.getOrderedUserActions(keyed_actions=keyed_actions)[0]['url']">login</a> first.</p>
-		</div>
+<div metal:define-macro="entry-form" tal:omit-tag="">
+	<div>
+		<h2 class="homebase">Luci Homebase</h2>
+		<p class="hbText">Welcome to Luci, <span tal:replace="string: ${user/getUserName}" />.</p>
+		<p tal:condition="python:'children' in data and len(data['children']) > 0" tal:content="string: Select an action from the list on the left." />
 	</div>
+</div>
 
 <tal:comment replace="nothing">
 !###########################
@@ -36,52 +34,57 @@
 ############################
 </tal:comment>
 
-	<div metal:define-macro="user-del-form">
-		<tal:comment replace="nothing">
-			XXX: to validate:
-				- user was selected,
-				- selected index is valid
-		</tal:comment>
-
-		<script type="text/javascript">
-			function validateForm(form) {
-				var errors = new Array();
-
-				if (!form || !form.deluserId)
-					return (-1);
-
-				var userIdx = form.deluserId.selectedIndex;
-				if (userIdx <= 0 ||
-					!form.deluserId.options[userIdx] ||
-					!form.deluserId.options[userIdx].value)
-				{
-					errors.push('You have not selected a valid user.');
-					return (-1);
-				}
-
-				if (!errors.length) {
-					if (confirm('Do you really want to remove the user \"' +
-						form.deluserId.options[userIdx].value + '\"?'))
-					{
-						form.submit();
-					}
-				} else {
-					alert(errors);
-					return (-1);
-				}
+<div metal:define-macro="user-del-form">
+	<tal:comment replace="nothing">
+		: to validate:
+			- user was selected,
+			- selected index is valid
+	</tal:comment>
+
+	<script type="text/javascript">
+		function validateForm(form) {
+			var errors = new Array();
+
+			if (!form || !form.deluserId)
+				return (-1);
 
-				return (0);
+			var userIdx = form.deluserId.selectedIndex;
+			if (userIdx <= 0 ||
+				!form.deluserId.options[userIdx] ||
+				!form.deluserId.options[userIdx].value)
+			{
+				errors.push('You have not selected a valid user.');
+				return (-1);
 			}
-		</script>
 
-	<form name="adminform" method="post" action="">
-		<h2 class="homebase">Delete a User</h2>
+			if (error_dialog(errors))
+				return (-1);
+
+			if (confirm('Do you really want to remove the user \"' +
+				form.deluserId.options[userIdx].value + '\"?'))
+			{
+				form.submit();
+			}
+
+			return (0);
+		}
+	</script>
+
+	<span tal:omit-tag=""
+		tal:define="global userList python:here.portal_membership.listMembers();
+					global blankForm python:1" />
+
+	<form name="adminform" method="post" action=""
+		tal:condition="python: userList and len(userList) > 0">
+
+		<h2 class="homebase" tal:define="global blankForm python:0">
+			Delete a User
+		</h2>
 
-		<span tal:omit-tag="" tal:define="global userList python:here.portal_membership.listMembers()" />
 
 		<select tal:condition="python:userList" name="deluserId" class="homebase">
 			<option class="homebase" value="" selected="1">Select a User</option>
-			<tal:block tal:repeat="user python:here.portal_membership.listMembers()">
+			<tal:block tal:repeat="user python:userList">
 				<option class="homebase"
 					tal:content="python:user"
 					tal:attributes="value python:user"
@@ -95,81 +98,68 @@
 		<input name="absoluteURL" type="hidden"
 			tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
 
-		<div class="hbSubmit" tal:condition="python:userList" style="padding-top:1em">
+		<div class="hbSubmit" tal:condition="python:userList" id="hbSubmit">
 			<input class="hbSubmit" name="Submit" type="button" value="Submit" onClick="validateForm(document.adminform);" />
 		</div>
+	</form>
 
-		<span tal:condition="python:not userList">
-			No users have been added.
-		</span>
-
-		</form>
+	<div tal:condition="python:blankForm">
+		No users have been added.
 	</div>
+</div>
+
 
 <tal:comment replace="nothing">
+
+
 !###########################
 # USER ADD FORM            #
 ############################
+
+
 </tal:comment>
 
-	<div metal:define-macro="user-add-form">
-		<tal:comment replace="nothing">
-			Things to validate:
-			 - user/passwd exist and are not blank
-			 - user doesn't contain invalid characters.
-			 - passwords match
-		</tal:comment>
-
-		<script type="text/javascript">
-			function validateForm(form) {
-				var errors = new Array()
-
-				if (!form)
-					return (-1);
-
-				if (!form.newUserName || !form.newUserName.value)
-					errors.push('You did not enter a user name.');
-
-				if (!form.newPassword || !form.newPassword.value)
-					errors.push('You did not enter a password.');
-
-				if (errors.length > 0) {
-					alert('The following errors were found:\n\n' + errors.join('\n'));
-					return (-1);
-				}
-
-				if (form.newUserName.value !=
-					form.newUserName.value.replace(/[^0-9A-Za-z_-]/g, ''))
-				{
-					errors.push("The username you specified contains invalid characters. Use only alphanumeric chararacters, '_', and '-'");
-				}
-
-				if (!form.newPassword.value.replace(/\s/g, '')) {
-					errors.push('Passwords may not be blank.');
-					alert('The following errors were found:\n\n' + errors.join('\n'));
-					return (-1);
-				}
-
-				if (form.newPassword.value.length < 5)
-					errors.push('Passwords must be at least five characters long.');
-
-				if (form.newPassword.value != form.newPasswordConfirm.value)
-					errors.push('The passwords you entered do not match.');
-
-				if (!errors.length) {
-					if (confirm('Do you really want to add the user \"' +
-						form.newUserName.value + '\"?'))
-					{
-						form.submit();
-					}
-				} else {
-					alert('The following errors were found:\n\n' + errors.join('\n'));
-					return (-1);
-				}
+<div metal:define-macro="user-add-form">
+	<tal:comment replace="nothing">
+		Things to validate:
+		 - user/passwd exist and are not blank
+		 - user doesn't contain invalid characters.
+		 - passwords match
+	</tal:comment>
+
+	<script type="text/javascript">
+		function validateForm(form) {
+			var errors = new Array()
 
-				return (0);
-			}
-		</script>
+			if (!form)
+				return (-1);
+
+			if (!form.newUserName || !form.newUserName.value)
+				errors.push('You did not enter a user name.');
+			if (!form.newPassword || !form.newPassword.value)
+				errors.push('You did not enter a password.');
+			if (error_dialog(errors))
+				return (-1);
+
+			var invalid = str_is_valid(form.newUserName.value, '/[0-9A-Za-z_]/g');
+			if (invalid)
+				errors.push('The user name you specified contains the following invalid characters: "' + invalid + '"');
+
+			if (str_is_blank(form.newPassword.value))
+				errors.push('Passwords may not be blank.');
+			else if (form.newPassword.value.length < 5)
+				errors.push('Passwords must be at least five characters long.');
+			else if (form.newPassword.value != form.newPasswordConfirm.value)
+				errors.push('The passwords you entered do not match.');
+
+			if (error_dialog(errors))
+				return (-1);
+
+			if (confirm('Do you really want to add the user \"' + form.newUserName.value + '\"?'))
+				form.submit();
+			return (0);
+		}
+	</script>
 
 	<form name="adminform" method="post" action="">
 		<h2 class="homebase">Add a User</h2>
@@ -178,20 +168,20 @@
 			<tr class="hbAddUser">
 				<td class="hbAddUser">User Name</td>
 				<td class="hbAddUser">
-					<input class="hbInputUser" name="newUserName" type="text" size="24" maxlength="256" />
+					<input class="hbInputUser" name="newUserName" type="text" />
 				</td>
 			</tr>
 
 			<tr class="hbAddUser">
 				<td class="hbAddUser">Password</td>
 				<td class="hbAddUser">
-					<input class="hbInputPasswd" name="newPassword" type="password" size="24" maxlength="256" />
+					<input class="hbInputPasswd" name="newPassword" type="password" />
 				</td>
 			</tr>
 
 			<tr class="hbAddUser">
 				<td class="hbAddUser">Confirm Password</td>
-				<td class="hbAddUser"><input class="hbInputPasswd" name="newPasswordConfirm" type="password" size="24" maxlength="256" /></td>
+				<td class="hbAddUser"><input class="hbInputPasswd" name="newPasswordConfirm" type="password" /></td>
 			</tr>
 		</table>
 
@@ -201,65 +191,94 @@
 		<input name="absoluteURL" type="hidden"
 			tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
 
-		<div class="hbSubmit">
+		<div class="hbSubmit" id="hbSubmit">
 			<input class="hbSubmit" name="Submit" type="button" value="Submit" onClick="validateForm(document.adminform);" />
 		</div>
-		</form>
-	</div>
+	</form>
+</div>
+
+
 
 <tal:comment replace="nothing">
+
+
 !###########################
 # PERMISSIONS FORM         #
 ############################
+
+
 </tal:comment>
 
-	<div metal:define-macro="perm-manage-form">
-		<tal:comment replace="nothing">
-			Things to validate:
-				- user is selected and valid index
-				- The rest is checked by the python form submit validator.
-		</tal:comment>
-
-        <script type="text/javascript">
-			function validateForm(form) {
-				var errors = new Array();
-
-				if (!form || !form.userList)
-					return (-1);
-
-				var userIdx = form.userList.selectedIndex;
-				if (userIdx < 0 || !form.userList.options[userIdx].value)
-					errors.push('You have not selected a valid user.');
-
-				if (!errors.length) {
-					if (confirm('Submit permissions for ' + form.userList.options[userIdx].value))
-						form.submit();
-				} else {
-					alert('The following errors were found:\n\n' + errors.join('\n'));
-					return (-1);
-				}
+<div metal:define-macro="perm-manage-form">
+	<tal:comment replace="nothing">
+		Things to validate:
+			- user is selected and valid index
+			- The rest is checked by the python form submit validator.
+	</tal:comment>
 
-				return (0);
+	<script type="text/javascript">
+		function validateForm(form) {
+			var errors = new Array();
+
+			if (!form || !form.userList)
+				return (-1);
+
+			var userIdx = form.userList.selectedIndex;
+			if (userIdx < 0 || !form.userList.options[userIdx].value)
+				errors.push('You have not selected a valid user.');
+
+			if (error_dialog(errors))
+				return (-1);
+
+			var selected_clusters = new Array();
+			var selected_storage = new Array();
+
+			if (!form)
+				return (-1);
+
+			var num_clusters = document.getElementById('numClusters').value;
+			for (var i = 0 ; i < num_clusters ; i++) {
+				var element = document.getElementById('__CLUSTER' + i);
+				if (!element || !element.value || !element.checked)
+					continue;
+				selected_clusters.push(element.value);
 			}
 
-            function checkAllBoxes(str, val) {
-                var i = 0;
-                while ((element = document.getElementById(str + i++)))
-                    element.checked = val;
-            }
-        </script>
+			var num_storage = document.getElementById('numStorage').value;
+			for (var i = 0 ; i < num_storage ; i++) {
+				var element = document.getElementById('__SYSTEM' + i);
+				if (!element || !element.value || !element.checked)
+					continue;
+				selected_storage.push(element.value);
+			}
 
-	<form name="adminform" method="post" action="">
-		<h2 class="homebase">User Permissions</h2>
+			if (selected_clusters.length + selected_storage.length < 1)
+				return (0);
+
+			if (error_dialog(errors))
+				return (-1);
+
+			if (confirm('Modify permissions for ' + form.userList.options[userIdx].value + '?'))
+				form.submit();
+			return (0);
+		}
+	</script>
+
+	<span
+		tal:omit-tag=""
+		tal:define="global perms python:here.getUserPerms();
+					global systems python:here.getSystems();
+					global num_clusters python:-1;
+					global num_systems python:-1;
+					global blankForm python:1;
+					global curUser request/form/user | request/user | python:here.getDefaultUser()" />
+
+	<form name="adminform" method="post" action=""
+		tal:condition="python: curUser and perms and systems and ((systems[0] and len(systems[0]) > 0) or (systems[1] and len(systems[1]) > 0))">
+
+		<span tal:omit-tag="" tal:define="global blankForm python:0" />
 
-		<span
-			tal:omit-tag=""
-			tal:define="global perms python:here.getUserPerms();
-						global clusters python:here.getClusters();
-						global storage python:here.getStorage();
-						global num_clusters python:-1;
-						global num_storage python:-1;
-						global curUser request/user | python:here.getDefaultUser()" />
+		<h2 class="homebase">User Permissions</h2>
 
 		<input name="absoluteURL" type="hidden"
 			tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
@@ -267,8 +286,9 @@
 		<input name="pagetype" type="hidden"
 			tal:attributes="value request/pagetype | request/form/pagetype | nothing" />
 
-		<span tal:condition="python:perms" class="hbText" tal:content="string:Select a User" />
-		<select tal:omit-tag="python: not perms" class="homebase" name="userList" onChange="document.location = adminPermForm.absoluteURL.value + '&user=' + adminPermForm.userList.options[adminPermForm.userList.selectedIndex].text">
+		<span tal:condition="python:perms" tal:content="string:Select a User" /><br/>
+
+		<select tal:omit-tag="python: not perms" class="homebase" name="userList" onChange="document.location = adminform.absoluteURL.value + '&user=' + adminform.userList.options[adminform.userList.selectedIndex].text">
 			<tal:block tal:repeat="user python:perms">
 				<option class="homebase"
 					tal:content="python:user"
@@ -278,75 +298,95 @@
 			</tal:block>
 		</select>
 
-		<span tal:condition="python:not perms" class="hbText">
-			No users have been added
-		</span>
-
-		<p />
-
-		<h2 class="homebase" tal:condition="python:curUser and perms and clusters">Clusters</h2>
-
-		<tal:block tal:condition="python:perms" tal:repeat="c python:clusters">
-			<input type="checkbox" class="hombase"
-				tal:define="global num_clusters python:num_clusters + 1"
-				tal:attributes="
-					checked python:perms[curUser]['cluster'][c[0]] and 'checked' or None;
-					name python:'__CLUSTER:' + here.strFilter('[^0-9A-Za-z_-]', '_', c[0]);
-					id python:'__CLUSTER' + str(num_clusters);
-					value python:c[0];"
-			/>
-			<span class="hbText" tal:omit-tag="" tal:content="python:c[0]"/>
+		<h3 class="homebase" tal:condition="python:systems[0] and len(systems[0]) > 0">
+			Clusters
+		</h3>
+
+		<tal:block tal:repeat="c python:systems[0]">
+			<div class="hbcheckdiv"
+					tal:define="cfname python: here.strFilter('[^0-9A-Za-z_-]', '_', c)"
+					tal:attributes="id python: cfname">
+
+				<input type="checkbox" class="homebase"
+					tal:define="global num_clusters python:num_clusters + 1"
+					tal:attributes="
+						checked python:perms[curUser]['cluster'][c] and 'checked' or None;
+						name python:'__CLUSTER:' + cfname;
+						id python:'__CLUSTER' + str(num_clusters);
+						onChange python: 'checkChildren(\'' + cfname + '\', this)';
+						value python: c"
+				/>
+				<span tal:omit-tag="" tal:content="python:c" />
+
+				<tal:block tal:repeat="cs python:systems[0][c]">
+					<div class="hbcheckdiv">
+						<input type="checkbox" class="hombase"
+							tal:define="global num_systems python:num_systems + 1"
+							tal:attributes="
+								checked python:perms[curUser]['storage'][cs] and 'checked' or None;
+								name python:'__SYSTEM:' + here.strFilter('[^0-9A-Za-z_-]', '_', cs);
+								id python:'__SYSTEM' + str(num_systems);
+								value python:cs"
+						/>
+						<span tal:omit-tag="" tal:content="python: cs" />
+					</div>
+				</tal:block>
+			</div>
 		</tal:block>
 
-		<input type="hidden" name="numClusters" id="numClusters"
-			tal:attributes="value python: num_clusters" />
+		<div tal:omit-tag="" tal:condition="python: systems[1] and len(systems[1]) > 0">
+			<h3 class="homebase">Unclustered Systems</h3>
 
-		<div tal:condition="python:curUser and perms and clusters" class="hbSubmit">
-			<input class="hbSubmit" type="button" name="allClustersB" id="allClustersB" value="Select All Clusters" onClick="checkAllBoxes('__CLUSTER', true);" />
-			<input class="hbSubmit" type="button" name="noClustersB" id="noClustersB" value="Select No Clusters" onClick="checkAllBoxes('__CLUSTER', false);" />
-		</div>
-
-		<h2 class="homebase" tal:condition="python:curUser and perms and storage">Storage</h2>
-		<tal:block tal:condition="python:perms" tal:repeat="s python:storage">
-			<input type="checkbox" class="homebase"
-				tal:define="global num_storage python:num_storage + 1"
-				tal:attributes="
-					checked python:perms[curUser]['storage'][s[0]] and 'checked' or None;
-					name python:'__STORAGE:' + here.strFilter('[^0-9A-Za-z_-]', '_', s[0]);
-					id python:'__STORAGE' + str(num_storage); 
-					value python:s[0];"
-			/>
+			<tal:block tal:repeat="s python: systems[1]">
+			<div class="hbcheckdiv">
+				<input type="checkbox" class="hombase"
+					tal:define="global num_systems python:num_systems + 1"
+					tal:attributes="
+						checked python:perms[curUser]['storage'][s] and 'checked' or None;
+						name python:'__SYSTEM:' + here.strFilter('[^0-9A-Za-z_-]', '_', s);
+						id python:'__SYSTEM' + str(num_systems);
+						value python:s"
+				/>
+				<span class="hbText" tal:omit-tag="" tal:content="python:s"/>
+				</div>
+			</tal:block>
+		</div>
 
-			<span class="hbText" tal:omit-tag="" tal:content="python:s[0]"/>
-			<br />
-		</tal:block>
-		<input type="hidden" name="numStorage" id="numStorage"
-			tal:attributes="value python: num_storage" />
+		<input type="hidden" id="numStorage"
+			tal:attributes="value python: num_systems + 1" />
 
-		<div tal:condition="python:curUser and perms and storage " class="hbSubmit">
-			<input class="hbSubmit" type="button" name="allStorageB" id="allStorageB" value="All Storage Systems" onClick="checkAllBoxes('__STORAGE', true);" />
-			<input class="hbSubmit" type="button" name="noStorageB" id="noStorageB" value="Select No Storage Systems" onClick="checkAllBoxes('__STORAGE', false);" />
-		</div>
+		<input type="hidden" id="numClusters"
+			tal:attributes="value python: num_clusters + 1" />
 
-		<div tal:condition="python:curUser and perms" class="hbSubmit">
-			<input class="hbSubmit" type="button" name="Submit" value="Submit" onClick="validateForm(document.adminform);" />
+		<div class="hbSubmit" id="hbSubmit">
+			<input type="button" class="hbSubmit" name="Submit" value="Submit" onClick="validateForm(document.adminform);" />
 		</div>
 	</form>
+
+	<div tal:condition="python: blankForm">
+		<p>Either no users have been added or no clusters or storage systems are being managed by Luci.</p>
 	</div>
+</div>
+
 
 <tal:comment replace="nothing">
+
+
 !###########################
 # SYSTEM DELETE FORM       #
 ############################
+
+
 </tal:comment>
 
+
 <div metal:define-macro="system-del-form">
 	<tal:comment replace="nothing">
 		To validate:
-			- confirm removal
-			- if it's a cluster, ask if they also want to remove
-			  associated storage systems.
-				-> if yes, confirm again, showing list
+			- 	confirm removal
+			- 	if it's a cluster, ask if they also want to remove
+				associated storage systems.
+					-> if yes, confirm again, showing list
 	</tal:comment>
 
 	<script type="text/javascript">
@@ -359,8 +399,6 @@
 				return (-1);
 
 			var num_clusters = document.getElementById('numClusters').value;
-			var num_storage = document.getElementById('numStorage').value;
-
 			for (var i = 0 ; i < num_clusters ; i++) {
 				var element = document.getElementById('__CLUSTER' + i);
 				if (!element || !element.value || !element.checked)
@@ -368,6 +406,7 @@
 				selected_clusters.push(element.value);
 			}
 
+			var num_storage = document.getElementById('numStorage').value;
 			for (var i = 0 ; i < num_storage ; i++) {
 				var element = document.getElementById('__SYSTEM' + i);
 				if (!element || !element.value || !element.checked)
@@ -375,97 +414,144 @@
 				selected_storage.push(element.value);
 			}
 
-			if (selected_clusters.length + selected_storage.length <= 0)
+			if (selected_clusters.length + selected_storage.length < 1)
+				return (0);
+
+			if (error_dialog(errors))
 				return (-1);
 
-			if (!errors.length) {
-				var confirm_str = 'Do you really want to remove the following Managed Systems:';
+			var confirm_str = 'Do you really want to remove the following managed systems:';
+			if (selected_clusters.length > 0)
+				confirm_str += '\nClusters:\n-' + selected_clusters.join('\n-');
 
+			if (selected_storage.length > 0) {
 				if (selected_clusters.length > 0)
-					confirm_str += '\nClusters:\n' + selected_clusters.join('\n');
-				if (selected_storage.length > 0) {
-					if (selected_clusters.length > 0)
-						confirm_str += '\n';
-					confirm_str += '\nStorage Systems:\n' + selected_storage.join('\n');
-				}
+					confirm_str += '\n';
 
-				if (confirm(confirm_str))
-					form.submit();
-			} else {
-				alert('The following errors were found:\n\n' + errors.join('\n'));
-				return (-1);
+				confirm_str += '\nStorage Systems:\n-' + selected_storage.join('\n-');
 			}
 
+			if (confirm(confirm_str))
+				form.submit();
 			return (0);
 		}
 	</script>
 
-	<form name="adminform" method="post" action="">
-		<span tal:omit-tag=""
-			tal:define="global clusters python:here.getClusters();
-						global systems python:here.getStorage();
-						global num_systems python:-1;
-						global num_clusters python:-1"
-		/>
-
-		<h2 class="homebase" tal:condition="python:systems">Remove Systems</h2>
-
-		<input type="hidden" name="numStorage" id="numStorage"
-			tal:attributes="value python: len(systems)" />
-		<input type="hidden" name="numClusters" id="numClusters"
-			tal:attributes="value python: len(clusters)" />
+	<span tal:omit-tag=""
+		tal:define="global systems python:here.getSystems();
+					global blankForm python:1;
+					global num_clusters python:-1;
+					global num_systems python:-1"
+	/>
+
+	<form name="adminform" method="post" action=""
+		tal:condition="python:(systems[0] and len(systems[0]) > 0) or (systems[1] and len(systems[1]) > 0)">
+
+		<span tal:omit-tag="" tal:define="global blankForm python:0" />
+
+		<h2 class="homebase" tal:condition="python:systems">
+			Remove Systems and Clusters
+		</h2>
+
 		<input type="hidden" name="pagetype"
 			tal:attributes="value request/pagetype | request/form/pagetype | nothing" />
-		<input type="hidden" name="absoluteURL"
-			tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
 
-		<tal:block tal:repeat="s python:systems">
-			<input type="checkbox" class="hombase"
-				tal:define="global num_systems python:num_systems + 1"
-				tal:attributes="
-					name python:'__SYSTEM:' + here.strFilter('[^0-9A-Za-z_-]', '_', s[0]);
-					id python:'__SYSTEM' + str(num_systems);
-					value python:s[0]"
-			/>
-			<input type="hidden" value=""
-				tal:attributes="name python:'__SYSTEM:' + here.strFilter('[^0-9A-Za-z_-]', '_', s[0])" />
-			<span class="hbText" tal:omit-tag="" tal:content="python:s[0]"/>
-			<br />
-		</tal:block>
+		<h3 class="homebase" tal:condition="python: systems[0] and len(systems[0]) > 0">
+			Clusters
+		</h3>
+
+		<tal:block tal:repeat="c python:systems[0]">
+			<div class="hbcheckdiv"
+					tal:define="cfname python: here.strFilter('[^0-9A-Za-z_-]', '_', c)"
+					tal:attributes="id python: cfname">
+
+				<input type="checkbox" class="homebase"
+					tal:define="global num_clusters python:num_clusters + 1"
+					tal:attributes="
+						name python:'__CLUSTER:' + cfname;
+						id python:'__CLUSTER' + str(num_clusters);
+						onChange python: 'checkChildren(\'' + cfname + '\', this)';
+						value python: c"
+				/>
+				<input type="hidden" value=""
+					tal:attributes="
+						name python:'__CLUSTER:' + cfname"
+				/>
+				<span tal:omit-tag="" tal:content="python:c" />
 
-		<h2 class="homebase" tal:condition="python:clusters">Remove Clusters</h2>
-		<tal:block tal:repeat="c python:clusters">
-			<input type="checkbox" class="hombase"
-				tal:define="global num_clusters python:num_clusters + 1"
-				tal:attributes="
-					name python:'__CLUSTER:' + here.strFilter('[^0-9A-Za-z_-]', '_', c[0]);
-					id python:'__CLUSTER' + str(num_clusters);
-					value python:c[0]"
-			/>
-			<input type="hidden" value=""
-				tal:attributes="name python:'__CLUSTER:' + here.strFilter('[^0-9A-Za-z_-]', '_', c[0])" />
-			<span class="hbText" tal:omit-tag="" tal:content="python:c[0]"/>
-			<br />
+				<tal:block tal:repeat="cs python:systems[0][c]">
+					<div class="hbcheckdiv"
+						tal:define="csfname python: here.strFilter('[^0-9A-Za-z_-]', '_', cs)">
+
+						<input type="checkbox" class="hombase"
+							tal:define="global num_systems python:num_systems + 1"
+							tal:attributes="
+								name python:'__SYSTEM:' + csfname;
+								id python:'__SYSTEM' + str(num_systems);
+								value python:cs"
+						/>
+
+						<input type="hidden" value=""
+							tal:attributes="name python:'__SYSTEM:' + csfname" />
+						<span class="hbText" tal:omit-tag="" tal:content="python:cs" />
+					</div>
+				</tal:block>
+			</div>
 		</tal:block>
 
+		<div tal:omit-tag="" tal:condition="python: systems[1] and len(systems[1]) > 0">
+			<h3 class="homebase">Unclustered Systems</h3>
+
+			<tal:block tal:repeat="s python: systems[1]">
+				<div class="hbcheckdiv"
+					tal:define="sfname python: here.strFilter('[^0-9A-Za-z_-]', '_', s)">
+
+					<input type="checkbox" class="hombase"
+						tal:define="global num_systems python:num_systems + 1"
+						tal:attributes="
+							name python:'__SYSTEM:' + sfname;
+							id python:'__SYSTEM' + str(num_systems);
+							value python:s"
+					/>
+
+					<input type="hidden" value=""
+						tal:attributes="name python:'__SYSTEM:' + sfname" />
+					<span class="hbText" tal:omit-tag="" tal:content="python:s"/>
+				</div>
+			</tal:block>
+		</div>
+
+		<input type="hidden" id="numStorage"
+			tal:attributes="value python: num_systems + 1" />
+
+		<input type="hidden" id="numClusters"
+			tal:attributes="value python: num_clusters + 1" />
 
-		<div class="hbSubmit" tal:condition="python: clusters or systems">
+		<div class="hbSubmit" id="hbSubmit">
 			<input type="button" class="hbSubmit" name="Submit" value="Submit" onClick="validateForm(document.adminform);" />
 		</div>
-		<span tal:condition="python:(not clusters) and (not systems)">
-			No clusters or storage systems.
-		</span>
 	</form>
+
+	<div tal:condition="python: blankForm">
+		<p>No clusters or storage systems are currently being managed by Luci.</p>
+	</div>
 </div>
 
+
+
 <tal:comment replace="nothing">
+
+
 !###########################
 # SYSTEM ADD FORM          #
 ############################
+
+
 </tal:comment>
 
+
+
 <div metal:define-macro="system-add-form">
-	<form name="adminform" method="post" action="">
 	<tal:comment replace="nothing">
 		To validate for each storage system:
 			- Hostname and Password are given. (skip if both are blank)
@@ -473,368 +559,161 @@
 			- If not IP, make sure it's a FQDN with no invalid chars.
 	</tal:comment>
 
-	<h2 class="homebase">Add a Storage System</h2>
-	<input name="pagetype" type="hidden"
-		tal:attributes="value request/pagetype | request/form/pagetype | nothing" />
-
-	<input name="numSystems" id="numSystems" type="hidden" value="0" />
-
-	<input name="absoluteURL" type="hidden"
-		tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
-
-<tal:comment replace="nothing">XXX: refactor</tal:comment>
 	<script type="text/javascript">
-		var num_systems = 1;
-
-		function isValidHost(str) {
-			var i = str.split('.');
-
-			if (i.length == 1)
-				return ('Hostnames must be fully qualified.');
-
-			if (i.length == 4 && !isNaN(parseInt(i[3]))) {
-				var o1 = parseInt(i[0]);
-				var o2 = parseInt(i[1]);
-				var o3 = parseInt(i[2]);
-				var o4 = parseInt(i[3]);
-
-				if (isNaN(o1) || isNaN(o2) || isNaN(o3) ||
-					((o1 & 0xff) != o1) ||
-					((o2 & 0xff) != o2) ||
-					((o3 & 0xff) != o3) ||
-					((o4 & 0xff) != o4))
-				{
-					return ('Invalid IP Address.');
-				}
-
-				return (null);
-			}
-
-			if (!isNaN(parseInt(i[i.length - 1])))
-				return ('Invalid IP Address');
-
-			return (null);
-		}
-
 		function validateForm(form) {
 			var errors = new Array();
-			var added_storage = new Array();
 
 			if (!form)
 				return (-1);
 
-			var allSameCB = document.getElementById('allSameCheckBox');
-			for (var i = 0 ; i < num_systems ; i++) {
-				var errmsg;
-				var element = document.getElementById('__SYSTEM' + i + ':Addr');
-
-				if (!element)
-					continue;
-
-				var pwdElem = document.getElementById('__SYSTEM' + i + ':Passwd');
-				if (!element.value) {
-					if (pwdElem.value) {
-						if (!allSameCB.checked) {
-							errors.push('You entered a password, but no hostname for system ' + (i + 1));
-							continue;
-						} else
-							pwdElem.value = '';
-					}
-
-					continue;
-				}
-
-				if ((errmsg = isValidHost(element.value)))
-					errors.push(element.value + ' is not a valid hostname: ' + errmsg);
-				else {
-					pwdElem.disabled = false;
-					added_storage.push(element.value);
-				}
-			}
-
-			if (!errors.length) {
-				if (added_storage.length > 0 &&
-					confirm("Do you really want to add the following Storage Systems:\n" + added_storage.join('\n')))
-				{
-					var e = document.getElementById('numSystems');
-					if (e) {
-						form.submit();
-						e.value = num_systems;
-					}
-				}
-			} else {
-				alert('The following errors were found:\n\n' + errors.join('\n'));
+			var added_storage = validate_systems(form, errors);
+			if (error_dialog(errors))
 				return (-1);
+
+			if (added_storage.length > 0 &&
+				confirm("Do you really want to add the following Storage Systems:\n" + added_storage.join('\n')))
+			{
+				form.submit();
 			}
 
 			return (0);
 		}
+	</script>
 
-		function allPasswdsSame() {
-			var cb = document.getElementById('allSameCheckBox');
-			if (!cb)
-				return (-1);
-			var state = cb.checked;
-
-			var i = 1;
-			var passwd = document.getElementById('__SYSTEM0:Passwd').value;
-
-			if (!passwd || !state)
-				passwd = '';
-
-			for (var i = 1 ; i < num_systems ; i++) {
-				var element = document.getElementById('__SYSTEM' + i + ':Passwd')
-				element.value = passwd;
-				element.disabled = state;
-			}
-		}
+	<form name="adminform" method="post" action="">
+		<h2 class="homebase">Add a Storage System</h2>
 
-		function pwd0Change() {
-			if (document.getElementById('allSameCheckBox').checked)
-				allPasswdsSame();
-		}
-				
-		function addSystem() {
-			var sldiv = document.getElementById('systemsList');
-			if (!sldiv)
-				return;
-
-			var newsys = document.createElement('input');
-			newsys.setAttribute('name', '__SYSTEM' + num_systems + ':Addr');
-			newsys.setAttribute('id', '__SYSTEM' + num_systems + ':Addr');
-			newsys.setAttribute('type', 'text');
-			newsys.setAttribute('size', 32);
-			newsys.setAttribute('value', '');
-			newsys.setAttribute('maxlength', 256);
-				
-			var newsysp = document.createElement('input');
-			newsysp.setAttribute('name', '__SYSTEM' + num_systems + ':Passwd');
-			newsysp.setAttribute('id', '__SYSTEM' + num_systems + ':Passwd');
-			newsysp.setAttribute('type', 'password');
-			newsysp.setAttribute('size', 24);
-			newsysp.setAttribute('maxlength', 256);
-			newsysp.setAttribute('value', '');
-
-			var allSameCB = document.getElementById('allSameCheckBox');
-			if (allSameCB && allSameCB.checked) {
-				newsysp.setAttribute('value', document.getElementById('__SYSTEM0:Passwd').value);
-				newsysp.setAttribute('disabled', true);
-			}
+		<input name="pagetype" type="hidden"
+			tal:attributes="value request/pagetype | request/form/pagetype | nothing" />
 
-			var newdiv = document.createElement('div');
-			newdiv.setAttribute('class', 'hbSSysList');
-			newdiv.innerHTML = 'System Hostname ';
-			newdiv.appendChild(newsys);
-			newdiv.innerHTML += ' Password ';
-			newdiv.appendChild(newsysp);
-
-			sldiv.appendChild(newdiv);
-			++num_systems;
-
-			if (num_systems == 2) {
-				var button = document.createElement('input');
-				if (!button)
-					return (-1);
-				button.setAttribute('type', 'checkbox');
-				button.setAttribute('class', 'homebase');
-				button.setAttribute('name', 'allSameCheckBox');
-				button.setAttribute('id', 'allSameCheckBox');
-				button.setAttribute('onChange', 'allPasswdsSame();');
-					
-				var temps = document.getElementById('samePwdSpan');
-				temps.innerHTML = 'All Storage System Passwords Are the Same';
-				temps.appendChild(button);
-			}
-		}
-	</script>
+		<input name="numStorage" id="numStorage" type="hidden" value="1" />
 
-	<div id="systemsList" class="hbSSysList">
-		<div class="hbSSysList">
-		System Hostname
-		<input class="hbInputSys" type="text" id="__SYSTEM0:Addr" name="__SYSTEM0:Addr" size="32" maxlength="256" />
-		Password
-		<input type="password" size="24" id="__SYSTEM0:Passwd" name="__SYSTEM0:Passwd" maxlength="256" class="hbInputPass" onChange="pwd0Change();" />
-		</div>
-	</div>
+		<input name="absoluteURL" type="hidden"
+			tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
 
-	<div class="hbSubmit">
-		<input type="button" class="hbSubmit" value="Add Another Row" onClick="addSystem();" />
-	</div>
 
-	<div id="samePwd" class="hbSubmit">
-		<span id="samePwdSpan" class="hbText" />
-	</div>
+		<div id="systemsList" class="hbSSysList">
+			<div class="hbSSysList">
+				System Hostname
+				<input class="hbInputSys" type="text" id="__SYSTEM0:Addr" name="__SYSTEM0:Addr" />
+				Password
+				<input type="password" id="__SYSTEM0:Passwd" name="__SYSTEM0:Passwd" class="hbInputPass" onChange="pwd0Change(adminform);" />
+			</div>
+		</div>
 
-	<div class="hbSubmit">
-		<input type="button" class="hbSubmit" name="Submit" value="Submit" onClick="validateForm(document.adminform);" />
-	</div>
+		<div class="hbSubmit">
+			<input type="button" class="hbSubmit" value="Add Another Row" onClick="addSystem(adminform);" />
+		</div>
 
-<tal:comment replace="nothing">end refactor</tal:comment>
+		<div id="samePwd" class="hbSubmit">
+			<span id="samePwdSpan" class="hbText" />
+		</div>
 
+		<div class="hbSubmit" id="hbSubmit">
+			<input type="button" class="hbSubmit" name="Submit" value="Submit" onClick="validateForm(document.adminform);" />
+		</div>
 	</form>
 </div>
 
 
 <tal:comment>
+
+
 !###########################
 # CLUSTER ADD FORM         #
 ############################
-</tal:comment>
-
-<div metal:define-macro="cluster-add-form">
-	<span tal:omit-tag=""
-		tal:define="global clusters python:here.getClusters()" />
-
-	<form name="adminform" action="" method="post">
-		<input name="pagetype" type="hidden"
-			tal:attributes="value request/pagetype | request/form/pagetype | nothing" />
-
-		<input name="numSystems" id="numSystems" type="hidden" value="0" />
-
-		<input name="absoluteURL" type="hidden"
-			tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
 
-		<h2 class="homebase">Add Cluster</h2>
 
-		<span class="hbText">Cluster Name</span>
-		<input class="hbInputSys" type="text" id="clusterName" name="clusterName" size="32" maxlength="256" />
-
-<tal:comment replace="nothing">XXX: refactor</tal:comment>
+</tal:comment>
 
+<div metal:define-macro="cluster-add-form">
 	<tal:comment replace="nothing">
-		XXX: things to validate
-		- Cluster name is specified and contains only valid chars
-		- At least one node name/password are given and are valid
+		Things to validate
+			- Cluster name is specified and contains only valid chars
+			- At least one node name/password are given and are valid
 	</tal:comment>
 
 	<script type="text/javascript">
-		var num_systems = 3;
-
 		function validateForm(form) {
 			var errors = new Array();
 
-			if (!form)
-				return (-1);
-
-			if (!errors.length) {
-				if (confirm("Submit form?")) {
-					var e = document.getElementById('numSystems');
-					if (e) {
-						form.submit();
-						e.value = num_systems;
-					}
-					form.submit();
-				}
+			if (!form || !form.clusterName ||
+				str_is_blank(form.clusterName.value))
+			{
+				errors.push('No cluster name was given.');
 			} else {
-				alert('The following errors were found:\n\n' + errors.join('\n'));
-				return (-1);
+				var invalid_chars = str_is_valid(form.clusterName.value, '/[0-9A-Za-z_. -]/g');
+				if (invalid_chars)
+					errors.push('The cluster name you gave contains the following invalid characters: "' + invalid_chars + '".');
 			}
 
-			return (0);
-		}
+			var added_storage = validate_systems(form, errors);
 
-		function allPasswdsSame() {
-			var cb = document.getElementById('allSameCheckBox');
-			if (!cb)
-				return (-1);
-			var state = cb.checked;
-
-			var i = 1;
-			var passwd = document.getElementById('__SYSTEM0:Passwd').value;
-
-			if (!passwd || !state)
-				passwd = '';
-
-			for (var i = 1 ; i < num_systems ; i++) {
-				var element = document.getElementById('__SYSTEM' + i + ':Passwd')
-				element.value = passwd;
-				element.disabled = state;
-			}
-		}
-
-		function pwd0Change() {
-			if (document.getElementById('allSameCheckBox').checked)
-				allPasswdsSame();
-		}
-				
-		function addSystem() {
-			var allSame = document.getElementById('allSameCheckBox').checked;
-			var sldiv = document.getElementById('systemsList');
-			if (!sldiv)
-				return;
-
-			var newsys = document.createElement('input');
-			newsys.setAttribute('name', '__SYSTEM' + num_systems + ':Addr');
-			newsys.setAttribute('id', '__SYSTEM' + num_systems + ':Addr');
-			newsys.setAttribute('type', 'text');
-			newsys.setAttribute('size', 32);
-			newsys.setAttribute('maxlength', 256);
-			newsys.setAttribute('value', '');
-			
-			var newsysp = document.createElement('input');
-			newsysp.setAttribute('name', '__SYSTEM' + num_systems + ':Passwd');
-			newsysp.setAttribute('id', '__SYSTEM' + num_systems + ':Passwd');
-			newsysp.setAttribute('type', 'password');
-			newsysp.setAttribute('size', 24);
-			newsysp.setAttribute('value', '');
-			newsysp.setAttribute('maxlength', 256);
-			if (allSame) {
-				newsysp.setAttribute('value', document.getElementById('__SYSTEM0:Passwd').value);
-				newsysp.setAttribute('disabled', true);
-			}
+			if (error_dialog(errors))
+				return (-1);
 
-			var newsdiv = document.createElement('div');
-			newdiv.setAttribute('class', 'hbSSysList');
-			newdiv.innerHTML = 'System Hostname ';
-			newdiv.appendChild(newsys);
-			newdiv.innerHTML += ' Password ';
-			newdiv.appendChild(newsysp);
+			if (confirm("Submit form?"))
+				form.submit();
 
-			sldiv.appendChild(newdiv);
-			++num_systems;
+			return (0);
 		}
 	</script>
 
-	<div id="systemsList" class="hbCSystems" style="margin-left:1em;padding-top:1em">
-		<div class="hbSSysList">
-			System Hostname
-			<input class="hbInputSys" type="text" id="__SYSTEM0:Addr" name="__SYSTEM0:Addr" size="32" maxlength="256" />
-
-			Password
-			<input type="password" size="32" id="__SYSTEM0:Passwd" name="__SYSTEM0:Passwd" maxlength="256" class="hbInputPass" onChange="pwd0Change();" />
-		</div>
- 
-		<div class="hbSSysList">
-			System Hostname
-			<input class="hbInputSys" type="text" id="__SYSTEM1:Addr" name="__SYSTEM1:Addr" size="32" maxlength="256" />
-			Password
-			<input type="password" size="32" id="__SYSTEM1:Passwd" name="__SYSTEM1:Passwd" maxlength="256" class="hbInputPass" />
-		</div>
-
-		<div class="hbSSysList">
-			System Hostname
-			<input class="hbInputSys" type="text" id="__SYSTEM2:Addr" name="__SYSTEM2:Addr" size="32" maxlength="256" />
-			Password
-			<input type="password" size="32" id="__SYSTEM2:Passwd" name="__SYSTEM2:Passwd" maxlength="256" class="hbInputPass" />
+	<form name="adminform" action="" method="post">
+		<div id="systemsList" class="hbCSystems">
+			<span tal:omit-tag=""
+				tal:define="global clusters python:here.getClusters()" />
+
+			<input name="pagetype" type="hidden"
+				tal:attributes="value request/pagetype | request/form/pagetype | nothing" />
+
+			<input name="numStorage" id="numStorage" type="hidden" value="3" />
+
+			<input name="absoluteURL" type="hidden"
+				tal:attributes="value python:data['children'][data['curIndex']]['absolute_url']" />
+
+			<h2 class="homebase">Add Cluster</h2>
+
+			<span class="hbText">Cluster Name</span>
+			<input class="hbInputSys" type="text" id="clusterName" name="clusterName" />
+
+			<div class="hbSSysList">
+				System Hostname
+				<input class="hbInputSys" type="text" id="__SYSTEM0:Addr" name="__SYSTEM0:Addr" />
+				Password
+				<input type="password" id="__SYSTEM0:Passwd" name="__SYSTEM0:Passwd" class="hbInputPass" onChange="pwd0Change(adminform);" />
+			</div>
+
+			<div class="hbSSysList">
+				System Hostname
+				<input class="hbInputSys" type="text" id="__SYSTEM1:Addr" name="__SYSTEM1:Addr" />
+				Password
+				<input type="password" id="__SYSTEM1:Passwd" name="__SYSTEM1:Passwd" class="hbInputPass" />
+			</div>
+
+			<div class="hbSSysList">
+				System Hostname
+				<input class="hbInputSys" type="text" id="__SYSTEM2:Addr" name="__SYSTEM2:Addr" />
+				Password
+				<input type="password" id="__SYSTEM2:Passwd" name="__SYSTEM2:Passwd" class="hbInputPass" />
+			</div>
 		</div>
-	</div>
 
-	<div class="hbSubmit" style="padding-top:1em">
-		<input type="button" class="hbSubmit" value="Add Another Row" onClick="addSystem();" />
-	</div>
-
-	<div class="hbSubmit">
-		All Storage System Passwords Are the Same
-		<input class="hbSubmit" type="checkbox" name="allSameCheckBox" id="allSameCheckBox" onClick="allPasswdsSame();" />
-	</div>
+		<div class="hbSubmit">
+			<input type="button" class="hbSubmit" value="Add Another Row" onClick="addSystem(adminform);" />
+		</div>
 
-	<div class="hbSubmit" style="padding-top:1em">
-		<input type="button" class="hbSubmit" name="Submit" value="Submit" onClick="validateForm(document.adminform);" />
-	</div>
+		<div class="hbSubmit">
+			All Storage System Passwords Are the Same
+			<input class="hbSubmit" type="checkbox" name="allSameCheckBox" id="allSameCheckBox" onClick="allPasswdsSame(adminform);" />
+		</div>
 
-<tal:comment replace="nothing">XXX: end refactor</tal:comment>
+		<div class="hbSubmit" id="hbSubmit">
+			<input type="button" class="hbSubmit" name="Submit" value="Submit" onClick="validateForm(document.adminform);" />
+		</div>
 	</form>
 </div>
 
+
 </body>
 </html>
--- conga/luci/homebase/index_html	2006/05/25 22:34:24	1.6
+++ conga/luci/homebase/index_html	2006/06/20 21:21:47	1.7
@@ -1,15 +1,21 @@
-<metal:page define-macro="master"><metal:doctype define-slot="doctype"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";></metal:doctype>
+<metal:page define-macro="master">
+
+<metal:doctype define-slot="doctype">
+	<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd";>
+</metal:doctype>
+
 <metal:block define-slot="top_slot" />
+
 <metal:block use-macro="here/global_defines/macros/defines" />
 
 <html xmlns="http://www.w3.org/1999/xhtml";
-      xml:lang="en"
-      lang="en"
-      tal:attributes="lang language;
-                      xml:lang language">
- 
+	xml:lang="en"
+	lang="en"
+	tal:attributes="lang language;
+					xml:lang language">
+
 <tal:comment replace="nothing">
-	$Id: index_html,v 1.6 2006/05/25 22:34:24 rmccabe Exp $
+	$Id: index_html,v 1.7 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
 <head metal:use-macro="here/header/macros/html_header">
@@ -19,115 +25,313 @@
 		</metal:baseslot>
 	</metal:fillbase>
 
-    <metal:headslot fill-slot="head_slot"
-                    tal:define="lang language;
-                                charset site_properties/default_charset|string:utf-8">
-
-      <metal:cache use-macro="here/global_cache_settings/macros/cacheheaders">
-        Get the global cache headers located in global_cache_settings.
-      </metal:cache>
-
-      <metal:headslot define-slot="head_slot" />
-      <tal:comment replace="nothing"> A slot where you can insert elements in the header from a template </tal:comment>
-    </metal:headslot>
-
-    <metal:cssslot fill-slot="css_slot">
-      <tal:comment replace="nothing"> A slot where you can insert CSS in the header from a template </tal:comment>
-    
-  <style type="text/css">
+	<metal:headslot fill-slot="head_slot"
+					tal:define="lang language;
+								charset site_properties/default_charset|string:utf-8">
+
+	<metal:cache use-macro="here/global_cache_settings/macros/cacheheaders">
+		Get the global cache headers located in global_cache_settings.
+	</metal:cache>
+
+	<metal:headslot define-slot="head_slot" />
+		<tal:comment replace="nothing"> A slot where you can insert elements in the header from a template </tal:comment>
+	</metal:headslot>
+
+	<metal:cssslot fill-slot="css_slot">
+		<tal:comment replace="nothing"> A slot where you can insert CSS in the header from a template </tal:comment>
+
+<style type="text/css">
 	<!-- @import url(../cluster/clusterportlet.css); -->
-  </style>
+</style>
 
-  <style media="all" type="text/css">
-	<!-- @import url("luci_homebase.css"); -->
-  </style>
-
-      <metal:cssslot define-slot="css_slot" />
-    </metal:cssslot>
-
-    <metal:javascriptslot fill-slot="javascript_head_slot">
-      <tal:comment replace="nothing"> A slot where you can insert javascript in the header from a template </tal:comment>
-      <metal:javascriptslot define-slot="javascript_head_slot" />
-    </metal:javascriptslot>
-  </head>
-
-  <body tal:attributes="class here/getSectionFromURL;
-                        dir python:test(isRTL, 'rtl', 'ltr')">
-    <div id="visual-portal-wrapper">
-
-      <div id="portal-top" i18n:domain="plone">
-
-        <div id="portal-header">
-          <a class="hiddenStructure"
-             accesskey="2"
-             tal:attributes="href string:${request/ACTUAL_URL}#documentContent"
-             i18n:translate="label_skiptocontent">Skip to content.</a>
-
-          <a class="hiddenStructure"
-             accesskey="6"
-             tal:attributes="href string:${request/ACTUAL_URL}#portlet-navigation-tree"
-             i18n:translate="label_skiptonavigation">Skip to navigation</a>
-
-             <a metal:use-macro="here/main_logo/macros/main_portal_logo">
-               The portal logo, linked to the portal root
-             </a>
-
-             <div metal:use-macro="here/main_sections/macros/portal_tabs" tal:condition="python:here.userAuthenticated()">
-               The global sections tabs. (Welcome, News etc)
-             </div>
-          </div>
-
-          <div metal:use-macro="here/main_personalbar/macros/personal_bar">
-             The personal bar. (log in, logout etc...)
-           </div>
-
-      <div class="visualClear"><!-- --></div>
-
-      <tal:comment replace="nothing">
-      The wrapper table. It contains the three columns. There's a table-less
-      alternative in the plone_tableless skin layer that you can use if you
-      prefer layouts that don't use tables.
-      </tal:comment> 
-
-      <table id="portal-columns">
-        <tbody>
-          <tr>
-            <tal:comment replace="nothing"> Start of the left column </tal:comment>
-            <td id="portal-column-one"
-                metal:define-slot="column_one_slot"
-                tal:condition="sl"
-				tal:omit-tag="python:not here.userAuthenticated()">
-              <div class="visualPadding">
-                <metal:portlets define-slot="portlets_one_slot">
-                  <metal:leftportlets use-macro="here/homebase_portlet_fetcher/macros/left_column">
-                    This instruction gets the portlets (boxes) for the left column.
-                  </metal:leftportlets>
-                </metal:portlets>
-                &nbsp;
-              </div>
-            </td>
-            <tal:comment replace="nothing"> End of the left column </tal:comment>
-
-            <tal:comment replace="nothing"> Start of main content block </tal:comment>
-            <td id="portal-column-content">
-
-              <metal:block define-slot="content">
-                <div id="content"
-                     metal:define-macro="content">
-
-  
-
-                  <div class="documentContent" id="region-content">
-
-                    <a name="documentContent"></a>
-
-                    <metal:bodytext metal:define-slot="main" tal:content="nothing">
-                
-                      Page body text
-                    </metal:bodytext>
+<style type="text/css">
+	<!-- @import url(/luci/homebase/luci_homebase.css); -->
+</style>
+
+<tal:block tal:omit-tag="" 
+	tal:define="global data python:here.homebaseControl(request)" />
+
+<metal:cssslot define-slot="css_slot" />
+	</metal:cssslot>
+
+	<metal:javascriptslot fill-slot="javascript_head_slot">
+		<tal:comment replace="nothing"> A slot where you can insert javascript in the header from a template </tal:comment>
+		<metal:javascriptslot define-slot="javascript_head_slot" />
+
+<script type="text/javascript">
+function error_dialog(errors) {
+	if (!errors || errors.length < 1)
+		return (null);
+	alert('The following errors were found:\n\n' + errors.join('\n'));
+	return (-1);
+}
+
+function str_is_blank(str) {
+	return (!str || !str.replace(/\s/g, ''));
+}
+
+function str_is_valid(str, valid_regex_str) {
+	if (!str || !valid_regex_str)
+		return (null);
+	var re = eval(valid_regex_str);
+	var invalid = str.replace(re, '');
+	if (!invalid)
+		return (null);
+	return (invalid);
+}
+
+function checkAllBoxes(str, val) {
+	var i = 0;
+	var element;
+	while ((element = document.getElementById(str + i++)))
+		element.checked = val;
+}
+
+function checkChildren(parent_cont, parent_input) {
+	if (!parent_cont || !parent_input)
+		return
+	parent = document.getElementById(parent_cont);
+	children = parent.getElementsByTagName('input')
+	for (var i = 0 ; i < children.length ; i++) {
+		if (children[i] == parent_input)
+			continue;
+		if (children[i].type == 'checkbox')
+			children[i].checked = parent_input.checked;
+	}
+}
+
+function hide_element(id) {
+	var elem = document.getElementById(id);
+	if (elem)
+		elem.style['visibility'] = 'hidden';
+}
+
+function isValidHost(str) {
+	var i = str.split('.');
+
+	if (i.length == 1)
+		return ('Hostnames must be fully qualified.');
+
+	if (i.length == 4 && !isNaN(parseInt(i[3]))) {
+		var o1 = parseInt(i[0]);
+		var o2 = parseInt(i[1]);
+		var o3 = parseInt(i[2]);
+		var o4 = parseInt(i[3]);
+
+		if (isNaN(o1) || isNaN(o2) || isNaN(o3) ||
+			((o1 & 0xff) != o1) ||
+			((o2 & 0xff) != o2) ||
+			((o3 & 0xff) != o3) ||
+			((o4 & 0xff) != o4))
+		{
+			return ('Invalid IP Address.');
+		}
+
+		return (null);
+	}
+
+	if (!isNaN(parseInt(i[i.length - 1])))
+		return ('Invalid IP Address.');
+
+	if (!str.match(/^[0-9A-Za-z][0-9A-Za-z.-]*$/))
+		return ('Hostnames can contain only alphanumeric characters and hyphens.');
+
+	return (null);
+}
+
+function allPasswdsSame(form) {
+	var cb = document.getElementById('allSameCheckBox');
+	if (!cb)
+		return (-1);
+	var num_systems = form.numStorage.value;
+
+	var state = cb.checked;
+	var passwd = document.getElementById('__SYSTEM0:Passwd').value;
+	if (!passwd || !state)
+		passwd = '';
+
+	for (var i = 1 ; i < num_systems ; i++) {
+		var element = document.getElementById('__SYSTEM' + i + ':Passwd')
+		if (element) {
+			element.value = passwd;
+			element.disabled = state;
+		}
+	}
+}
+
+function pwd0Change(form) {
+	var element = document.getElementById('allSameCheckBox');
+	if (element && element.checked)
+		allPasswdsSame(form);
+}
+
+function addSystem(form) {
+	var sldiv = document.getElementById('systemsList');
+	if (!sldiv)
+		return;
+	var num_systems = form.numStorage.value;
+
+	var newsys = document.createElement('input');
+	newsys.setAttribute('style', 'padding:.20em !important;width:200px;');
+	newsys.setAttribute('name', '__SYSTEM' + num_systems + ':Addr');
+	newsys.setAttribute('id', '__SYSTEM' + num_systems + ':Addr');
+	newsys.setAttribute('type', 'text');
+	newsys.setAttribute('value', '');
+
+	var newsysp = document.createElement('input');
+	newsysp.setAttribute('style', 'padding:.20em !important;width:160px;');
+	newsysp.setAttribute('name', '__SYSTEM' + num_systems + ':Passwd');
+	newsysp.setAttribute('id', '__SYSTEM' + num_systems + ':Passwd');
+	newsysp.setAttribute('type', 'password');
+	newsysp.setAttribute('value', '');
+
+	var allSameCB = document.getElementById('allSameCheckBox');
+	if (allSameCB && allSameCB.checked) {
+		newsysp.setAttribute('value', document.getElementById('__SYSTEM0:Passwd').value);
+		newsysp.setAttribute('disabled', true);
+	}
+
+	var newdiv = document.createElement('div');
+
+	newdiv.setAttribute('style', 'margin-top: .25em;margin-bottom:.25em');
+	newdiv.innerHTML = 'System Hostname ';
+	newdiv.appendChild(newsys);
+	newdiv.innerHTML += ' Password ';
+	newdiv.appendChild(newsysp);
+
+	sldiv.appendChild(newdiv);
+	form.numStorage.value = ++num_systems;
+
+	if (num_systems == 2) {
+		var button = document.createElement('input');
+		if (!button)
+			return (-1);
+		button.setAttribute('type', 'checkbox');
+		button.setAttribute('class', 'homebase');
+		button.setAttribute('name', 'allSameCheckBox');
+		button.setAttribute('id', 'allSameCheckBox');
+		button.setAttribute('onChange', 'allPasswdsSame(document.adminform);');
+
+		var temps = document.getElementById('samePwdSpan');
+		temps.innerHTML = 'All Storage System passwords are the same';
+		temps.appendChild(button);
+	}
+}
+
+function validate_systems(form, errors) {
+	var allSameCB = document.getElementById('allSameCheckBox');
+	var added_storage = new Array();
+	var num_systems = form.numStorage.value;
+
+	for (var i = 0 ; i < num_systems ; i++) {
+		var element = document.getElementById('__SYSTEM' + i + ':Addr');
+
+		if (!element)
+			continue;
+
+		var pwdElem = document.getElementById('__SYSTEM' + i + ':Passwd');
+		if (!element.value) {
+			if (pwdElem.value) {
+				if (!allSameCB.checked) {
+					errors.push('You entered a password, but no hostname for system ' + (i + 1));
+					continue;
+				} else
+					pwdElem.value = '';
+			}
+
+			continue;
+		} else if (!pwdElem || !pwdElem.value)
+			errors.push('No password was given for \"' + element.value + '\"');
+		else if (str_is_blank(pwdElem.value))
+			errors.push('The password entered for \"' + element.value + '\" is blank.');
+
+		if (str_is_blank(element.value)) {
+			errors.push('You entered a blank hostname for system ' + (i + 1));
+			element.value = '';
+		} else {
+			var errmsg;
+			if ((errmsg = isValidHost(element.value)))
+				errors.push('\"' + element.value + '\" is not a valid hostname: ' + errmsg);
+			else {
+				pwdElem.disabled = false;
+				added_storage.push(element.value);
+			}
+		}
+	}
+
+	return (added_storage);
+}
+</script>
+</metal:javascriptslot>
+
+</head>
+
+<body tal:attributes="class here/getSectionFromURL;
+						dir python:test(isRTL, 'rtl', 'ltr')">
+	<div id="visual-portal-wrapper">
+
+	<div id="portal-top" i18n:domain="plone">
+
+		<div id="portal-header">
+			<a	class="hiddenStructure"
+				accesskey="2"
+			 	tal:attributes="href string:${request/ACTUAL_URL}#documentContent"
+			 	i18n:translate="label_skiptocontent">Skip to content.</a>
+
+			<a	class="hiddenStructure"
+				accesskey="6"
+				tal:attributes="href string:${request/ACTUAL_URL}#portlet-navigation-tree"
+				i18n:translate="label_skiptonavigation">Skip to navigation</a>
+
+			 <a metal:use-macro="here/main_logo/macros/main_portal_logo">
+				The portal logo, linked to the portal root
+			 </a>
+
+			 <div metal:use-macro="here/main_sections/macros/portal_tabs" tal:condition="python:here.userAuthenticated()">
+				The global sections tabs. (Welcome, News etc)
+			</div>
+		</div>
+
+		<div metal:use-macro="here/main_personalbar/macros/personal_bar">
+			The personal bar. (log in, logout etc...)
+		</div>
 
-        	<metal:main_form use-macro="here/form-chooser/macros/main-form">
-                <h1 tal:content="string:${cname}"></h1>
+		<div class="visualClear"><!-- --></div>
+
+	  <table id="portal-columns">
+		<tbody>
+		  <tr>
+			<tal:comment replace="nothing"> Start of the left column </tal:comment>
+			<td id="portal-column-one"
+				metal:define-slot="column_one_slot"
+				tal:define="lccond1 sl;lccond2 isAnon"
+				tal:condition="python:lccond1 and not lccond2">
+			  <div class="visualPadding">
+				<metal:portlets define-slot="portlets_one_slot">
+				  <metal:leftportlets use-macro="here/homebase_portlet_fetcher/macros/left_column">
+					This instruction gets the portlets (boxes) for the left column.
+				  </metal:leftportlets>
+				</metal:portlets>
+				&nbsp;
+			  </div>
+			</td>
+			<tal:comment replace="nothing"> End of the left column </tal:comment>
+
+			<tal:comment replace="nothing"> Start of main content block </tal:comment>
+			<td id="portal-column-content">
+
+			  <metal:block define-slot="content">
+				<div id="content"
+					 metal:define-macro="content">
+
+				  <div class="documentContent" id="region-content">
+					<a name="documentContent"></a>
+					<metal:bodytext metal:define-slot="main" tal:content="nothing">
+						Page body text
+					</metal:bodytext>
+
+			<metal:main_form use-macro="here/form-chooser/macros/main-form">
+				<h1 tal:content="string:${cname}"></h1>
 				Homebase
 			</metal:main_form>
 
@@ -135,55 +339,63 @@
 			tal:define="global ret python: request.SESSION.get('checkRet')"
 		/>
 
-		<div style="margin-top: 2em" class="retmsgs" tal:condition="python:(ret and 'messages' in ret and len(ret['messages']))">
+		<span tal:omit-tag="" tal:condition="python:request.SESSION.set('checkRet',{})" />
+
+		<div class="retmsgs" id="retmsgsdiv" tal:condition="python:(ret and 'messages' in ret and len(ret['messages']))">
+			<div class="hbclosebox">
+				<a href="javascript:hide_element('retmsgsdiv');"><img src="x.png"></a>
+			</div>
 			<ul class="retmsgs">
-	        <tal:block repeat="e python:ret['messages']">
-				<li class="retmsgs" style="color:green" tal:content="python:e" />
-			</tal:block>
+				<tal:block repeat="e python:ret['messages']">
+					<li class="retmsgs" tal:content="python:e" />
+				</tal:block>
 			</ul>
 		</div>
 
-		<div class="errmsgs" style="margin-top: 2em" tal:condition="python:(ret and 'errors' in ret and len(ret['errors']))">
-	        <p class="errmsgs" style="font-weight:800;color:red"> The following errors occurred:</p>
+		<div id="errmsgsdiv" class="errmsgs" tal:condition="python:(ret and 'errors' in ret and len(ret['errors']))">
+			<div class="hbclosebox">
+				<a class="hbclosebox" href="javascript:hide_element('errmsgsdiv');"><img src="x.png"></a>
+			</div>
+			<p class="errmsgs">The following errors occurred:</p>
 			<ul class="errmsgs">
-	        <tal:block repeat="e python:ret['errors']">
-				<li class="errmsgs" style="color:red" tal:content="python:e" />
-			</tal:block>
+				<tal:block repeat="e python:ret['errors']">
+					<li class="errmsgs" tal:content="python:e" />
+				</tal:block>
 			</ul>
 		</div>
 
 
-                  </div>
+				  </div>
 
-                </div>
+				</div>
 
-              </metal:block>
-            </td>
-            <tal:comment replace="nothing"> End of main content block </tal:comment>
+			  </metal:block>
+			</td>
+			<tal:comment replace="nothing"> End of main content block </tal:comment>
 
-          </tr>
-        </tbody>
-      </table>
-      <tal:comment replace="nothing"> end column wrapper </tal:comment>
+		  </tr>
+		</tbody>
+	  </table>
+	  <tal:comment replace="nothing"> end column wrapper </tal:comment>
 
-      <div class="visualClear"><!-- --></div>
+	  <div class="visualClear"><!-- --></div>
 
 
-      <hr class="netscape4" />
+	  <hr class="netscape4" />
 
-      <metal:block i18n:domain="plone">
+	  <metal:block i18n:domain="plone">
 
-        <metal:footer use-macro="here/main_footer/macros/portal_footer">
-          Footer
-        </metal:footer>
+		<metal:footer use-macro="here/main_footer/macros/portal_footer">
+		  Footer
+		</metal:footer>
 
-        <metal:colophon use-macro="here/colophon/macros/colophon">
-          The colophon area - contains details about the production of
-          the site. Typically "powered by" buttons, standards, tools used.
-        </metal:colophon>
-      </metal:block>
+		<metal:colophon use-macro="here/colophon/macros/colophon">
+		  The colophon area - contains details about the production of
+		  the site. Typically "powered by" buttons, standards, tools used.
+		</metal:colophon>
+	  </metal:block>
 
-    </div>
+	</div>
 
 </body>
 </html>
--- conga/luci/homebase/luci_homebase.css	2006/05/25 22:34:24	1.3
+++ conga/luci/homebase/luci_homebase.css	2006/06/20 21:21:47	1.4
@@ -1,51 +1,105 @@
-/* $Id: luci_homebase.css,v 1.3 2006/05/25 22:34:24 rmccabe Exp $ */
+/* $Id: luci_homebase.css,v 1.4 2006/06/20 21:21:47 rmccabe Exp $ */
 
-ul.errmsgs {
+*.errmsgs,*.retmsgs {
+	list-style-image: none !important;
+	list-style-type: none !important;
 }
 
-ul.retmsgs {
+*.errmsgs {
+	color: red !important;
 }
 
-li.errmsgs {
+h3.homebase {
+	color: #436976;
+	margin-top: 1em;
+	margin-bottom: .5em;
+	font-size: 12px;
+	font-weight: 800;
 }
 
-li.retmsgs {
+h2.homebase {
+	margin-bottom: +1em;
+	inherit;
+}
+
+*.retmsgs {
+	color: green !important;
 }
 
 p.errmsgs {
+	font-weight: 800;
 }
 
 div.errmsgs {
+	padding: .5em;
+	border-style: dotted;
+	border-width: 2px;
+	border-color: red;
+	margin-top: 2em;
+	max-width: 600px;
 }
 
 div.retmsgs {
+	padding: .5em;
+	margin-top: 2em;
+	border-style: dotted;
+	border-width: 2px;
+	border-color: green;
+	max-width: 600px;
 }
 
-*.homebase {
+div.hbCSystems {
+	margin-left:1em !important;
+	padding-top:.5em !important;
 }
 
-*.hbCSystems {
+div.hbSSysList {
+	margin-top: .25em !important;
+	margin-bottom: .25em !important;
 }
 
 div.hbSubmit {
-	margin-top: 1em !important;
+	margin-top: .5em;
+	margin-bottom: .5em;
+	margin-right: .5em;
+}
+
+#hbSubmit {
+	margin-top: +1em;
+	margin-left: 40%;
 }
 
 td.hbAddUser {
-	padding: 1em;
+	margin-top:.5em;
+	padding: .1em;
 }
 
-*.hbInputSys {
-	padding: .5em !important;
+div.hbcheckdiv {
+	padding-top: .25em;
+	padding-bottom: .25em;
 }
 
-*.hbInputPass {
-	padding: .5em !important;
+div.hbcheckdiv > div.hbcheckdiv {
+	margin-left: +1.5em;
 }
 
-div.hbSSysList {
-	margin-top: .5em !important;
-	margin-bottom: .5em !important;
+input.hbInputSys {
+	padding: .20em !important;
+	width: 200px;
+}
+
+input.hbInputPass {
+	padding: .20em !important;
+	width: 160px;
+}
+
+*.hbclosebox {
+   text-align: right;
+}
+
+div.systemsList {
+  margin-top: .25em !important;
+  margin-bottom: .25em !important;
 }
 
 *.hbText {
--- conga/luci/homebase/main_logo	2006/05/18 17:47:15	1.3
+++ conga/luci/homebase/main_logo	2006/06/20 21:21:47	1.4
@@ -1,17 +1,17 @@
 <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en"
-      i18n:domain="plone">
+	i18n:domain="plone">
+
+<head/>
 
 <body>
 
 <tal:comment replace="nothing">
-	$Id: main_logo,v 1.3 2006/05/18 17:47:15 rmccabe Exp $
+	$Id: main_logo,v 1.4 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
 <!--	THE PORTAL LOGO DEFINITION -->
 <h1 id="main-portal-logo" metal:define-macro="main_portal_logo">
-    <a href="/">
-        Luci
-    </a>
+	<a href="/">Luci</a>
 </h1>
 
 
--- conga/luci/homebase/main_pathbar	2006/05/18 17:47:15	1.3
+++ conga/luci/homebase/main_pathbar	2006/06/20 21:21:47	1.4
@@ -1,50 +1,57 @@
 <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en"
-      i18n:domain="plone">
+	i18n:domain="plone">
+
+<head/>
 
 <body>
 
 <tal:comment replace="nothing">
-	$Id: main_pathbar,v 1.3 2006/05/18 17:47:15 rmccabe Exp $
+	$Id: main_pathbar,v 1.4 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
 <!-- THE PATHBAR (breadcrumbs) DEFINITION -->
 
 <div metal:define-macro="path_bar"
-     id="portal-breadcrumbs"
-     tal:define="breadcrumbs python:putils.createBreadCrumbs(here);
-                     portal_url portal_url|utool">
+	id="portal-breadcrumbs"
+	tal:define="breadcrumbs python:putils.createBreadCrumbs(here);
+				portal_url portal_url|utool">
 
-    <span id="breadcrumbs-you-are-here" i18n:translate="you_are_here">
+	<span id="breadcrumbs-you-are-here" i18n:translate="you_are_here">
 		You are here:
 	</span>
 
-    <a i18n:translate="tabs_home" tal:attributes="href python:portal_url">
+	<a i18n:translate="tabs_home" tal:attributes="href python:portal_url">
 		Home
 	</a>
 
-    <span tal:condition="breadcrumbs" class="breadcrumbSeparator">
-        <tal:ltr condition="not: isRTL">&rarr;</tal:ltr> 
-        <tal:rtl condition="isRTL">&larr;</tal:rtl> 
-    </span>
-
-    <span tal:repeat="crumb breadcrumbs"
-          tal:attributes="dir python:test(isRTL, 'rtl', 'ltr')">
-        <tal:last tal:define="is_last repeat/crumb/end">
-            <a href="#"
-               tal:omit-tag="not: crumb/absolute_url"
-               tal:condition="python:not is_last"
-               tal:attributes="href crumb/absolute_url"
-               tal:content="crumb/Title">
-                crumb
-            </a>
-            <span class="breadcrumbSeparator" tal:condition="not: is_last"> 
-                <tal:ltr condition="not: isRTL">&rarr;</tal:ltr> 
-                <tal:rtl condition="isRTL">&larr;</tal:rtl> 
-            </span>
-            <span tal:condition="is_last"
-                  tal:content="crumb/Title">crumb</span>
-         </tal:last>
-    </span>
+	<span tal:condition="breadcrumbs" class="breadcrumbSeparator">
+		<tal:ltr condition="not: isRTL">&rarr;</tal:ltr>
+		<tal:rtl condition="isRTL">&larr;</tal:rtl>
+	</span>
+
+	<span
+		tal:repeat="crumb breadcrumbs"
+		tal:attributes="dir python:test(isRTL, 'rtl', 'ltr')">
+
+		<tal:last tal:define="is_last repeat/crumb/end">
+			<a href="#"
+				tal:omit-tag="not: crumb/absolute_url"
+				tal:condition="python:not is_last"
+				tal:attributes="href crumb/absolute_url"
+				tal:content="crumb/Title">crumb
+			</a>
+
+			<span class="breadcrumbSeparator" tal:condition="not: is_last">
+				<tal:ltr condition="not: isRTL">&rarr;</tal:ltr>
+				<tal:rtl condition="isRTL">&larr;</tal:rtl>
+			</span>
+
+			<span
+				tal:condition="is_last"
+				tal:content="crumb/Title">crumb
+			</span>
+		</tal:last>
+	</span>
 </div>
 
 </body>
--- conga/luci/homebase/main_personalbar	2006/05/18 17:47:15	1.3
+++ conga/luci/homebase/main_personalbar	2006/06/20 21:21:47	1.4
@@ -1,45 +1,52 @@
 <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en"
-      i18n:domain="plone">
+	i18n:domain="plone">
+
+<head/>
 
 <tal:comment replace="nothing">
-	$Id: main_personalbar,v 1.3 2006/05/18 17:47:15 rmccabe Exp $
+	$Id: main_personalbar,v 1.4 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
 <body>
 <!-- THE PERSONAL BAR DEFINITION -->
-<div metal:define-macro="personal_bar"
-      tal:define="display_actions python:user_actions[:-1]+global_actions+user_actions[-1:];
-                  getIconFor nocall:putils/getIconFor;"
-      tal:omit-tag="">
-
-<h5 class="hiddenStructure" i18n:translate="heading_personal_tools">Personal tools</h5>
-
-<ul id="portal-personaltools">
-    <li class="portalUser" 
-        tal:condition="not: isAnon"><a 
-        id="user-name"
-        tal:omit-tag="not: mtool/getHomeFolder"
-        tal:attributes="href string:${mtool/getHomeUrl}">
-        <span class="visualCaseSensitive"
-              tal:replace="user/getUserName">
-             John
-        </span>
-    </a></li>
-
-    <tal:actions tal:repeat="action python:here.getOrderedUserActions(keyed_actions=keyed_actions)">
-        <li tal:define="icon python:getIconFor(action['category'], action['id'], None);
-                        class_name string:actionicon-${action/category}-${action/id};
-                        class_name python:test(icon, class_name, nothing);"
-            tal:attributes="class class_name">
-            <a href=""
-               tal:attributes="href action/url;
-                               class python:test(icon, 'visualIconPadding', nothing);">
-               <tal:actionname i18n:translate="" tal:content="action/name">dummy</tal:actionname>
-            </a>
-        </li>
-    </tal:actions>
 
-</ul>
+<div metal:define-macro="personal_bar"
+	tal:define="display_actions python:user_actions[:-1]+global_actions+user_actions[-1:];
+				getIconFor nocall:putils/getIconFor;"
+	tal:omit-tag="">
+
+	<h5 class="hiddenStructure" i18n:translate="heading_personal_tools">Personal tools</h5>
+
+	<ul id="portal-personaltools">
+		<li class="portalUser"
+			tal:condition="not: isAnon">
+
+			<a	id="user-name"
+				tal:omit-tag="not: mtool/getHomeFolder"
+				tal:attributes="href string:${mtool/getHomeUrl}">
+				<span
+					class="visualCaseSensitive"
+					tal:replace="user/getUserName" />
+			</a>
+		</li>
+
+		<tal:actions
+			tal:repeat="action python:here.getOrderedUserActions(keyed_actions=keyed_actions)">
+
+			<li tal:define="icon python:getIconFor(action['category'], action['id'], None);
+				class_name string:actionicon-${action/category}-${action/id};
+				class_name python:test(icon, class_name, nothing);"
+				tal:attributes="class class_name">
+
+				<a	href=""
+					tal:attributes="href action/url;
+					class python:test(icon, 'visualIconPadding', nothing);">
+					<tal:actionname i18n:translate=""
+						tal:content="action/name">dummy</tal:actionname>
+				</a>
+			</li>
+		</tal:actions>
+	</ul>
 </div>
 
 </body>
--- conga/luci/homebase/main_sections	2006/05/18 17:47:15	1.3
+++ conga/luci/homebase/main_sections	2006/06/20 21:21:47	1.4
@@ -1,8 +1,10 @@
 <html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en"
-      i18n:domain="plone">
+	i18n:domain="plone">
+
+<head/>
 
 <tal:comment replace="nothing">
-	$Id: main_sections,v 1.3 2006/05/18 17:47:15 rmccabe Exp $
+	$Id: main_sections,v 1.4 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
 <body>
@@ -12,19 +14,20 @@
 	tal:omit-tag=""
 	tal:define="tabs python:here.getTabs(request)">
 
-    <h5 class="hiddenStructure" i18n:translate="heading_sections">Sections</h5>
+	<h5 class="hiddenStructure" i18n:translate="heading_sections">Sections</h5>
 
-    <ul id="portal-globalnav" tal:condition="python:here.userAuthenticated()">
-       <tal:tabs tal:repeat="tab tabs">
-        <li tal:attributes="id string:portaltab-${tab/Title};
-                            class python:test(tab['isSelected'], 'selected', 'plain');">
-            <a href="" 
-               tal:content="tab/Title"
-               tal:attributes="href tab/Taburl;
-                               title tab/Description|nothing">
-            Tab Name
-            </a></li></tal:tabs>
-    </ul>
+	<ul id="portal-globalnav" tal:condition="python:here.userAuthenticated()">
+		<tal:tabs tal:repeat="tab tabs">
+			<li tal:attributes="id string:portaltab-${tab/Title};
+							class python:test(tab['isSelected'], 'selected', 'plain');">
+				<a href=""
+					tal:content="tab/Title"
+					tal:attributes="href tab/Taburl;
+					title tab/Description|nothing">
+				Tab Name</a>
+			</li>
+		</tal:tabs>
+	</ul>
 </div>
 
 </body>
--- conga/luci/homebase/portlet_homebase	2006/05/18 17:47:15	1.6
+++ conga/luci/homebase/portlet_homebase	2006/06/20 21:21:47	1.7
@@ -1,22 +1,21 @@
 <html xmlns:tal="http://xml.zope.org/namespaces/tal";
-      xmlns:metal="http://xml.zope.org/namespaces/metal";>
+	xmlns:metal="http://xml.zope.org/namespaces/metal";>
+
+<head/>
 
 <body>
 
 <tal:comment replace="nothing">
-	$Id: portlet_homebase,v 1.6 2006/05/18 17:47:15 rmccabe Exp $
+	$Id: portlet_homebase,v 1.7 2006/06/20 21:21:47 rmccabe Exp $
 </tal:comment>
 
-<div metal:define-macro="homebase_portlet" tal:condition="python: here.userAuthenticated()">
-	<span tal:omit-tag=""
-		tal:define="global data python:here.homebaseControl(request)" />
-
-	<div tal:condition="python:here.isAdmin()" class="type-node">
-		<dl class="portlet" id="portlet-homebase">
-		<dt class="portletHeader"><a href="#" tal:content="user/getUserName"></a></dt>
+<div metal:define-macro="homebase_portlet">
+	<div class="type-node">
+	<dl class="portlet" id="portlet-homebase">
+	<dt class="portletHeader"><a href="/luci/homebase" tal:content="user/getUserName"></a></dt>
 
-		<dd class="portletItemSingle">
-		<ul class="portletCluConfigTree cluConfigTreeLevel0">
+	<dd class="portletItemSingle">
+	<ul class="portletCluConfigTree cluConfigTreeLevel0">
 		<tal:portal repeat="c python:data.get('children',[])">
 			<li tal:condition="not: c/currentItem" class="cluConfigTreeItem visualNoMarker">
 			<div tal:condition="not: c/currentItem">
@@ -28,17 +27,17 @@
 			</li>
 
 			<li tal:condition="c/currentItem" class="cluConfigTreeCurrentItem visualNoMarker">
-			<div tal:condition="c/currentItem">
-				<a class="visualIconPadding"
-					tal:attributes="href c/absolute_url;
-						title c/Description |nothing"
-					tal:content="c/Title|nothing">Title</a>
-			</div>
+				<div tal:condition="c/currentItem">
+					<a class="visualIconPadding"
+						tal:attributes="href c/absolute_url;
+							title c/Description |nothing"
+						tal:content="c/Title|nothing">Title</a>
+				</div>
 			</li>
 		</tal:portal>
-		</ul>
-		</dd>
-		</dl>
+	</ul>
+	</dd>
+	</dl>
 	</div>
 </div>
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]