RANGER-1014 : Show allow/deny policy items info on Reports page Signed-off-by: Velmurugan Periasamy <[email protected]>
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/759f52e3 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/759f52e3 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/759f52e3 Branch: refs/heads/master Commit: 759f52e3ea0fec9b1c6374714e46a8724f378968 Parents: 9a9f7cd Author: Mehul Parikh <[email protected]> Authored: Wed Jun 1 17:00:32 2016 +0530 Committer: Velmurugan Periasamy <[email protected]> Committed: Tue Jun 7 15:56:21 2016 -0400 ---------------------------------------------------------------------- .../scripts/views/common/CustomSubgrid.js | 195 +++++++++ .../scripts/views/reports/UserAccessLayout.js | 408 ++++++++++++------- security-admin/src/main/webapp/styles/xa.css | 58 ++- 3 files changed, 512 insertions(+), 149 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/759f52e3/security-admin/src/main/webapp/scripts/views/common/CustomSubgrid.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/common/CustomSubgrid.js b/security-admin/src/main/webapp/scripts/views/common/CustomSubgrid.js new file mode 100644 index 0000000..0c7e52a --- /dev/null +++ b/security-admin/src/main/webapp/scripts/views/common/CustomSubgrid.js @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +define(function(require){ + require('backgrid'); +/* + SubgridCustomRow is a simple container view that takes a grid instance and renders a + grid within the specific column. + @extends Backbone.View + */ + var SubgridCustomRow = Backgrid.SubgridCustomRow = Backbone.View.extend({ + + tagName: "tr", + + className: "backgrid-subgrid-custom-row", + + submodel: Backbone.Model.extend({}), + + /** + * Initializes a row view instance. + * @param {Object} options + * @param {Backbone.Collection.<Backgrid.Column>|Array.<Backgrid.Column>|Array.<Object>} options.columns Column metadata. + * @param {Backbone.Model} options.model The model instance to render. + * @throws {TypeError} If options.columns or options.model is undefined. + */ + //params: options.columnName, options.labelName , options.columnCollectionName + //define model.attributes.<columnName>Collection eg. model.attributes.colnameCollection + initialize: function (options) { + var thisView = this; + var GridColumnView = Backbone.View.extend({ tagName: "td" }); + var SubCollection = Backbone.Collection.extend({ model: this.submodel }); + this.gridColumnView = new GridColumnView({}); + this.sideColumnView = new GridColumnView({}); + this.el.id = this.model.get("id"); + // requireOptions(options, ["columns", "model"]); + this.columns = options.columns; + var subcolumns = this.subcolumns = options.model.get("subcolumns"); + if (!(subcolumns instanceof Backgrid.Columns)) { + subcolumns = this.subcolumns = this.model.subcolumns = new Backgrid.Columns(subcolumns); + } + + var customCollection = this[options.columnCollectionName] = options.model.get(options.columnCollectionName); + if(!(customCollection instanceof Backbone.Collection)) { + customCollection = this[options.columnCollectionName] = this.model.attributes[options.columnCollectionName] = new SubCollection(customCollection); + } + this.label = options.labelName; + this.subgrid = new Backgrid.Grid({ + columns: this.subcolumns, + collection: this[options.columnCollectionName], + emptyText: "No records found" + }); + + this.listenTo(Backbone, "SubgridCustomCell:remove", this.render); + }, + /** + * Renders a row containing a subgrid for this row's model. + * */ + render: function () { + this.$el.empty(); + this.$el.addClass("warning");// add class warning to subgrid row + this.gridColumnView.el.colSpan = (this.columns.length - 1); + // Appends the first empty column + $(this.el).append(this.sideColumnView.render().$el); + // Appends the subgrid column that spans the rest of the table + $(this.el).append(this.gridColumnView.render().$el); + // Appends the Subgrid + this.gridColumnView.$el.append(this.subgrid.render().$el); + $(this.$el.children()[0]).html('<b>'+this.label+'</b>'); + this.gridColumnView.$el.find('[class="backgrid"]').addClass("table-bordered"); + return this; + } + }); + /* + SubgridCustomCell is a cell class to expand and collaspe another grid within + the grid specific to each row. + + @extends Backgrid.Cell + */ + + var SubgridCustomCell = Backgrid.SubgridCustomCell = Backgrid.Cell.extend({ + + className: "subgrid-custom-cell", + // define the icon within the cell + icon: function () { + var iconOptions = '<a href="javascript:void(0);" style="color:black;"><i class="icon-plus"></i></a>'; + if(this.state == "expanded") + iconOptions = '<a href="javascript:void(0);" style="color:black;"><i class="icon-minus"></i></a>'; + return (iconOptions); + }, + optionValues: undefined, + + /** + * Initializer. + * @param {Object} options + * @param {Backbone.Model} options.model + * @param {Backgrid.Column} options.column + * @param {Backgrid.Columns} options.column.attributes + * @throws {ReferenceError} If formatter is a string but a formatter class of + * said name cannot be found in the Backgrid module. + * */ + initialize: function (options) { + this.state = "collasped"; + //requireOptions(options, ["model", "column"]); + //requireOptions(options.column.attributes, ["optionValues"]); + this.model.set("subcolumns", options.column.get("optionValues")); + //requireTypeOrder(options.column, "subgrid", 0 ); + this.column = options.column; + if (!(this.column instanceof Backgrid.Column)) { + this.column = new Backgrid.Column(this.column); + } + this.listenTo(Backbone, "backgrid:sort", this.clearSubgrid); + this.model.bind("remove", this.clearSubgrid, this); + }, + /** + * Renders a collasped view. + */ + render: function () { + //this.$el.empty().text(this.formatter.fromRaw(this.model.get(this.column.get("name")))); + $(this.el).append(this.icon()); + return this; + }, + + events: { + "click": "stateConverter" + }, + /** + * Checks the current state of the cell, either: + * appends another row for the subgrid and appends the grid to the row + * or removes the row from the parent grid, + * and saves the current data the model. + * */ + stateConverter: function () { + + var columnName = this.column.get('name'); + var columnCollectionName = columnName+"Collection"; + var labelName = this.column.attributes.label; + $(this.el).html(""); + if (this.state == "collasped"){ + $(this.el).parent().addClass("warning"); + this.state = "expanded"; + this.subrow = new SubgridCustomRow({ + columns: this.column.collection, + model: this.model, + columnName: columnName, + columnCollectionName: columnCollectionName, + labelName: labelName + }); + $(this.el).parent("tr").after(this.subrow.render().$el); + } else { + if( $(this.el).parent().siblings('.warning').length <= 1 ){ + $(this.el).parent().removeClass("warning") + } + this.state = "collasped"; + this.subrow.remove(); + } + //this.model.set("subgrid", this.subrow.subgrid); + this.model.set(columnCollectionName, this.subrow[columnCollectionName]); + + $(this.el).append(this.icon()); + }, + /** + * Binds the remove function with the row when a model is removed. + */ + clearSubgrid: function () { + var thisView = this; + // TO DO : Clean up code + $(".backgrid-subgrid-custom-row").filter(function() { + return ($(this).attr("id") == thisView.model.get('id')); + }).remove() + }, + remove: function () { + if (this.subrow) { + this.subrow.remove.apply(this, arguments); + delete this.subrow; + } + return Backbone.View.prototype.remove.apply(this, arguments); + } + }); +}); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/759f52e3/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js b/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js index 4c02504..159d18a 100644 --- a/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js +++ b/security-admin/src/main/webapp/scripts/views/reports/UserAccessLayout.js @@ -28,6 +28,7 @@ define(function(require) {'use strict'; var XATableLayout = require('views/common/XATableLayout'); var localization = require('utils/XALangSupport'); var XAGlobals = require('utils/XAGlobals'); + var CustomSubgrid = require('views/common/CustomSubgrid'); var RangerService = require('models/RangerService'); var RangerServiceDefList= require('collections/RangerServiceDefList'); @@ -76,7 +77,9 @@ define(function(require) {'use strict'; btnShowLessUsers : '[data-id="showLessUsers"]', componentType : '[data-id="component"]', downloadReport : '[data-id="downloadReport"]', - policyType : '[data-id="policyType"]' + policyType : '[data-id="policyType"]', + btnShowMoreAccess : '[data-id="showMoreAccess"]', + btnShowLessAccess : '[data-id="showLessAccess"]' }, /** ui events hash */ @@ -90,6 +93,8 @@ define(function(require) {'use strict'; events['click ' + this.ui.btnShowMoreUsers] = 'onShowMoreUsers'; events['click ' + this.ui.btnShowLessUsers] = 'onShowLessUsers'; events['click .downloadFormat'] = 'setDownloadFormatFilter'; + events['click ' + this.ui.btnShowMoreAccess] = 'onShowMorePermissions'; + events['click ' + this.ui.btnShowLessAccess] = 'onShowLessPermissions'; return events; }, @@ -140,7 +145,6 @@ define(function(require) {'use strict'; this.renderTable(obj.collName, obj.serviceDefName); this.getResourceLists(obj.collName,obj.serviceDefName); },this); - this.modifyTableForSubcolumns(); this.$el.find('[data-js="policyName"]').focus() var urlString = XAUtil.getBaseUrl(); if(urlString.slice(-1) == "/") { @@ -163,13 +167,26 @@ define(function(require) {'use strict'; XAUtil.blockUI('unblock'); if(coll.length >= 1 && !that.allowDownload) that.allowDownload = true; - + _.each(that[collName].models,function(model,ind){ + if (XAUtil.isMaskingPolicy(model.get('policyType'))) { + //'<name>Collection' must be same as subgrid custom column name + model.attributes.allowCollection = model.get('dataMaskPolicyItems'); + } else if (XAUtil.isRowFilterPolicy(model.get('policyType'))) { + model.attributes.allowCollection = model.get('rowFilterPolicyItems'); + } else { + model.attributes.allowCollection = model.get('policyItems'); + } + model.attributes.denyCollection = model.get('denyPolicyItems'); + model.attributes.denyExcludeCollection = model.get('denyExceptions'); + model.attributes.allowExcludeCollection = model.get('allowExceptions'); + }); + }); }, renderTable : function(collName,serviceDefName){ var that = this, tableRegion = this[collName+'Table']; tableRegion.show(new XATableLayout({ - columns: this.getColumns(this[collName],collName,serviceDefName), + columns: this.getSubgridColumns(this[collName],collName,serviceDefName), collection: this[collName], includeFilter : false, scrollToTop : false, @@ -181,17 +198,110 @@ define(function(require) {'use strict'; })); }, - getColumns : function(coll,collName,serviceDefName){ + getSubgridColumns:function(coll,collName,serviceDefName){ var that = this; - var cols = { + + var subcolumns = [{ + name: 'groups', + cell: 'html', + label: 'Groups', + formatter: _.extend({}, Backgrid.CellFormatter.prototype, { + fromRaw: function (rawValue,model, coll) { + var startSpanEle = '<span class="label label-info cellWidth-1 float-left-margin-2" style="">',endSpanEle = '</span>'; + var group_str = ''; + if(_.isEmpty(model.get('groups'))){ + return '<center>--</center>'; + } else { + _.each(model.get('groups'),function(group,index){ + if(index < 4) { + group_str += '<span class="label label-info cellWidth-1 float-left-margin-2" group-policy-id="'+model.cid+'" style="">' + group + endSpanEle + " "; + } else { + group_str += '<span class="label label-info cellWidth-1 float-left-margin-2" group-policy-id="'+model.cid+'" style="display:none">' + group+ endSpanEle + " "; + } + }); + if(model.get('groups').length > 4) { + group_str += '<span class="pull-left float-left-margin-2">\ + <a href="javascript:void(0);" data-id="showMoreAccess" policy-id="'+ + model.cid+'"><code style=""> + More..</code></a></span>\ + <span class="pull-left float-left-margin-2" ><a href="javascript:void(0);" data-id="showLessAccess" policy-id="'+ + model.cid+'" style="display:none;"><code style=""> - Less..</code></a></span>';} + return group_str; + } + } + }), + editable: false, + click: false, + sortable: false + }, + { + name: 'users', + cell: 'html', + label: 'Users', + formatter: _.extend({}, Backgrid.CellFormatter.prototype, { + fromRaw: function (rawValue,model) { + var startSpanEle = '<span class="label label-info cellWidth-1 float-left-margin-2" style="">',endSpanEle = '</span>'; + var user_str = ''; + if(_.isEmpty(model.get('users'))){ + return '<center>--</center>'; + } else { + _.each(model.get('users'),function(user,index){ + if(index < 4) { + user_str += '<span class="label label-info cellWidth-1 float-left-margin-2" user-policy-id="'+model.cid+'" style="">' + user + endSpanEle + " "; + } else { + user_str += '<span class="label label-info cellWidth-1 float-left-margin-2" user-policy-id="'+model.cid+'" style="display:none">' + user+ endSpanEle + " "; + } + }); + if(model.get('users').length > 4) { + user_str += '<span class="pull-left float-left-margin-2">\ + <a href="javascript:void(0);" data-id="showMoreAccess" policy-id="'+ + model.cid+'"><code style=""> + More..</code></a></span>\ + <span class="pull-left float-left-margin-2" ><a href="javascript:void(0);" data-id="showLessAccess" policy-id="'+ + model.cid+'" style="display:none;"><code style=""> - Less..</code></a></span>';} + return user_str;} + } + }), + editable: false, + click: false, + sortable: false + }, + { + name: 'accesses', + cell: 'html', + label: 'Accesses', + formatter: _.extend({}, Backgrid.CellFormatter.prototype, { + fromRaw: function (rawValue,model) { + var startSpanEle = '<span class="label label-info cellWidth-1 float-left-margin-2" style="">',endSpanEle = '</span>'; + var access_str = ''; + _.each(model.get('accesses'),function(access,index){ + if(index < 4){ + access_str += '<span class="label label-info cellWidth-1 float-left-margin-2" access-policy-id="'+model.cid+'" style="">' + access.type+ endSpanEle + " "; + } else { + access_str += '<span class="label label-info cellWidth-1 float-left-margin-2" access-policy-id="'+model.cid+'" style="display:none">' + access.type+ endSpanEle + " "; + } + }); + if(model.get('accesses').length > 4) { + access_str += '<span class="pull-left float-left-margin-2">\ + <a href="javascript:void(0);" data-id="showMoreAccess" policy-id="'+ + model.cid+'"><code style=""> + More..</code></a></span>\ + <span class="pull-left float-left-margin-2" ><a href="javascript:void(0);" data-id="showLessAccess" policy-id="'+ + model.cid+'" style="display:none;"><code style=""> - Less..</code></a></span>';} + return access_str; + } + }), + editable: false, + click: false, + sortable: false + } + ]; + var columns = { id : { cell : "uri", href: function(model){ var rangerService = new RangerService(); - rangerService.urlRoot += '/name/'+model.get('service'); + rangerService.urlRoot += '/name/'+model.get('service'); rangerService.fetch({ - cache : false, - async : false + cache : false, + async : false }); return '#!/service/'+rangerService.get('id')+'/policies/'+model.id+'/edit'; }, @@ -205,8 +315,7 @@ define(function(require) {'use strict'; editable: false, sortable : false }, - resources: - { + resources: { label: 'Resources', cell: 'Html', formatter: _.extend({}, Backgrid.CellFormatter.prototype, { @@ -225,12 +334,12 @@ define(function(require) {'use strict'; strVal = strVal+ "<br />"; }); return strVal; - } + } }), editable: false, sortable: false, click: false - }, + }, policyType: { label: 'Policy Type', cell: Backgrid.HtmlCell.extend({className: 'cellWidth-1', className: 'html-cell'}), @@ -251,56 +360,6 @@ define(function(require) {'use strict'; sortable: false, click: false }, - permissions: { - label: 'Permissions', - cell : Backgrid.HtmlCell.extend({className: 'cellWidth-1', className: 'html-cell' }), - formatter: _.extend({}, Backgrid.CellFormatter.prototype,{ - fromRaw: function(rawValue,model){ - var itemList = [], policyType = model.get("policyType"); - if (XAUtil.isMaskingPolicy(policyType)) { - itemList = model.get("dataMaskPolicyItems"); - } else if (XAUtil.isRowFilterPolicy(policyType)) { - itemList = model.get("rowFilterPolicyItems"); - }else{// by default it is access - itemList = model.get("policyItems"); - } - if(itemList.length > 0) { - var htmlStr = '', accessStr = '', grpStr = '', userStr = ''; - var startSpanEle = '<span class="label label-info cellWidth-1 float-left-margin-2" style="">',endSpanEle = '</span>'; - _.each(itemList,function(policyItem){ - if(!_.isUndefined(policyItem.groups) || !_.isUndefined(policyItem.users) && - !_.isUndefined(policyItem.accesses)){ - var maxItem = policyItem.groups.length > policyItem.users.length ? policyItem.groups : policyItem.users; - maxItem = policyItem.accesses.length > maxItem.length ? policyItem.accesses : maxItem; - - _.each(maxItem,function(item, i){ - if(!_.isUndefined(policyItem.users[i])){ - userStr += startSpanEle + policyItem.users[i] + endSpanEle; - } - if(!_.isUndefined(policyItem.groups[i])){ - grpStr += startSpanEle + policyItem.groups[i] + endSpanEle; - } - if(!_.isUndefined(policyItem.accesses[i])){ - accessStr += startSpanEle + policyItem.accesses[i].type + endSpanEle; - } - }); - - } - htmlStr += '<tr style="height:60px"><td class="report-user-group">'+grpStr+'</td>\ - <td class="report-user-group">'+(userStr)+'</td>\ - <td class="report-access">'+accessStr+'</td></tr>'; - accessStr = '', grpStr = '', userStr = ''; - }); - return htmlStr; - } else { - return '---'; - } - } - }), - editable: false, - sortable: false, - click: false - }, isEnabled:{ label:localization.tt('lbl.status'), cell :"html", @@ -314,91 +373,143 @@ define(function(require) {'use strict'; drag : false, sortable : false } - }; + var permissions = this.getPermissionColumns(this[collName],collName,serviceDefName,subcolumns); + _.extend(columns,permissions); + return coll.constructor.getTableCols(columns, coll); + }, + getPermissionColumns: function (coll,collName,serviceDefName,subcolumns){ + + var that = this,permissions,cols,serviceDefOptions; + + var serviceDefOptions = {}; + _.each(this.serviceDefList.models, function(model){ + if(model.get('name') === serviceDefName) + serviceDefOptions = model.get('options'); + }); + var enableDenyAndExceptionsInPolicies = false; + if(!_.isUndefined(serviceDefOptions.enableDenyAndExceptionsInPolicies)) + enableDenyAndExceptionsInPolicies = true; + if(serviceDefName === XAEnums.ServiceType.SERVICE_TAG.label){ + enableDenyAndExceptionsInPolicies = true; + } - return coll.constructor.getTableCols(cols, coll); + permissions = { + allow:{ + label: 'Allow Conditions', + cell: "subgrid-custom", + optionValues : subcolumns, + editable: false, + sortable: false, + click : false + } + }; + if(enableDenyAndExceptionsInPolicies) { + cols = { + allowExclude:{ + label: 'Allow Exclude', + cell: "subgrid-custom", + optionValues : subcolumns, + editable: false, + sortable: false, + click : false + }, + deny:{ + label: 'Deny Conditions', + cell: "subgrid-custom", + optionValues : subcolumns, + editable: false, + sortable: false, + click : false + }, + denyExclude:{ + label: 'Deny Exclude', + cell: "subgrid-custom", + optionValues : subcolumns, + editable: false, + sortable: false, + click : false + } + }; + } + return _.extend(permissions,cols); }, - /* add 'component' and 'policy type' select */ - renderComponentAndPolicyTypeSelect: function(){ - var that = this; - var options = this.serviceDefList.map(function(m){ return { 'id' : m.get('name'), 'text' : m.get('name')}; }); - var policyTypes = _.map(XAEnums.RangerPolicyType,function(m){ - return {'id': m.value,'text': m.label}; - }); - this.ui.componentType.select2({ - multiple: true, - closeOnSelect: true, - placeholder: 'Select Component', - //maximumSelectionSize : 1, - width: '220px', - allowClear: true, - data: options - }); - this.ui.policyType.select2({ - closeOnSelect: true, - placeholder: 'Select policy type', - maximumSelectionSize : 1, - width: '220px', - allowClear: true, - data: policyTypes - }); - }, - modifyTableForSubcolumns : function(){ - this.$el.find(".permissions").html('<tr><th colspan="3">Permissions</th></tr>\ - <tr><th style="width:80px;max-width:80px;">Groups</th><th style="width:80px;max-width:80px;">Users</th>\ - <th style="width:150px">Accesses</th></tr>'); - }, - onDownload: function(e){ - var that = this, url = ''; - if(!this.allowDownload){ - XAUtil.alertPopup({ - msg :"No policies found to download!", + /* add 'component' and 'policy type' select */ + renderComponentAndPolicyTypeSelect: function(){ + var that = this; + var options = this.serviceDefList.map(function(m){ return { 'id' : m.get('name'), 'text' : m.get('name')}; }); + var policyTypes = _.map(XAEnums.RangerPolicyType,function(m){ + return {'id': m.value,'text': m.label}; }); - return; - } - if(!this.searchedFlag) { - url = this.previousSearchUrl; - } else if (this.searchedFlag && this.updatedUrl) { - var urlString = XAUtil.getBaseUrl(); - if(urlString.slice(-1) === "/") { - urlString = urlString.slice(0,-1); + this.ui.componentType.select2({ + multiple: true, + closeOnSelect: true, + placeholder: 'Select Component', + //maximumSelectionSize : 1, + width: '220px', + allowClear: true, + data: options + }); + this.ui.policyType.select2({ + closeOnSelect: true, + placeholder: 'Select policy type', + maximumSelectionSize : 1, + width: '220px', + allowClear: true, + data: policyTypes + + }); + }, + onDownload: function(e){ + var that = this, url = ''; + if(!this.allowDownload){ + XAUtil.alertPopup({ + msg :"No policies found to download!", + }); + return; } - url = url + urlString; - if (e === "xlsFormat") { - url = url + '/service/plugins/policies/downloadExcel?'; - } else { - url = url + '/service/plugins/policies/csv?'; + if(!this.searchedFlag) { + url = this.previousSearchUrl; + } else if (this.searchedFlag && this.updatedUrl) { + var urlString = XAUtil.getBaseUrl(); + if(urlString.slice(-1) === "/") { + urlString = urlString.slice(0,-1); + } + url = url + urlString; + if (e === "xlsFormat") { + url = url + '/service/plugins/policies/downloadExcel?'; + } else { + url = url + '/service/plugins/policies/csv?'; + } + url = url + this.searchedParamsString + this.searchedComponentString; + this.previousSearchUrl = url; + this.searchedFlag = true; } - url = url + this.searchedParamsString + this.searchedComponentString; - this.previousSearchUrl = url; - this.searchedFlag = true; - } - this.ui.downloadReport.attr("href",url)[0].click(); - }, - setDownloadReportUrl: function(that,component,params){ + this.ui.downloadReport.attr("href",url)[0].click(); + }, + setDownloadReportUrl: function(that,component,params){ - var compString = '', url = ''; - if(!_.isUndefined(component)) { - _.each(component,function(comp){ - compString = compString + comp + '_'; - }); - } - if (!_.isEmpty(compString)) { - compString = compString.slice(0,-1); - } - _.each(params, function(val, paramName){ - if(_.isUndefined(val) || _.isEmpty(val)) { - delete params[paramName]; + var compString = '', url = ''; + if(!_.isUndefined(component)) { + _.each(component,function(comp){ + compString = compString + comp + '_'; + }); } - }); - var str = jQuery.param( params ); - this.searchedComponentString = "&serviceType=" + compString; - this.searchedParamsString = str; - this.updatedUrl = true; + if (!_.isEmpty(compString)) { + compString = compString.slice(0,-1); + } + _.each(params, function(val, paramName){ + if(_.isUndefined(val) || _.isEmpty(val)) { + delete params[paramName]; + } + }); + var str = jQuery.param( params ); + this.searchedComponentString = "&serviceType=" + compString; + this.searchedParamsString = str; + this.updatedUrl = true; - }, + }, /** on render callback */ setupGroupAutoComplete : function(){ this.groupArr = this.groupList.map(function(m){ @@ -673,6 +784,27 @@ define(function(require) {'use strict'; }, 1100); } }, + onShowMorePermissions: function(e){ + var policyId = $(e.currentTarget).attr('policy-id'); + var $td = $(e.currentTarget).parents('td'); + $td.find('[access-policy-id="'+policyId+'"]').show(); + $td.find('[user-policy-id="'+policyId+'"]').show(); + $td.find('[group-policy-id="'+policyId+'"]').show(); + $td.find('[data-id="showLessAccess"][policy-id="'+policyId+'"]').show(); + $td.find('[data-id="showMoreAccess"][policy-id="'+policyId+'"]').hide(); + + }, + onShowLessPermissions: function(e){ + var policyId = $(e.currentTarget).attr('policy-id'); + var $td = $(e.currentTarget).parents('td'); + $td.find('[access-policy-id="'+policyId+'"]').slice(4).hide(); + $td.find('[user-policy-id="'+policyId+'"]').slice(4).hide(); + $td.find('[group-policy-id="'+policyId+'"]').slice(4).hide(); + $td.find('[data-id="showMoreAccess"][policy-id="'+policyId+'"]').show(); + $td.find('[data-id="showLessAccess"][policy-id="'+policyId+'"]').hide(); + + }, + onShowMore : function(e){ var attrName = 'policy-groups-id'; var id = $(e.currentTarget).attr(attrName); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/759f52e3/security-admin/src/main/webapp/styles/xa.css ---------------------------------------------------------------------- diff --git a/security-admin/src/main/webapp/styles/xa.css b/security-admin/src/main/webapp/styles/xa.css index a451761..fb5d80e 100644 --- a/security-admin/src/main/webapp/styles/xa.css +++ b/security-admin/src/main/webapp/styles/xa.css @@ -1945,38 +1945,41 @@ input[type="radio"], input[type="checkbox"] {margin-top: 0;} max-width: 120px; } .hdfs-table table.backgrid thead th:nth-child(1){ - width: 60px; - max-width: 60px + width: 8%; + } .hdfs-table table.backgrid thead th:nth-child(2) { /*width: 300px;*/ width: 25%; } .hdfs-table table.backgrid thead th:nth-child(3){ - width:200px; + width:30%; } .hdfs-table table.backgrid thead th:nth-child(4){ - width:100px; + width:10%; } .hdfs-table table.backgrid tbody td:nth-child(4){ - width:100px; + width:10%; text-align: center; } .hdfs-table table.backgrid tbody tr td:nth-child(3){ text-align: left !important; max-width: 200px; } -.hdfs-table table.backgrid tbody tr td:nth-child(6){ +.hdfs-table table.backgrid tbody tr td:nth-child(5){ text-align: center; width: 100px } -.hdfs-table table.backgrid thead th:nth-child(6){ +.hdfs-table table.backgrid thead th:nth-child(5){ text-align: center; - width: 100px; + width: 10%; } -.hdfs-table table.backgrid thead th:nth-child(5) tr{ - border-left-style: hidden; +.hdfs-table table.backgrid thead th:nth-child(6){ + width: 10%; } +/*.hdfs-table table.backgrid thead th:nth-child(5) tr{ + border-left-style: hidden; +}*/ .report-access{ width:100%; border-right:1px solid #DDD; @@ -1984,4 +1987,37 @@ input[type="radio"], input[type="checkbox"] {margin-top: 0;} .report-user-group{ width:80px; min-width:80px; -} \ No newline at end of file +} +td.subgrid-custom-cell{ + text-align: center; +} +.backgrid-subgrid-custom-row table.backgrid thead th:nth-child(1){ + width: 300px; + max-width: 300px; +} +.backgrid-subgrid-custom-row table.backgrid thead th:nth-child(2){ + width: 300px; + max-width: 300px; +} +.backgrid-subgrid-custom-row table.backgrid thead th:nth-child(3){ + width: 300px; + max-width: 300px; +} +.backgrid-subgrid-custom-row table.backgrid tbody td:nth-child(1){ + width: 300px; + max-width: 300px; +} +.backgrid-subgrid-custom-row table.backgrid tbody td:nth-child(2){ + width: 300px; + max-width: 300px; +} +.backgrid-subgrid-custom-row table.backgrid tbody td:nth-child(3){ + width: 300px; + max-width: 300px; +} +.hdfs-table table.backgrid tbody tr.backgrid-subgrid-custom-row{ + background-color: #f9f9f9; +} +.backgrid-subgrid-custom-row table.backgrid thead th { + font-weight:inherit; +}
