[Debtags-commits] [svn] r1514 - central-database/branches/alioth/webfrontend

Enrico Zini enrico at costa.debian.org
Sat Nov 19 14:12:46 UTC 2005


Author: enrico
Date: Sat Nov 19 14:12:44 2005
New Revision: 1514

Modified:
   central-database/branches/alioth/webfrontend/edit.cgi
   central-database/branches/alioth/webfrontend/edittemplate.html
   central-database/branches/alioth/webfrontend/main.css
Log:
Tag editor now does all interaction client-side except for 'commit'.  WOW!

Modified: central-database/branches/alioth/webfrontend/edit.cgi
==============================================================================
--- central-database/branches/alioth/webfrontend/edit.cgi	(original)
+++ central-database/branches/alioth/webfrontend/edit.cgi	Sat Nov 19 14:12:44 2005
@@ -12,6 +12,7 @@
 use CGI qw/:standard/;
 use HTML::Template;
 use URI::Escape;
+use IO::String;
 use Engine;
 use Navigation;
 use Web qw/msg/;
@@ -101,64 +102,18 @@
 	for my $par (param())
 	{
 #		msg "Testing: %s\n", $par;
-		if ($par eq 'hf') {
-			my $hf = param($par);
-			%hidden_facets =
-				map { $_ => 1 }
-					grep { Engine::hasFacet(sanitize($_)) }
-						split(',', $hf);
-		} elsif ($par eq 'tags') {
+		if ($par eq 'navtags') {
 			$nav_tags = param($par);
 		} elsif ($par eq 'b') {
 			my $b = param($par);
 			$bayesian = 1 if ($b eq 'true');
 			$bayesian = 0 if ($b eq 'false');
-		} elsif ($par eq 'add') {
-			my $tag = sanitize(param($par));
-			my ($t) = Engine::tags($tag);
-			if (not defined $t)
+		} elsif ($par eq 'patch') {
+			my $patch = param($par);
+			if ($patch =~ /^[0-9A-Za-z.+:, -]+$/)
 			{
-				msg "$tag does not match a valid tag\n";
-			} else {
-				if (Engine::addTag($p, $t))
-				{
-					msg "Added tag $tag\n";
-					Navigation::invalidateCache();
-				}
-			}
-		} elsif ($par eq 'del') {
-			my $tag = sanitize(param($par));
-			my ($t) = Engine::tags($tag);
-			if (not defined $t)
-			{
-				msg "$tag does not match a valid tag\n";
-			} else {
-				if (Engine::removeTag($p, $t))
-				{
-					msg "Removed tag $tag\n";
-					Navigation::invalidateCache();
-				}
-			}
-		} elsif ($par eq 'fhide') {
-			my $fac = sanitize(param($par));
-			my ($f) = Engine::facets($fac);
-			$hidden_facets{$f->name} = 1
-				if defined $f;
-		} elsif ($par eq 'fdel') {
-			my $fac = sanitize(param($par));
-			my ($f) = Engine::facets($fac);
-			if (defined $f)
-			{
-				my @tags = grep { $p->hasTag($_) } $f->tags;
-				if (Engine::removeTag($p, @tags))
-				{
-					for my $t (@tags)
-					{
-						msg "Removed tag %s\n", $t->name;
-					}
-					Navigation::invalidateCache();
-				}
-				$hidden_facets{$f->name} = 1
+				my $in = IO::String->new($p->name.": ".$patch."\n");
+				Engine::applyPatch($in);
 			}
 		}
 	}
@@ -324,6 +279,7 @@
 	$template->param(SWITCHBAYESTXT => ($bayesian ? "turn prediction off" : "turn prediction on"));
 }
 $template->param(NAVIGATE => "index.cgi?tags=$nav_tags");
+$template->param(NAV_TAGS => $nav_tags);
 $template->param(COUNT_HIDDEN => scalar keys %hidden_facets);
 if (defined $p)
 {

Modified: central-database/branches/alioth/webfrontend/edittemplate.html
==============================================================================
--- central-database/branches/alioth/webfrontend/edittemplate.html	(original)
+++ central-database/branches/alioth/webfrontend/edittemplate.html	Sat Nov 19 14:12:44 2005
@@ -21,49 +21,238 @@
 	  f.name = "<tmpl_var name='NAME'>";
 	  f.sdesc = unescape("<tmpl_var name='SDESC'>");
 	  f.ldesc = unescape("<tmpl_var name='LDESC'>");
-	  f.hasTagsSorted = new Array();
-	  f.newTagsSorted = new Array();
+	  f.tagsSorted = new Array();
+	  f.tags = new Object();
+	  f.open = true;
 
 	  <tmpl_loop name="HASTAGS">
 		  var t = new Object;
-		  f.hasTags = new Object;
-		  f.hasTags["<tmpl_var name='NAME'>"] = t;
+		  f.tags["<tmpl_var name='NAME'>"] = t;
 		  t.name = "<tmpl_var name='NAME'>";
 		  t.sdesc = unescape("<tmpl_var name='SDESC'>");
 		  t.ldesc = unescape("<tmpl_var name='LDESC'>");
-		  t.remurl = unescape("<tmpl_var name='REMURL'>");
-		  f.hasTagsSorted.push(t);
+		  t.origSelected = true;
+		  t.selected = true;
+		  f.tagsSorted.push(t);
 	  </tmpl_loop>
 	  <tmpl_loop name="TAGS">
 		  var t = new Object;
-		  f.newTags = new Object;
-		  f.newTags["<tmpl_var name='NAME'>"] = t;
+		  f.tags["<tmpl_var name='NAME'>"] = t;
 		  t.name = "<tmpl_var name='NAME'>";
 		  t.sdesc = unescape("<tmpl_var name='SDESC'>");
 		  t.ldesc = unescape("<tmpl_var name='LDESC'>");
-		  t.addurl = unescape("<tmpl_var name='ADDURL'>");
-		  f.newTagsSorted.push(t);
+		  t.origSelected = false;
+		  t.selected = false;
+		  f.tagsSorted.push(t);
 	  </tmpl_loop>
 	  facetsSorted.push(f);
   </tmpl_loop>
 
-  var deletedNodes = new Object();
+  function getFacet(tag)
+  {
+  	return tag.slice(0, tag.indexOf("::"));
+  }
+  
+  function mkPatch()
+  {
+  	var res = new Array();
+  	for (i = 0; i < facetsSorted.length; i++)
+	{
+		var f = facetsSorted[i];
+		for (j = 0; j < facets[f.name].tagsSorted.length; j++)
+		{
+			var t = facets[f.name].tagsSorted[j];
+			if (t.origSelected == true && t.selected == false)
+				res.push("-"+t.name);
+			else if (t.origSelected == false && t.selected == true)
+				res.push("+"+t.name);
+		}
+	}
+	return res.join(', ');
+  }
+  
+  function hasChanges()
+  {
+  	for (i = 0; i < facetsSorted.length; i++)
+	{
+		var f = facetsSorted[i];
+		for (j = 0; j < facets[f.name].tagsSorted.length; j++)
+		{
+			var t = facets[f.name].tagsSorted[j];
+			if (t.origSelected != t.selected)
+				return true;
+		}
+	}
+	return false;
+  }
+
+  function mkOpenFacetBox(facet)
+  {
+	var res = "";
+	var f = facets[facet];
+	res += "\t<div class='facetbuttons'>\n";
+	res += "\t\t<span class='button' onclick='hideFacet(\""+f.name+"\")'>[done with this]</span><br />\n";
+	res += "\t\t<span class='button' onClick='remFacet(\""+f.name+"\")'>[does not apply]</span>\n";
+	res += "\t</div>\n";
+	res += "\t<div class='intro'>\n";
+	res += "\t\t<p>\n";
+	res += "\t\t\t<b>"+f.sdesc+"</b>\n";
+	//<tmpl_if name="PPROB">(<tmpl_var name="PPROB">%)</tmpl_if>
+	res += "\t\t</p>\n";
+	res += "\t\t<p>"+f.ldesc+"</p>\n";
+	res += "\t</div>\n";
+	res += "\t<ul>\n";
+	for (j = 0; j < facets[f.name].tagsSorted.length; j++)
+	{
+		var t = facets[f.name].tagsSorted[j];
+		if (t.selected == true)
+		{
+			res += "\t<li>\n";
+			res += "\t\t<b>"+t.sdesc+"</b>\n";
+			// res += "\t\t<tmpl_if name="NPROB">(<tmpl_var name="NPROB">%)</tmpl_if>";
+			res += "\t\t<span class='button' onClick='remTag(\""+t.name+"\")'>[remove]</a>\n";
+			res += "\t</li>\n";
+		}
+	}
+	for (j = 0; j < facets[f.name].tagsSorted.length; j++)
+	{
+		var t = facets[f.name].tagsSorted[j];
+		if (t.selected == false)
+		{
+			res += "\t<li>\n";
+			res += "\t\t"+t.sdesc+"\n";
+			// res += "\t\t<tmpl_if name="NPROB">(<tmpl_var name="NPROB">%)</tmpl_if>";
+			res += "\t\t<span class='button' onClick='addTag(\""+t.name+"\")'>[add]</a>\n";
+			res += "\t</li>\n";
+		}
+	}
+	res += "\t</ul>\n";
+	return res;
+  }
+  function mkClosedFacetBox(facet)
+  {
+	var f = facets[facet];
+	return "<span class='button' onclick='showFacet(\""+f.name+"\")'>[expand "+f.name+": "+f.sdesc+"]</span>";
+  }
+  function mkCurTags()
+  {
+  	var res = "";
+	var found = 0;
+  	for (i = 0; i < facetsSorted.length; i++)
+	{
+		var f = facetsSorted[i];
+		for (j = 0; j < facets[f.name].tagsSorted.length; j++)
+		{
+			var t = facets[f.name].tagsSorted[j];
+			if (t.selected == true)
+			{
+				res += "\t<li>"+t.sdesc+" <span class='button' onClick='remTag(\""+t.name+"\")'>[remove]</a></li>\n";
+				++found;
+			}
+		}
+	}
+	if (found == 0)
+		res += "\t<li>(no tags are currently attached to this package)</li>\n";
+	return res;
+  }
+  function mkCurTagsButtons()
+  {
+  	var res = "";
+	if (hasChanges())
+	{
+		res += "<span class='button' onClick='commit()'>[submit]</span>\n";
+		res += "<span class='button' onClick='undoAll()'>[undo all changes]</span>\n";
+	}
+	return res;
+  }
+  function updateCurTags()
+  {
+	node = document.getElementById("curtags-list")
+	node.innerHTML = mkCurTags();
+
+	node = document.getElementById("curpatch")
+	node.innerHTML = mkPatch();
+
+	node = document.getElementById("curtags-buttons")
+	node.innerHTML = mkCurTagsButtons();
+  }
+
   function hideFacet(facet)
   {
-  	var s = new String;
 	node = document.getElementById("editfacet-"+facet)
-	deletedNodes[facet] = node.innerHTML;
-	node.innerHTML = "<span class='button' onclick='showFacet(\""+facet+"\")'>[expand "+facet+": "+facets[facet].sdesc+"]</span> ";
+	node.innerHTML = mkClosedFacetBox(facet);
+	facets[facet].open = false;
   }
   function showFacet(facet)
   {
-	if (deletedNodes[facet])
+	node = document.getElementById("editfacet-"+facet)
+	node.innerHTML = mkOpenFacetBox(facet);
+	facets[facet].open = true;
+  }
+  function updateFacet(facet)
+  {
+	node = document.getElementById("editfacet-"+facet)
+	if (facets[facet].open)
+		node.innerHTML = mkOpenFacetBox(facet);
+	else
+		node.innerHTML = mkClosedFacetBox(facet);
+  }
+
+  function addTag(tag)
+  {
+  	facet = getFacet(tag);
+	facets[facet].tags[tag].selected = true;
+	updateFacet(facet);
+	updateCurTags();
+  }
+  
+  function remTag(tag)
+  {
+  	facet = getFacet(tag);
+	facets[facet].tags[tag].selected = false;
+	updateFacet(facet);
+	updateCurTags();
+  }
+
+  function remFacet(facet)
+  {
+	var f = facets[facet];
+	for (j = 0; j < f.tagsSorted.length; j++)
 	{
-		node = document.getElementById("editfacet-"+facet)
-		node.innerHTML = deletedNodes[facet];
-		deletedNodes[facet] = false;
+	        var t = facets[f.name].tagsSorted[j];
+		t.selected = false;
 	}
+	hideFacet(facet);
+	updateCurTags();
   }
+
+  function updateAll()
+  {
+  	updateCurTags();
+  	for (i = 0; i < facetsSorted.length; i++)
+		updateFacet(facetsSorted[i].name);
+  }
+
+  function undoAll()
+  {
+  	for (i = 0; i < facetsSorted.length; i++)
+	{
+		var f = facetsSorted[i];
+		for (j = 0; j < facets[f.name].tagsSorted.length; j++)
+		{
+			var t = facets[f.name].tagsSorted[j];
+			t.selected = t.origSelected;
+		}
+	}
+	updateAll();
+  }
+
+  function commit()
+  {
+	document.patch.patch.value = mkPatch();
+	document.patch.submit();
+  }
+
   //-->
   </script>
 </head>
@@ -82,8 +271,8 @@
     <p>Please <em>help</em> sorting the
     <a href="index.cgi?tags=special::not-yet-tagged">not yet tagged</a> packages.
     For more information (creating new tags etc.) visit the
-    <a href="http://debtags.alioth.debian.org/">Debtags Homepage</a> at <a href="http://alioth.debian.org/">Alioth</a>.</p>
-    <p>Please don't forget to remove the "not-yet-tagged" Tags!</p>
+    <a href="http://debtags.alioth.debian.org/">Debtags Homepage</a>.</p>
+    <p>Don't forget to submit your changes when you are happy with them, and to remove the "not-yet-tagged" tags.</p>
   </div>
 
   <TMPL_IF NAME="MESSAGE">
@@ -105,30 +294,28 @@
     <tmpl_if name="SWITCHBAYES">
       <a href="<tmpl_var name='SWITCHBAYES'>">[<tmpl_var name='SWITCHBAYESTXT'>]</a>
     </tmpl_if>
-    <div id="hiddenFacets">
+    <div id="curpatch">
     </div>
   </div>
 
   <div id="curtags">
-  <tmpl_if name="COUNT_TAGS">
     <p><b>Currently attached tags:</b>
-    <ul>
+    <ul id="curtags-list">
       <script type="text/javascript">
-  	for (i = 0; i < facetsSorted.length; i++)
-	{
-		var f = facetsSorted[i];
-		for (j = 0; j < facets[f.name].hasTagsSorted.length; j++)
-		{
-			var t = facets[f.name].hasTagsSorted[j];
-			document.write("\t<li>"+t.sdesc+" <a class='button' href='"+t.remurl+"'>[remove]</a></li>\n");
-		}
-	}
+        document.write(mkCurTags());
       </script>
     </ul>
     </p>
-  <tmpl_else>
-    <h2>This package currently has no tags attached</h2>
-  </tmpl_if>
+    <form name="patch" id="patchForm" method="get">
+    <input type="hidden" name="pkg" value="<tmpl_var name='PKG_NAME'>">
+    <input type="hidden" name="navtags" value="<tmpl_var name='NAV_TAGS'>">
+    <input type="hidden" name="patch" value="">
+    <div id="curtags-buttons">
+      <script type="text/javascript">
+        document.write(mkCurTagsButtons());
+      </script>
+    </div>
+    </form>
   </div>
 
   <div style="clear: both"></div>
@@ -137,39 +324,9 @@
   <script type="text/javascript">
   	for (i = 0; i < facetsSorted.length; i++)
 	{
-		var f = facetsSorted[i];
-		document.write("<div class='editfacet' id='editfacet-"+f.name+"'>\n");
-    		document.write("\t<div class='facetbuttons'>\n");
-		document.write("\t\t<span class='button' onclick='hideFacet(\""+f.name+"\")'>[done with this]</span><br />\n");
-      		document.write("\t\t<a class='button' href='<tmpl_var name="DELURL">'>[does not apply]</a>\n");
-		document.write("\t</div>\n");
-		document.write("\t<div class='intro'>\n");
-		document.write("\t\t<p>\n");
-        	document.write("\t\t\t<b>"+f.sdesc+"</b>\n");
-		//<tmpl_if name="PPROB">(<tmpl_var name="PPROB">%)</tmpl_if>
-		document.write("\t\t</p>\n");
-		document.write("\t\t<p>"+f.ldesc+"</p>\n");
-		document.write("\t</div>\n");
-    		document.write("\t<ul>\n");
-		for (j = 0; j < facets[f.name].hasTagsSorted.length; j++)
-		{
-			var t = facets[f.name].hasTagsSorted[j];
-			document.write("\t<li>\n");
-			document.write("\t\t<b>"+t.sdesc+"</b>\n");
-			// document.write("\t\t<tmpl_if name="NPROB">(<tmpl_var name="NPROB">%)</tmpl_if>");
-			document.write("\t\t<a class='button' href='"+t.remurl+"'>[remove]</a>\n");
-			document.write("\t</li>\n");
-		}
-		for (j = 0; j < facets[f.name].newTagsSorted.length; j++)
-		{
-			var t = facets[f.name].newTagsSorted[j];
-			document.write("\t<li>\n");
-			document.write("\t\t"+t.sdesc+"\n");
-			// document.write("\t\t<tmpl_if name="NPROB">(<tmpl_var name="NPROB">%)</tmpl_if>");
-			document.write("\t\t<a class='button' href='"+t.addurl+"'>[add]</a>\n");
-			document.write("\t</li>\n");
-		}
-    		document.write("\t</ul>\n");
+		var name = facetsSorted[i].name;
+		document.write("<div class='editfacet' id='editfacet-"+name+"'>\n");
+		document.write(mkOpenFacetBox(name));
 		document.write("</div>\n");
 	}
   </script>

Modified: central-database/branches/alioth/webfrontend/main.css
==============================================================================
--- central-database/branches/alioth/webfrontend/main.css	(original)
+++ central-database/branches/alioth/webfrontend/main.css	Sat Nov 19 14:12:44 2005
@@ -37,6 +37,10 @@
 }
 
 /* Introductory text */
+#intro {
+font-size: small;
+}
+
 .intro {
 padding-bottom: 3pt;
 }



More information about the Debtags-commits mailing list