diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/components/DirectiveEditForm.scala b/rudder-web/src/main/scala/com/normation/rudder/web/components/DirectiveEditForm.scala index b7d804b22c5..1078951bb83 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/components/DirectiveEditForm.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/components/DirectiveEditForm.scala @@ -276,6 +276,7 @@ class DirectiveEditForm( & "#techniqueDescription *" #> technique.description & "#nameField" #> {piName.toForm_!} & + "#tagField *" #> tagsEditForm.cfTagsDirectiveConfiguration & "#rudderID *" #> {directive.id.value} & "#shortDescriptionField" #> piShortDescription.toForm_! & "#longDescriptionField" #> piLongDescription.toForm_! & @@ -423,6 +424,8 @@ class DirectiveEditForm( override def subContainerClassName = "col-xs-12" } + def tagsEditForm = new TagsEditForm() + def showDeprecatedVersion (version : TechniqueVersion) = { val deprecationInfo = fullActiveTechnique.techniques(version).deprecrationInfo match { case Some(_) => "(deprecated)" diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleCompliance.scala b/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleCompliance.scala index 5a29cacfede..a3226c5549b 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleCompliance.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleCompliance.scala @@ -97,12 +97,13 @@ class RuleCompliance ( private[this] val getAllNodeInfos = RudderConfig.nodeInfoService.getAll _ import RuleCompliance._ - + def tagsEditForm = new TagsEditForm() def display : NodeSeq = { ( "#ruleName" #> rule.name & "#ruleCategory" #> categoryService.shortFqdn(rootRuleCategory, rule.categoryId) & + "#tagField *" #> tagsEditForm.cfTagsRuleConfiguration & "#rudderID" #> rule.id.value & "#ruleShortDescription" #> rule.shortDescription & "#ruleLongDescription" #> rule.longDescription & diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleDisplayer.scala b/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleDisplayer.scala index 18b0b77b53b..8384e7e41f6 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleDisplayer.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleDisplayer.scala @@ -124,6 +124,17 @@ class RuleDisplayer ( , () => refreshGrid ) ) } + + def includeSubCategory = { + SHtml.ajaxCheckbox( + true + , value => OnLoad(JsRaw(s""" + include=${value}; + filterTableInclude('#grid_rules_grid_zone',filter,include); """)) & check() + , ("id","includeCheckbox") + ) + } + def viewCategories(ruleCategoryTree : RuleCategoryTree) : NodeSeq = { val actionButton = @@ -139,6 +150,7 @@ class RuleDisplayer ( {actionButton} +
{includeSubCategory}Display Rules from subcategories
{ruleCategoryTree.tree} @@ -176,15 +188,6 @@ class RuleDisplayer ( , directive ) } - def includeSubCategory = { - SHtml.ajaxCheckbox( - true - , value => OnLoad(JsRaw(s""" - include=${value}; - filterTableInclude('#grid_rules_grid_zone',filter,include); """)) & check() - , ("id","includeCheckbox") - ) - } def actionButton = { if (directive.isDefined) { @@ -200,7 +203,6 @@ class RuleDisplayer ( {actionButton} -
{includeSubCategory} Display Rules from subcategories

{ ruleGrid.rulesGridWithUpdatedInfo(None, !directive.isDefined, true, false) ++ Script(OnLoad(ruleGrid.asyncDisplayAllRules(None, true, configService.display_changes_graph().openOr(true)).applied)) @@ -212,7 +214,7 @@ class RuleDisplayer ( def display = { val columnToFilter = { - if (directive.isDefined) 2 else 1 + if (directive.isDefined) 3 else 2 } ruleCategoryTree match { diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleGrid.scala b/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleGrid.scala index 7502c1c02c9..3cfb09f7895 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleGrid.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/components/RuleGrid.scala @@ -260,8 +260,8 @@ class RuleGrid( logger.warn(fail.messageChain) (true, Some(fail.msg)) } - val onLoad = - s"""createRuleTable ( + val onLoad = s""" + createRuleTable ( "${htmlId_rulesGridId}" , ${tableData.json.toJsCmd} , ${showCheckboxColumn} @@ -275,13 +275,83 @@ class RuleGrid( ); createTooltip(); createTooltiptr(); - $$('#${htmlId_rulesGridWrapper}').css("margin","10px 0px 0px 0px"); + angular.bootstrap('#showFiltersRules', ['filters']); """
{errorProperty.getOrElse("")}
+
+
+
+
+ +
+ +
+
+
+ + = + + + + +
+
+
+ + + +
+
+
+
+ + + + + + + = + + + +
+
+
+
+
+
+
@@ -316,7 +386,7 @@ class RuleGrid( ${completeCategories.map(c => s"""$$('#${c.value}Checkbox').prop("checked",${status}); """).mkString("\n")} ${indeterminate.map(c => s"""$$('#${c.value}Checkbox').prop("indeterminate",true); """).mkString("\n")} """)) - } + } } } catch { case e:Exception => @@ -640,6 +710,8 @@ class RuleGrid( val t5 = System.currentTimeMillis TimingDebugLogger.trace(s"Rule grid: transforming into data: get rule data: callback: ${t5-t4}ms") + val tags = """[{"key":"environment","value":"production"},{"key":"customer","value":"Acme prod"}]""" + RuleLine ( line.rule.name , line.rule.id @@ -653,6 +725,7 @@ class RuleGrid( , reasons , policyMode , explanation + , tags ) } } @@ -687,6 +760,7 @@ case class RuleLine ( , reasons : Option[String] , policyMode : String , explanation : String + , tags : String ) extends JsTableLine { /* Would love to have a reflexive way to generate that map ... */ @@ -710,6 +784,7 @@ case class RuleLine ( , ( "trClass", trClass ) , ( "policyMode", policyMode ) , ( "explanation", explanation ) + , ( "tags", tags) ) base +* JsObj(optFields:_*) diff --git a/rudder-web/src/main/scala/com/normation/rudder/web/services/DisplayDirectiveTree.scala b/rudder-web/src/main/scala/com/normation/rudder/web/services/DisplayDirectiveTree.scala index 3b3637a2db7..84cea0da078 100644 --- a/rudder-web/src/main/scala/com/normation/rudder/web/services/DisplayDirectiveTree.scala +++ b/rudder-web/src/main/scala/com/normation/rudder/web/services/DisplayDirectiveTree.scala @@ -218,7 +218,7 @@ object DisplayDirectiveTree extends Loggable { } val htmlId = s"jsTree-${directive.id.value}" override val attrs = ( - ("data-jstree" -> """{ "type" : "directive" }""") :: + ("data-jstree" -> """{"type":"directive", "tags":[{"key":"environment", "value":"production"},{"key":"customer", "value":"Acme corp"}]}""") :: ( "id" -> htmlId) :: ("class" -> classes ) :: Nil @@ -231,8 +231,8 @@ object DisplayDirectiveTree extends Loggable { val tooltipId = Helpers.nextFuncName -
Configure this Directive.
-
+
Configure this Directive.
+ } else { NodeSeq.Empty } @@ -280,7 +280,7 @@ object DisplayDirectiveTree extends Loggable {
Technique version: {directive.techniqueVersion.toString}
{s"Used in ${isAssignedTo} rules" }
{ if(!directive.isEnabled)
Disable
} -
+
} @@ -292,7 +292,7 @@ object DisplayDirectiveTree extends Loggable { } } - displayCategory(directiveLib, "jstn_0").toXml + displayCategory(directiveLib, "jstn_0").toXml ++ Script(OnLoad(JsRaw("angular.bootstrap('#activeTechniquesTree_actions_zone', ['filters']);"))) } } diff --git a/rudder-web/src/main/webapp/javascript/rudder/angular/filters.js b/rudder-web/src/main/webapp/javascript/rudder/angular/filters.js new file mode 100644 index 00000000000..9e12211ca25 --- /dev/null +++ b/rudder-web/src/main/webapp/javascript/rudder/angular/filters.js @@ -0,0 +1,522 @@ +var app = angular.module('filters', ['ngSanitize']); + +app.controller('filterTagDirectiveCtrl', function ($scope, $http, $location, $timeout) { + $scope.searchStr = ""; + $scope.showFilters = false; + $scope.only = {"key":false , "value":false}; + $scope.newTag = {"key":"" , "value":""}; + $scope.tags = []; + $scope.isEmptyOrBlank = function(str){ + return (!str || 0 === str.length || /^\s*$/.test(str)); + } + $scope.clearSearch = function(){ + $scope.searchStr = ""; + clearSearchFieldTree('#activeTechniquesTree'); + $scope.searchTree('#activeTechniquesTree'); + } + $scope.resetNewTag = function(){ + $scope.newTag = {"key":"" , "value":""}; + } + $scope.modifyTag = function(index,tag){ + $scope.toggleFilter('#helpTag',true); + $scope.newTag.key = tag.key; + $scope.newTag.value = tag.value; + } + $scope.addTag = function(treeId, tag){ + var newTag = tag ? tag : $scope.newTag; + var alreadyExist = false; + for(var i=0 ; i<$scope.tags.length ; i++){ + if((newTag.key==$scope.tags[i].key)&&(newTag.value==$scope.tags[i].value)){ + alreadyExist = true; + $scope.tags[i].alreadyExist = true; + (function(i){ + $timeout(function() { + $scope.tags[i].alreadyExist = false; + }, 200); + })(i); + } + } + if(!alreadyExist){ + $scope.tags.push(newTag); + $scope.searchTree(treeId); + if(!tag){ + $scope.resetNewTag(); + $scope.updateTag(); + }else{ + $scope.updateFilter(); + } + $timeout(function() { + adjustHeight('#activeTechniquesTree'); + },0); + } + } + $scope.updateTag = function(){ + var scopeDirectiveTag = angular.element($('[ng-controller="tagsDirectiveCtrl"]')).scope(); + if(scopeDirectiveTag){ + scopeDirectiveTag.$apply(function(){ + $scope.updateFunction(scopeDirectiveTag); + }) + } + } + $scope.updateFilter = function(){ + var scopeDirectiveTag = angular.element($('[ng-controller="tagsDirectiveCtrl"]')).scope(); + $scope.updateFunction(scopeDirectiveTag); + } + $scope.updateFunction = function(scopeDirectiveTag){ + var match; + if(scopeDirectiveTag.tags.length>0){ + for(var i=0 ; i0){ + for(var i=0 ; i0){ + var ruleTags = JSON.parse(data[0]); + for(i in $scope.tags){ + containsTags = false; + for(j in ruleTags){ + if(((!$scope.only.key && !$scope.only.value) + && + ((($scope.tags[i].key == ruleTags[j].key)||($scope.tags[i].key==""))&&(($scope.tags[i].value == ruleTags[j].value)||($scope.tags[i].value==""))))||($scope.only.key && (($scope.tags[i].key == ruleTags[j].key)||($scope.tags[i].key=="")))||($scope.only.value && (($scope.tags[i].value == ruleTags[j].value)||($scope.tags[i].value==""))) + ){ + containsTags = true; + } + } + matchTags.push(containsTags) + } + if($.inArray(false, matchTags) < 0){ + return true; + } + return false; + } + return true; + } + ); + } + $scope.initFilterTable(); +}); +//======================================================================================== +//======================================================================================== +app.config(function($locationProvider) { + $locationProvider.html5Mode({ + enabled: true, + requireBase: false + }); +}) +//======================================================================================== +//======================================================================================== +// Adjust tree height +function adjustHeight(treeId){ + var tree = $(treeId); + var offsetTop = tree.offset().top + 10; + var maxHeight = 'calc(100vh - '+ offsetTop + 'px)'; + tree.css('max-height',maxHeight); +} +//======================================================================================== +//======================================================================================== +// PLUGIN JSTREE : SEARCH-TAG +$.jstree.plugins.searchtag = function (options, parent) { + var that = this; + this.bind = function () { + parent.bind.call(this); + this._data.searchtag.str = ""; + this._data.searchtag.dom = $(); + this._data.searchtag.res = []; + this._data.searchtag.opn = []; + this._data.searchtag.som = false; + this._data.searchtag.smc = false; + this._data.searchtag.hdn = []; + + this.element + .on("searchtag.jstree", $.proxy(function (e, data) { + if(this._data.searchtag.som && data.res.length) { + var m = this._model.data, i, j, p = [], k, l; + for(i = 0, j = data.res.length; i < j; i++) { + if(m[data.res[i]] && !m[data.res[i]].state.hidden) { + p.push(data.res[i]); + p = p.concat(m[data.res[i]].parents); + if(this._data.searchtag.smc) { + for (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) { + if (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) { + p.push(m[data.res[i]].children_d[k]); + } + } + } + } + } + p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root); + this._data.searchtag.hdn = this.hide_all(true); + this.show_node(p, true); + this.redraw(true); + } + }, this)) + .on("clear_search.jstree", $.proxy(function (e, data) { + if(this._data.searchtag.som && data.res.length) { + this.show_node(this._data.searchtag.hdn, true); + this.redraw(true); + } + }, this)); + }; + this.searchtag = function (str, tags, filteringTagsOptions, skip_async, show_only_matches, inside, append, show_only_matches_children) { + this.show_all(); + if((!Array.isArray(tags) || tags.length<=0)&&(str === false || $.trim(str.toString()) === "")) { + return this.clear_search(); + } + inside = this.get_node(inside); + inside = inside && inside.id ? inside.id : null; + var str = str.toString(); + var s = this.settings.search, + m = this._model.data, + f = null, + r = [], + p = [], i, j; + if(this._data.searchtag.res.length && !append) { + this.clear_search(); + } + if(show_only_matches === undefined) { + show_only_matches = s.show_only_matches; + } + if(show_only_matches_children === undefined) { + show_only_matches_children = s.show_only_matches_children; + } + if(!append) { + this._data.searchtag.str = str; + this._data.searchtag.dom = $(); + this._data.searchtag.res = []; + this._data.searchtag.opn = []; + this._data.searchtag.som = show_only_matches; + this._data.searchtag.smc = show_only_matches_children; + } + f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy }); + $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) { + var v = m[i]; + var containsTags; + var matchTags = []; + if(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && (!s.search_callback && f.search(v.text).isMatch) ) { + var directiveTags = v.data.jstree.type=="directive" ? v.data.jstree.tags : false; + if(tags.length>0){ + if(directiveTags){ + for(var j=0 ; j0; + return res; + } +}); +app.controller('tagsRuleCtrl', function ($scope, $http, $location, $timeout) { + $scope.scopeFilter; + $scope.init = function(tags){ + $scope.tags = tags; + $scope.scopeFilter = angular.element($('[ng-controller="filterTagRuleCtrl"]')).scope(); + $scope.scopeFilter.updateFilter(); + } + + $scope.toggleTag = function(tag){ + $scope.scopeFilter.$apply(function(){ + var newTag = {"key":tag.key, "value":tag.value}; + $scope.scopeFilter.addTag(newTag); + }); + } + + $scope.matchTag = function(tag){ + var res = tag.match && $scope.scopeFilter.tags.length>0; + return res; + } +}); +app.config(function($locationProvider) { + $locationProvider.html5Mode({ + enabled: true, + requireBase: false + }); +}); \ No newline at end of file diff --git a/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js b/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js index 0a4b3dc4698..5a61b0eda92 100644 --- a/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js +++ b/rudder-web/src/main/webapp/javascript/rudder/rudder-datatable.js @@ -244,7 +244,15 @@ function createRuleTable(gridId, data, needCheckbox, needActions, needCompliance $(nTd).prepend(elem); } }; - + var tags = { + "mDataProp" : "tags" + , "sClass" : "never" + , "sTitle" : "Tags" + , "fnCreatedCell" : function (nTd, sData, oData, iRow, iCol) { + $(nTd).empty(); + $(nTd).text(oData.tags); + } + }; // Name of the rule // First mandatory row, so do general thing on the row ( line css, description tooltip ...) var name = { @@ -385,6 +393,7 @@ function createRuleTable(gridId, data, needCheckbox, needActions, needCompliance // Choose which columns should be included var columns = []; + columns.push(tags); if (needCheckbox) { columns.push(checkbox); } @@ -408,8 +417,16 @@ function createRuleTable(gridId, data, needCheckbox, needActions, needCompliance "sZeroRecords": "No matching rules!" , "sSearch": "" } + , "columnDefs": [{ + "targets": [ 0 ] + , "visible": false + , "searchable": true + }] , "fnDrawCallback": function( oSettings ) { $('.rudder-label').bsTooltip(); + $('#updateRuleTable').on('click',function(){ + refresh(); + }) var rows = this._('tr', {"page":"current"}); $.each(rows, function(index,row) { var id = "Changes-"+row.id; @@ -431,9 +448,8 @@ function createRuleTable(gridId, data, needCheckbox, needActions, needCompliance }) } , "aaSorting": [[ 0, "asc" ] , [ sortingDefault, "asc" ]] - , "sDom": '<"dataTables_wrapper_top newFilter"f<"dataTables_refresh">>rt<"dataTables_wrapper_bottom"lip>' + , "sDom": 'rt<"dataTables_wrapper_bottom"lip>' } - var table = createTable(gridId,data,columns, params, contextPath, refresh, "rules", isPopup); table.search("").columns().search(""); if(isPopup){ @@ -523,6 +539,7 @@ function createRuleComplianceTable(gridId, data, contextPath, refresh) { , "oLanguage": { "sSearch": "" } + , "columnDefs": [{ "visible": false, "targets": 0 }] , "aaSorting": [[ 0, "asc" ]] , "fnDrawCallback" : function( oSettings ) { createInnerTable(this, createDirectiveTable(false, true, contextPath), contextPath, "rule"); @@ -1671,7 +1688,6 @@ function createTable(gridId,data,columns, customParams, contextPath, refresh, st $('#filterLogs .pickStartInput, #filterLogs .pickEndInput').datetimepicker({dateFormat:'yy-mm-dd', timeFormat: 'HH:mm:ss', timeInput: true}); $('#filterLogsButton').click(pickEventLogsInInterval); } - return table; } diff --git a/rudder-web/src/main/webapp/javascript/rudder/rudder.js b/rudder-web/src/main/webapp/javascript/rudder/rudder.js index fd8c2fbb8e9..fac7b867884 100644 --- a/rudder-web/src/main/webapp/javascript/rudder/rudder.js +++ b/rudder-web/src/main/webapp/javascript/rudder/rudder.js @@ -50,6 +50,8 @@ var bootstrapAffix = $.fn.affix.noConflict(); var bootstrapModal = $.fn.modal.noConflict(); $.fn.bsModal = bootstrapModal; $.fn.bsTooltip = bootstrapTooltip; +$.fn.bsPopover = bootstrapPopover; +$.fn.bsTab = bootstrapTab; /** * Instanciate the tooltip * For each element having the "tooltipable" class, when hovering it will look for it's @@ -466,12 +468,12 @@ var searchTree = function(inputId, treeId) { enableSubtree($(".jstree-search")); return false; } + var clearSearchFieldTree = function(inputId, treeId) { $(inputId).val(''); $(treeId).jstree('clear_search'); return false; } - var twoDigitsFormator = d3.format("02d"); /* Facility to format a number on two digits */ diff --git a/rudder-web/src/main/webapp/javascript/rudder/tree.js b/rudder-web/src/main/webapp/javascript/rudder/tree.js index 82c810818dc..c6c636dbec8 100644 --- a/rudder-web/src/main/webapp/javascript/rudder/tree.js +++ b/rudder-web/src/main/webapp/javascript/rudder/tree.js @@ -1,5 +1,3 @@ - - /* * Reference Technique library tree */ @@ -114,7 +112,7 @@ var buildActiveTechniqueTree = function(id, foreignTreeId, authorized, appContex "show_only_matches": true }, "plugins" : [ "types", "dnd", "search" ] - }) + }) } /* @@ -362,16 +360,15 @@ var buildTechniqueDependencyTree = function(id, initially_select, appContext) { }) } - - var buildDirectiveTree = function(id, initially_select, appContext, select_limit) { + var select_multiple_modifier = "on" if (select_limit > 0) { select_multiple_modifier = "ctrl" } - var tree = $(id).bind("loaded.jstree", function (event, data) { - data.instance.open_all(); - $(id+' .rudder-label').bsTooltip(); + var tree = $(id).on("loaded.jstree", function (event, data) { + data.instance.open_all(); + $(id+' .rudder-label').bsTooltip(); }).jstree({ "core" : { "animation" : 300, @@ -418,13 +415,12 @@ var buildDirectiveTree = function(id, initially_select, appContext, select_limit "theme" : "rudder", "url" : appContext+"/javascript/jstree/themes/rudder/style.css" }, - "plugins" : [ "themes", "html_data", "types", "search"] + "plugins" : [ "themes", "html_data", "types", "search", "searchtag"] }); tree.jstree().select_node(initially_select) } - /* * Directive management */ @@ -462,7 +458,6 @@ var buildChangesTree = function(id,appContext) { }, "plugins" : [ "types" ] }) - } /** @@ -486,4 +481,4 @@ var correctNode = function(elem) { _results.push(correctNode($(child).children("ul:first"))); } return _results; -}; +}; \ No newline at end of file diff --git a/rudder-web/src/main/webapp/secure/configurationManager/directiveManagement.html b/rudder-web/src/main/webapp/secure/configurationManager/directiveManagement.html index 3b6f3d437f6..9b0d007969e 100644 --- a/rudder-web/src/main/webapp/secure/configurationManager/directiveManagement.html +++ b/rudder-web/src/main/webapp/secure/configurationManager/directiveManagement.html @@ -1,53 +1,66 @@ - -Rudder - Directives Management - - - + Rudder - Directives Management + + + +
Directive Library
-
-
+
+
@@ -55,9 +68,9 @@
- +
- @@ -68,10 +81,64 @@
+
+
+
+
+
+ +
+
+
+ +
+ + = + + + + +
+
+
+ All + / + Filter keys only + / + Filter values only + +
+
+
+ +
+
+
+
+
- + +
-
diff --git a/rudder-web/src/main/webapp/secure/configurationManager/ruleManagement.html b/rudder-web/src/main/webapp/secure/configurationManager/ruleManagement.html index fe4a99f5621..f760172295a 100644 --- a/rudder-web/src/main/webapp/secure/configurationManager/ruleManagement.html +++ b/rudder-web/src/main/webapp/secure/configurationManager/ruleManagement.html @@ -3,6 +3,9 @@ Rudder - Rules Management + + +
diff --git a/rudder-web/src/main/webapp/style/rudder/rudder-menu.css b/rudder-web/src/main/webapp/style/rudder/rudder-menu.css index 276b2e3e7ae..88ab10e79e6 100644 --- a/rudder-web/src/main/webapp/style/rudder/rudder-menu.css +++ b/rudder-web/src/main/webapp/style/rudder/rudder-menu.css @@ -358,7 +358,7 @@ a.sidebar-toggle{ .rudder_col { background-color: rgb(236, 240, 245); - padding: 15px 15px 5px; + padding: 15px 15px 10px; } .content-wrapper { height: auto; @@ -837,12 +837,25 @@ a.sidebar-toggle{ opacity:1; } /* RULE PAGE */ +#includeSubCategory{ + margin-top: 10px; + padding: 0 4px; +} +#includeSubCategory span{ + margin-left:10px; +} .tw-bs form hr,form .tw-bs hr{ width:100%; } #submitSearch #SubmitSearch{ margin-left: 7px; } +label.rule-info{ + margin-bottom:0; +} +label.rule-info + div{ + color:#555; +} .fake-form-control{ float: left; opacity: 1; @@ -893,7 +906,7 @@ a.sidebar-toggle{ border-right: 0; } .skin-yellow.sidebar-collapse .directive-footer { - width: 63.2%; + width: 63.2%;style="margin-top: 10px;padding: 0 4px;" } /* --- CHANGE REQUEST PAGE --- */ @@ -987,15 +1000,16 @@ a.sidebar-toggle{ border-left: 15px solid #ECF0F5; max-height:88vh; } -#directiveDetails,.directiveTree{ +#directiveDetails{ overflow-y:auto; overflow-x:hidden; - padding-bottom: 20px; } .directiveTree { padding-left: 10px; padding-right: 10px; - max-height: calc(100vh - 70px); + padding: 0 10px; + overflow-y:auto; + overflow-x:hidden; } .ui-widget.ui-tooltip h4{ margin-bottom: 10px; diff --git a/rudder-web/src/main/webapp/style/rudder/rudder-tags.css b/rudder-web/src/main/webapp/style/rudder/rudder-tags.css new file mode 100644 index 00000000000..42c77822a05 --- /dev/null +++ b/rudder-web/src/main/webapp/style/rudder/rudder-tags.css @@ -0,0 +1,285 @@ +.tab-filter .input-group label { + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + background-color: #f4f4f4; + padding: 2px 8px 0px 8px; + font-size: 16px; +} +.tw-bs .btn.updateTable:focus{ + background-color: #f4f4f4; + border-color:#ccc; + color:#3694d1; +} +.tw-bs .btn.updateTable:focus:hover{ + color:#3694d1; + background-color: #e6e6e6; + border-color: #adadad; +} +.tw-bs .btn-success[disabled]:hover{ + background-color: #9bc832; + border-color: #8fb92a; +} +.panel-footer .tags-container{ + padding: 5px 1px 2px 1px; + border-top: 1px solid #ddd; +} +.in + .panel-footer .tags-container{ + padding: 0 10px 4px 10px; + border-top:none; +} +#activeTechniquesTree{ + overflow-y: auto; + overflow-x: hidden; + margin: 0 -10px; + padding: 0 15px; + width: calc(100% + 20px); +} +.filterTag .panel-default{ + margin-top:10px; + box-shadow:none !important; +} +#showFiltersDirective .filterTag .panel-group { + margin-bottom: 10px; +} +#showFiltersRules .filterTag .panel-group { + margin-bottom: 0; +} +.filterTag .panel-default .panel-body { + padding: 5px 10px 0 10px; +} +.filterTag .panel-default .panel-heading{ + background-color:#f5f5f5; + border-color: #ddd; + margin:0; + padding:0; +} +.filterTag .panel-default .panel-heading a{ + padding: 6px 15px; + display: block; + font-size:12px; +} +.filterTag .panel-default .panel-heading a > span.pull-right{ + transition-duration:.2s; + transform:rotate(-90deg); +} +.filterTag .panel-default .panel-heading a > span.pull-right.in{ + transform:rotate(0deg); +} +.filterTag .panel-default .panel-heading a > .fa{ + font-size: 16px; + position: relative; + top: 1px; + margin-left: 5px; + color: #999; + cursor:help; +} +.filterTag .panel-default .panel-heading a > .fa:hover{ + color: #555; +} +.filterTag .panel-default .panel-footer { + padding: 0; + background-color:#fff; + border-top: none; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.form-control.tags-search{ + width:150px; + display:inline-block; + float:right; +} +.input-group-addon.addon-json{ + border-left: none; + border-right: none; + background: #f4f4f4; + font-weight: bold; + cursor:default; +} +.rudder-tag{ + background-color: #f4f4f4; + padding: 4px 24px 3px 10px; + border-radius: 20px; + border: 1px solid #ddd; + position: relative; + margin: 0 2px 4px 2px; + cursor:pointer; + font-size:12px; + display: inline-block; +} +.rudder-tag.tag-search{ + background-color: #ffffff; + border: 1px solid #ababab; +} +.rudder-tag.already-exist{ + -webkit-animation: exist .2s backwards; + -moz-animation: exist .2s backwards; + -o-animation: exist .2s backwards; + animation: exist .2s backwards; +} +.rudder-tag .tag-separator{ + padding: 3px; + font-size: 12px; + line-height: 0; + color: #333; +} +.rudder-tag .fa-times{ + position: absolute; + right: 7px; + top: 6px; + opacity: 0.3; + cursor:pointer; +} +.rudder-tag .fa-times:hover{ + opacity: 1; +} +.rudder-tag.simple{ + padding: 3px 10px; + cursor:pointer; + transition-duration:.2s; +} +.rudder-tag.simple:hover{ + background-color:#e3e3e3; +} +.rudder-tag.simple.match{ + background-color: #3694d1; + border-color: #348cc5; + color: #fff; +} +.rudder-tag.simple.match:hover{ + background-color: #136ca7; + border-color: #0e5e92; +} +.rudder-tag.onlyKey .tag-value,.rudder-tag.onlyValue .tag-key{ + opacity:.5; +} +.only-tags a,.only-tags a:focus{ + display:inline-block; + color: #999; + padding: 2px; + text-align:center; + font-size: 12px; +} +.btn-group.only-tags{ + margin-left:15px; +} +.only-tags > .btn.active{ + background-color: #3694d1 !important; + color: #fff !important; + border-color:#2173a9 !important; +} +.only-tags a.all{ + width:20px; + text-decoration:none !important; +} +.only-tags a.key{ + width:95px; + text-decoration:none !important; +} +.only-tags a.value{ + width:105px; + text-decoration:none !important; +} +.only-tags a.active{ + color: #555; + font-weight:bold; +} +.only-tags a:hover{ + color: #333; +} +.only-tags > .btn-xs{ + margin-bottom: 5px; + position: relative; + left: -1px; + margin-left: 5px; +} +.only-tags > .btn-xs > .fa{ + margin-left: 5px; +} +.rudder-tag .fa-asterisk{ + font-size: 8px; + top: -1px; + position: relative; +} +#activeTechniquesTree_alert .alert{ + margin-bottom:10px; +} +#activeTechniquesTree_alert .alert > i{ + margin-right: 10px; +} +hr.separator-filter-tree{ + width: calc(100% + 20px); + margin: 0 -10px; +} +.nav-tabs-filter + .tab-content > .tab-pane{ + padding:4px 2px 0px 2px; + border-left:1px solid #ddd; + border-right:1px solid #ddd; +} +.nav-tabs-filter + .tab-content > .tab-pane.active.no-padding-top{ + padding:0px 2px; +} +.nav-tabs-filter + .tab-content > .tab-filter{ + padding:5px; +} +.nav-tabs-filter + .tab-content > .tab-filter.no-padding-bottom{ + padding-bottom:0; +} +.tw-bs .nav-tabs-filter > li > a.toggleTabFilter{ + background-color: #f4f4f4 !important; + border:1px solid #cccccc !important; + color:#555 !important; + cursor:pointer !important; + padding: 4px 25px 4px 10px; + position: relative; + margin-right: 5px; +} +.tw-bs .nav-tabs-filter > li > a.toggleTabFilter.updateTable{ + background-color: #3694d1 !important; + color: #fff !important; + border: 1px solid #2173a9 !important; + border-bottom:none !important; +} +.tw-bs .nav-tabs-filter > li > a.toggleTabFilter.updateTable:active{ + box-shadow: inset 0 0 4px 1px #286090; +} +.tw-bs .nav-tabs-filter > li > a.toggleTabFilter.updateTable:hover{ + background-color: #337ab7 !important; + border-color: #2e6da4 !important; + color: #fff !important; +} +.tw-bs .nav-tabs-filter > li:last-child{ + margin-left: 10px; +} +.tw-bs .nav-tabs > li:last-child > a.toggleTabFilter{ + padding: 4px 10px; +} +.tw-bs .nav-tabs > li > a.toggleTabFilter:hover{ + color:#333 !important; +} +.tw-bs .nav-tabs > li > a.toggleTabFilter >span.fa{ + position: absolute; + right: 8px; + top: 10px; + transition-duration: .2s; + font-size: 12px; +} +@-webkit-keyframes exist { + 0% {box-shadow: 0 0 0 #c2c2c2;} + 50% {box-shadow: 0 0 13px #c2c2c2;} + 100% {box-shadow: 0 0 0 #c2c2c2;} +} +@-moz-keyframes exist { + 0% {box-shadow: 0 0 0 #c2c2c2;} + 50% {box-shadow: 0 0 13px #c2c2c2;} + 100% {box-shadow: 0 0 0 #c2c2c2;} +} +@-o-keyframes exist { + 0% {box-shadow: 0 0 0 #c2c2c2;} + 50% {box-shadow: 0 0 13px #c2c2c2;} + 100% {box-shadow: 0 0 0 #c2c2c2;} +} +@keyframes exist { + 0% {box-shadow: 0 0 0 #c2c2c2;} + 50% {box-shadow: 0 0 13px #c2c2c2;} + 100% {box-shadow: 0 0 0 #c2c2c2;} +} \ No newline at end of file diff --git a/rudder-web/src/main/webapp/style/rudder/rudder.css b/rudder-web/src/main/webapp/style/rudder/rudder.css index d3f8eef380e..a0db14df600 100644 --- a/rudder-web/src/main/webapp/style/rudder/rudder.css +++ b/rudder-web/src/main/webapp/style/rudder/rudder.css @@ -635,10 +635,6 @@ input.pickStartInput, input.pickEndInput { padding: 3px 0px 3px 0px; } -.dataTables_wrapper { - margin-top: 10px; -} - .dataTables_wrapper_top { padding: 6px; overflow: hidden; diff --git a/rudder-web/src/main/webapp/templates-hidden/components/ComponentDirectiveEditForm.html b/rudder-web/src/main/webapp/templates-hidden/components/ComponentDirectiveEditForm.html index 8875edf5428..11f2927dff5 100644 --- a/rudder-web/src/main/webapp/templates-hidden/components/ComponentDirectiveEditForm.html +++ b/rudder-web/src/main/webapp/templates-hidden/components/ComponentDirectiveEditForm.html @@ -27,6 +27,7 @@ +
Directive
@@ -61,6 +62,9 @@

Technique version deprecated

Here comes the name field
+
+ Here comes the tag field +
Here comes the shortDescription field
diff --git a/rudder-web/src/main/webapp/templates-hidden/components/ComponentRuleEditForm.html b/rudder-web/src/main/webapp/templates-hidden/components/ComponentRuleEditForm.html index 52f478c189e..b206fa86200 100644 --- a/rudder-web/src/main/webapp/templates-hidden/components/ComponentRuleEditForm.html +++ b/rudder-web/src/main/webapp/templates-hidden/components/ComponentRuleEditForm.html @@ -86,43 +86,36 @@
- +
-
- -
+
- +
-
- -
+
+
+ Here comes the tag field +
- +
-
- -
+
- +
-
- -
+
- +
-
- Here comes the rudder ID -
+ Here comes the rudder ID