From 209cd33e4780d45a5085a3538720b7c2ed92357b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Membr=C3=A9?= Date: Tue, 21 Jul 2015 10:38:32 +0200 Subject: [PATCH] Fixes #7016: Adapt Rudder to Scalla 2.11 and Lift 2.6 --- rudder-core/pom.xml | 6 +- rudder-web/pom.xml | 4 +- .../rudder/web/comet/AsyncDeployment.scala | 21 ++- .../rudder/web/components/NodeGroupForm.scala | 10 +- .../web/components/SearchNodeComponent.scala | 169 ++++++++++-------- .../popup/CreateCategoryOrGroupPopup.scala | 14 +- .../popup/CreateCloneGroupPopup.scala | 12 +- .../popup/ExpectedPolicyPopup.scala | 2 +- .../popup/ModificationValidationPopup.scala | 6 +- .../rudder/web/services/DisplayNode.scala | 31 +--- .../rudder/web/services/NodeGrid.scala | 79 ++++---- .../rudder/web/services/ReportDisplayer.scala | 2 +- .../rudder/web/services/SrvGrid.scala | 5 - .../ChangeRequestManagement.scala | 3 +- .../rudder/web/snippet/node/AcceptNode.scala | 108 ++++++----- .../rudder/web/snippet/node/Groups.scala | 2 +- .../web/snippet/node/PendingHistoryGrid.scala | 99 +++++----- .../main/webapp/javascript/rudder/rudder.js | 22 +++ .../directiveManagement.html | 10 +- rudder-web/src/main/webapp/secure/index.html | 18 +- .../webapp/secure/nodeManager/groups.html | 14 +- .../main/webapp/secure/nodeManager/index.html | 2 +- .../secure/nodeManager/manageNewNode.html | 31 ++-- .../main/webapp/secure/nodeManager/nodes.html | 4 +- .../secure/nodeManager/searchNodes.html | 11 +- .../Popup/ModificationValidationPopup.html | 8 +- .../Popup/accept_new_server.html | 18 +- .../Popup/createCategoryOrGroup.html | 18 +- .../Popup/createCloneGroupPopup.html | 14 +- .../Popup/expected_policy_popup.html | 6 +- .../Popup/refuse_new_server.html | 19 +- .../templates-hidden/common-layout.html | 75 +++----- .../ComponentDirectiveEditForm.html | 21 +-- .../components/NodeGroupForm.html | 40 ++--- .../templates-hidden/node_logs_tabs.html | 3 +- .../pending_history_grid.html | 23 +-- .../webapp/templates-hidden/reports_grid.html | 8 +- .../templates-hidden/reports_server.html | 18 +- .../server/server_details.html | 45 ++--- .../templates-hidden/server_details_tabs.html | 10 -- .../webapp/templates-hidden/server_grid.html | 31 ++-- .../webapp/templates-hidden/srv_grid.html | 12 +- 42 files changed, 488 insertions(+), 566 deletions(-) delete mode 100644 rudder-web/src/main/webapp/templates-hidden/server_details_tabs.html diff --git a/rudder-core/pom.xml b/rudder-core/pom.xml index 56a7e3baf2e..24da581ac6d 100644 --- a/rudder-core/pom.xml +++ b/rudder-core/pom.xml @@ -108,18 +108,18 @@ along with this program. If not, see . com.typesafe.slick - slick_2.10 + slick_${scala-binary-version} 2.1.0 com.github.tminglei - slick-pg_2.10 + slick-pg_${scala-binary-version} 0.6.3 com.github.tminglei - slick-pg_joda-time_2.10 + slick-pg_joda-time_${scala-binary-version} 0.6.3 diff --git a/rudder-web/pom.xml b/rudder-web/pom.xml index ec7993a9562..4a963a567ae 100644 --- a/rudder-web/pom.xml +++ b/rudder-web/pom.xml @@ -87,8 +87,8 @@ along with this program. If not, see . net.liftmodules - widgets_2.5_${scala-binary-version} - 1.3 + widgets_2.6_${scala-binary-version} + 1.4-SNAPSHOT diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/comet/AsyncDeployment.scala b/rudder-web/src/main/scala/com/normation/rudder/web/comet/AsyncDeployment.scala index 24a66e70b5f..37b25b1dbf6 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/comet/AsyncDeployment.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/comet/AsyncDeployment.scala @@ -83,7 +83,6 @@ class AsyncDeployment extends CometActor with CometListener with Loggable { private[this] val eventList = RudderConfig.eventListDisplayer private[this] val uuidGen = RudderConfig.stringUuidGenerator - //current states of the deployment private[this] var deploymentStatus = DeploymentStatus(NoStatus, IdleDeployer) @@ -101,7 +100,6 @@ class AsyncDeployment extends CometActor with CometListener with Loggable { new RenderOut(layout) } - val deployementErrorMessage = """(.*)!errormessage!(.*)""".r private[this] def statusIcon : NodeSeq = { @@ -122,7 +120,6 @@ class AsyncDeployment extends CometActor with CometListener with Loggable { } - private[this] def lastStatus = { deploymentStatus.current match { @@ -170,14 +167,16 @@ class AsyncDeployment extends CometActor with CometListener with Loggable { private[this] def layout = { - + + + } private[this] def errorPopup = { diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/components/NodeGroupForm.scala b/rudder-web/src/main/scala/com/normation/rudder/web/components/NodeGroupForm.scala index 36feac11fbd..c587d0a89ae 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/components/NodeGroupForm.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/components/NodeGroupForm.scala @@ -75,8 +75,8 @@ object NodeGroupForm { xml } - val staticInit = chooseXml("staticInit") - val staticBody = chooseXml("staticBody") + val staticInit = chooseXml("staticinit") + val staticBody = chooseXml("staticbody") val body = chooseXml("body") private val saveButtonId = "groupSaveButtonId" @@ -177,13 +177,13 @@ class NodeGroupForm( ) bind("group", html, - "pendingChangeRequest" -> PendingChangeRequestDisplayer.checkByGroup(pendingChangeRequestXml,nodeGroup.id, workflowEnabled), + "pendingchangerequest" -> PendingChangeRequestDisplayer.checkByGroup(pendingChangeRequestXml,nodeGroup.id, workflowEnabled), "name" -> groupName.toForm_!, - "rudderID" ->
Rudder ID: {nodeGroup.id.value}
, + "rudderid" ->
Rudder ID: {nodeGroup.id.value}
, "description" -> groupDescription.toForm_!, "container" -> groupContainer.toForm_!, "static" -> groupStatic.toForm_!, - "showGroup" -> (searchNodeComponent.is match { + "showgroup" -> (searchNodeComponent.is match { case Full(req) => req.buildQuery case eb:EmptyBox => Error when retrieving the request, please try again }), diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/components/SearchNodeComponent.scala b/rudder-web/src/main/scala/com/normation/rudder/web/components/SearchNodeComponent.scala index c50562f0bd9..7ae76734850 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/components/SearchNodeComponent.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/components/SearchNodeComponent.scala @@ -63,6 +63,7 @@ import com.normation.rudder.domain.queries.OstypeComparator import net.liftweb.util.ToJsCmd import bootstrap.liftweb.RudderConfig import com.normation.rudder.domain.RudderLDAPConstants.A_NODE_PROPERTY +import scala.collection.mutable.{Map => MutMap} /** * The Search Nodes component @@ -81,7 +82,7 @@ class SearchNodeComponent( , onSearchCallback : (Boolean, Option[Query]) => JsCmd = {(_, _) => Noop } // this callback is used when a research is done and the state of the Search button changes , saveButtonId : String = "" // the id of the save button, that gets disabled when one change the form , groupPage : Boolean -)extends DispatchSnippet with Loggable { +) extends DispatchSnippet with Loggable { import SearchNodeComponent._ //our local copy of things we work on @@ -101,7 +102,18 @@ class SearchNodeComponent( case Full(n) => n } - private[this] def searchNodes = chooseTemplate("query","SearchNodes",serverPortletTemplateFile) + private[this] def searchNodes = chooseTemplate("query","searchnodes",serverPortletTemplateFile) + private[this] def queryline = { + + + + + + + + + + } private[this] def content = chooseTemplate("content","query",searchNodes) @@ -123,7 +135,6 @@ class SearchNodeComponent( var dispatch : DispatchIt = { case "showQuery" => { _ => buildQuery } - case "head" => { _ => head() } } var initUpdate = true // this is true when we arrive on the page, or when we've done an search @@ -132,16 +143,7 @@ class SearchNodeComponent( //activate the global save button var searchFormHasError = false - val errors = Buffer[Box[String]]() - - def head() : NodeSeq = { - - { - srvGrid.head - } - - } - + val errors = MutMap[CriterionLine,String]() def buildQuery : NodeSeq = { @@ -157,17 +159,25 @@ class SearchNodeComponent( lines.insert(i+1, lines(i).copy(value = "")) } else { //defaults values - lines.insert(i+1, CriterionLine(ditQueryData.criteriaMap(OC_NODE),ditQueryData.criteriaMap(OC_NODE).criteria(0),ditQueryData.criteriaMap(OC_NODE).criteria(0).cType.comparators(0))) + lines.insert(i+1, defaultLine) } - query = Some(Query(rType, composition, lines.toSeq)) + query = Some(Query(rType, composition, lines.to[Seq])) initUpdate = false ajaxCriteriaRefresh } def removeLine(i:Int) : JsCmd ={ if(lines.size > i) { + + val line = lines(i) lines.remove(i) - query = Some(Query(rType, composition, lines.toSeq)) + // Remove error notifications if there is no more occurrences of the line + // Or new lines with that will always have th error message (ie An empty hostname) + if ( ! lines.contains(line)) { + errors remove line + } + + query = Some(Query(rType, composition, lines.to[Seq])) } initUpdate = false ajaxCriteriaRefresh @@ -176,16 +186,15 @@ class SearchNodeComponent( def processForm() : JsCmd = { //filter on non validate values errors.clear() - lines.zipWithIndex.foreach { case (CriterionLine(ot,a,c,v),i) => - if(errors.size < i+1) errors.append(Empty) + lines.zipWithIndex.foreach { case (cl@CriterionLine(_,a,c,v),i) => a.cType.validate(v,c.id) match { - case Failure(m,_,_) => errors(i) = Full(m) - case _ => errors(i) = Empty + case Failure(m,_,_) => errors put (cl,m) + case _ => } } - val newQuery = Query(rType, composition, lines.toSeq) + val newQuery = Query(rType, composition, lines.to[Seq]) query = Some(newQuery) - if(errors.filter(_.isDefined).size == 0) { + if(errors.size == 0) { // ********* EXECUTE QUERY *********** srvList = queryProcessor.process(newQuery) initUpdate = true @@ -202,10 +211,38 @@ class SearchNodeComponent( * Refresh the query parameter part */ def ajaxCriteriaRefresh : JsCmd = { - SetHtml("SearchForm", displayQuery(content))& activateButtonOnChange & JsRaw("correctButtons();") + lines.clear() + SetHtml("SearchForm", displayQuery(content))& activateButtonOnChange & JsRaw("correctButtons();") } + def displayQueryLine(cl : CriterionLine, index:Int, addRemove:Boolean) : NodeSeq = { + + lines.append(cl) + + val initJs = cl.attribute.cType.initForm("v_"+index) + val inputAttributes = ("id","v_"+index) :: ("class", "queryInputValue") :: {if (cl.comparator.hasValue) Nil else ("disabled", "disabled") :: Nil } + val input = cl.attribute.cType.toForm(cl.value, (x => lines(index) = lines(index).copy(value=x)), inputAttributes:_*) + ( ".removeLine *" #> { + if(addRemove) + SHtml.ajaxSubmit("-", () => removeLine(index), ("class", "removeLineButton")) + else + NodeSeq.Empty + } & + ".addLine *" #> SHtml.ajaxSubmit("+", () => addLine(index), ("class", "removeLineButton")) & + ".objectType *" #> objectTypeSelect(cl.objectType,lines,index) & + ".attributeName *" #> attributeNameSelect(cl.objectType,cl.attribute,lines,index) & + ".comparator *" #> comparatorSelect(cl.objectType,cl.attribute,cl.comparator,lines,index) & + ".inputValue *" #> input & + ".error" #> { errors.get(cl) match { + case Some(m) => {m} + case _ => NodeSeq.Empty + }} + + ).apply { queryline } ++ Script(OnLoad(initJs)) + + } + /** * Display the query part * Caution, we pass an html different at the init part (whole content:query) or at update (update:query) @@ -213,61 +250,45 @@ class SearchNodeComponent( */ def displayQuery(html: NodeSeq) = { val Query(otName,comp, criteria) = query.get - bind("query", html, - "typeQuery" -> , - "composition" -> SHtml.radio(Seq("AND", "OR"), Full(if(comp == Or) "OR" else "AND"), {value:String => - composition = CriterionComposition.parse(value).getOrElse(And) //default to AND on unknown composition string - }, ("class", "radio")).flatMap(e => ), - "lines" -> {(ns: NodeSeq) => - /* - * General remark : - * - bind parameter of closure to lines (so that they actually get the current value of the line when evaluated) - * - bind parameter out of closure to ot/a/c/v so that they have the current value (and not a past one) - */ - - { - criteria.zipWithIndex.flatMap { case (CriterionLine(ot,a,c,v),i) => - - for(j <- lines.size to i) { - lines.append(defaultLine) - } - for(j <- errors.size to i) { - errors.append(Empty) - } - bind("line",ns, - "removeLine" -> { - if(criteria.size <= 1) - NodeSeq.Empty + val checkBox = { + SHtml.checkbox( + rType==NodeAndPolicyServerReturnType + , { value:Boolean => + if (value) + rType = NodeAndPolicyServerReturnType else - SHtml.ajaxSubmit("-", () => removeLine(i), ("class", "removeLineButton")) - }, - "addline" -> - SHtml.ajaxSubmit("+", () => addLine(i), ("class", "removeLineButton")), - "objectType" -> objectTypeSelect(ot,lines,i), - "attributeName" -> attributeNameSelect(ot,a,lines,i), - "comparator" -> comparatorSelect(ot,a,c,lines,i), - "inputValue" -> { - var form = a.cType.toForm(v, (x => lines(i) = lines(i).copy(value=x)), ("id","v_"+i), ("class", "queryInputValue")) - if(!c.hasValue) form = form % Attribute("disabled",Seq(Text("disabled")),Null) - form - } , - "error" -> { errors(i) match { - case Full(m) => {m} - case _ => NodeSeq.Empty - }} - ) - }:NodeSeq} ++ { if(criteria.size > 0) { + rType = NodeReturnType + } + , ("id", "typeQuery") + , ( "class", "compositionCheckbox") + ) + } + + val radio = { + SHtml.radio( + Seq("AND", "OR") + , Full(if(comp == Or) "OR" else "AND") + , {value:String => composition = CriterionComposition.parse(value).getOrElse(And)} //default to AND on unknown composition string + , ("class", "radio") + ).flatMap(radio => + + ) + } + + ( "#typeQuery" #> checkBox & + "#composition" #> radio & + "#submitSearch * " #> SHtml.ajaxSubmit("Search", processForm, ("id" -> "SubmitSearch"), ("class" -> "submitButton")) & + "#query_lines *" #> criteria.zipWithIndex.flatMap { case (cl,i) => displayQueryLine(cl,i, criteria.size > 1)} + ).apply(html + /*}:NodeSeq} ++ { if(criteria.size > 0) { //add a @@ -30,6 +30,10 @@ + + + + @@ -40,54 +44,19 @@ - - - - + + - - - - - - + @@ -110,23 +79,23 @@ - +