From 88d52adbab65fc33b7b4220e4e84fff70bc0c566 Mon Sep 17 00:00:00 2001 From: Stas Vilchik Date: Thu, 31 Oct 2013 15:29:51 +0100 Subject: [PATCH] SONAR-4851 Offer a new smart search input form on top of the page --- .../app/controllers/issues_controller.rb | 23 ++ .../app/views/issues/_sidebar2.html.erb | 4 + .../WEB-INF/app/views/issues/search2.html.erb | 84 ++++++++ .../WEB-INF/app/views/layouts/_head.html.erb | 8 + .../main/webapp/javascripts/navigator/app.js | 94 +++++++++ .../webapp/javascripts/navigator/filters.js | 198 ++++++++++++++++++ .../third-party/backbone.marionette.min.js | 21 ++ .../src/main/webapp/stylesheets/mixins.css | 0 .../src/main/webapp/stylesheets/mixins.less | 154 ++++++++++++++ .../src/main/webapp/stylesheets/navigator.css | 81 +++++++ .../main/webapp/stylesheets/navigator.less | 103 +++++++++ .../src/main/webapp/stylesheets/variables.css | 3 + .../main/webapp/stylesheets/variables.less | 8 + sonar-server/wro.xml | 6 + 14 files changed, 787 insertions(+) create mode 100644 sonar-server/src/main/webapp/WEB-INF/app/views/issues/_sidebar2.html.erb create mode 100644 sonar-server/src/main/webapp/WEB-INF/app/views/issues/search2.html.erb create mode 100644 sonar-server/src/main/webapp/javascripts/navigator/app.js create mode 100644 sonar-server/src/main/webapp/javascripts/navigator/filters.js create mode 100644 sonar-server/src/main/webapp/javascripts/third-party/backbone.marionette.min.js create mode 100644 sonar-server/src/main/webapp/stylesheets/mixins.css create mode 100644 sonar-server/src/main/webapp/stylesheets/mixins.less create mode 100644 sonar-server/src/main/webapp/stylesheets/navigator.css create mode 100644 sonar-server/src/main/webapp/stylesheets/navigator.less create mode 100644 sonar-server/src/main/webapp/stylesheets/variables.css create mode 100644 sonar-server/src/main/webapp/stylesheets/variables.less diff --git a/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb index c2f9cca74b2..319c2306221 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb +++ b/sonar-server/src/main/webapp/WEB-INF/app/controllers/issues_controller.rb @@ -54,6 +54,29 @@ class IssuesController < ApplicationController end end + # GET /issues/search + def search2 + @issues_query_params = criteria_params + @first_search = issues_query_params_sanitized.empty? + @unchanged = issues_query_params_sanitized.empty? + + init_params + if params[:id] + @filter = find_filter(params[:id].to_i) + @first_search = false + issue_filter_result = Internal.issues.execute(params[:id].to_i, @issues_query_params) + else + issue_filter_result = Internal.issues.execute(@issues_query_params) + end + @issues_query = issue_filter_result.query + @issues_result = issue_filter_result.result + + if request.xhr? + @ajax_mode = true + render :partial => 'search_ajax' + end + end + # Load existing filter # GET /issues/filter/ def filter diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_sidebar2.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_sidebar2.html.erb new file mode 100644 index 00000000000..56dbf5ffb16 --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/_sidebar2.html.erb @@ -0,0 +1,4 @@ +
+ +
+ diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/search2.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/search2.html.erb new file mode 100644 index 00000000000..6bd2ffee8db --- /dev/null +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/search2.html.erb @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb index a02adcab8fd..6eb48e182db 100644 --- a/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb +++ b/sonar-server/src/main/webapp/WEB-INF/app/views/layouts/_head.html.erb @@ -31,6 +31,7 @@ <%= stylesheet_link_tag 'sonar-colorizer', :media => 'all' %> <%= stylesheet_link_tag 'dashboard', :media => 'all' %> <%= stylesheet_link_tag 'select-list', :media => 'all' %> + <%= stylesheet_link_tag 'navigator', :media => 'all' %> <%= yield :style -%> <%= javascript_include_tag 'third-party/prototype' %> <%= javascript_include_tag 'third-party/scriptaculous' %> @@ -40,12 +41,19 @@ <%= javascript_include_tag 'third-party/d3.v3.min' %> <%= javascript_include_tag 'third-party/underscore-min' %> <%= javascript_include_tag 'third-party/backbone-min' %> + <%= javascript_include_tag 'third-party/backbone.marionette.min' %> <%= javascript_include_tag 'third-party/jquery.ba-throttle-debounce.min.js' %> <%= javascript_include_tag 'third-party/select2.min' %> + <%= javascript_include_tag 'widgets/bubble-chart' %> <%= javascript_include_tag 'widgets/timeline' %> <%= javascript_include_tag 'widgets/stack-area' %> + <%= javascript_include_tag 'select-list' %> + + <%= javascript_include_tag 'navigator/filters' %> + <%= javascript_include_tag 'navigator/app' %> + <%= javascript_include_tag 'application' %> <%= javascript_include_tag 'dashboard' %> <%= javascript_include_tag 'duplication' %> diff --git a/sonar-server/src/main/webapp/javascripts/navigator/app.js b/sonar-server/src/main/webapp/javascripts/navigator/app.js new file mode 100644 index 00000000000..9820dbd453b --- /dev/null +++ b/sonar-server/src/main/webapp/javascripts/navigator/app.js @@ -0,0 +1,94 @@ +/* global $j:false, Backbone:false */ + +window.SS = typeof window.SS === 'object' ? window.SS : {}; + +(function() { + + var NavigatorApp = new Backbone.Marionette.Application(); + window.SS.NavigatorApp = NavigatorApp; + + + + NavigatorApp.addRegions({ + filtersRegion: '.navigator-filters' + }); + + + + NavigatorApp.addInitializer(function() { + this.filters = new window.SS.Filters([ + new window.SS.Filter({ + name: 'Project', + property: 'componentRoots', + type: window.SS.AjaxSelectFilterView, + select2 : { + allowClear: true, + ajax: { + quietMillis: 300, + url: '/dev/api/resources/search?f=s2&q=TRK&display_key=true', + data: function (term, page) { return { s: term, p: page }; }, + results: function (data) { return { more: data.more, results: data.results }; } + } + } + }), + + new window.SS.Filter({ + name: 'Severity', + property: 'severities[]', + type: window.SS.SelectFilterView, + choices: window.SS.severities + }), + + new window.SS.Filter({ + name: 'Status', + property: 'statuses[]', + type: window.SS.SelectFilterView, + choices: window.SS.statuses + }), + + new window.SS.Filter({ + name: 'Resolution', + property: 'resolutions[]', + type: window.SS.SelectFilterView, + choices: window.SS.resolutions + }), + + new window.SS.Filter({ + name: 'Assignee', + property: 'assignees', + type: window.SS.AjaxSelectFilterView, + select2: { + allowClear: true, + query: + function(query) { + if (query.term.length === 0) { + query.callback({results: [{id:'',text:'Unassigned'}]}); + } else if (query.term.length >= 2) { + $j.ajax('/dev/api/users/search?f=s2', { + data: {s: query.term}, + dataType: 'jsonp' + }).done(function(data) { + query.callback(data); + }); + } + } + } + }), + + new window.SS.Filter({ + name: 'Created', + propertyFrom: 'createdAfter', + propertyTo: 'createdBefore', + type: window.SS.RangeFilterView + }) + ]); + + + this.filterBarView = new window.SS.FilterBarView({ + collection: this.filters + }); + + this.filtersRegion.show(this.filterBarView); + }); + +})(); diff --git a/sonar-server/src/main/webapp/javascripts/navigator/filters.js b/sonar-server/src/main/webapp/javascripts/navigator/filters.js new file mode 100644 index 00000000000..0336b007d94 --- /dev/null +++ b/sonar-server/src/main/webapp/javascripts/navigator/filters.js @@ -0,0 +1,198 @@ +/* global _:false, $j:false, Backbone:false */ + +window.SS = typeof window.SS === 'object' ? window.SS : {}; + +(function() { + + var Filter = Backbone.Model.extend({ + + }); + + var Filters = Backbone.Collection.extend({ + model: Filter + }); + + + var BaseFilterView = Backbone.Marionette.ItemView.extend({ + template: '#filterTemplate', + className: 'navigator-filter', + + events: function() { + return {}; + }, + + renderBody: function() { + return ''; + }, + + serializeData: function() { + return _.extend({}, this.model.toJSON(), { + body: this.renderBody() + }); + }, + + restore: function() { + + } + }); + + + var SelectFilterView = BaseFilterView.extend({ + + modelEvents: { + "change": "render" + }, + + renderBody: function() { + var template = _.template($j('#selectFilterTemplate').html()); + return template(this.model.toJSON()); + }, + + onRender: function() { + var that = this; + + this.$('.navigator-filter-label').hide(); + + this.$(':input').select2({ + allowClear: false, + placeholder: this.model.get('name'), + width: '150px' + }).on('change', function(e) { + that.model.set('value', e.val); + }); + + this.restore(); + }, + + restore: function() { + if (this.model.get('value')) { + this.$(':input').select2('val', this.model.get('value')); + } + } + }); + + + var AjaxSelectFilterView = BaseFilterView.extend({ + + renderBody: function() { + var template = _.template($j('#ajaxSelectFilterTemplate').html()); + return template(this.model.toJSON()); + }, + + onRender: function() { + var that = this; + + this.$('.navigator-filter-label').hide(); + + this.$(':input').select2(_.extend({ + allowClear: false, + placeholder: this.model.get('name'), + width: '150px', + minimumInputLength: 2 + }, this.model.get('select2'))) + .on('change', function(e) { + that.model.set('value', e.val); + }); + + this.restore(); + }, + + restore: function() { + if (this.model.get('value')) { + this.$(':input').select2('data', this.model.get('value')); + } + } + }); + + + var RangeFilterView = BaseFilterView.extend({ + + events: function() { + return _.extend(BaseFilterView.prototype.events.call(), { + 'change input': 'changeInput' + }); + }, + + renderBody: function() { + var template = _.template($j('#rangeFilterTemplate').html()); + return template(this.model.toJSON()); + }, + + onRender: function() { + this.restore(); + }, + + changeInput: function() { + this.model.set('value', { + from: '', + to: '' + }); + }, + + restore: function() { + if (this.model.get('value')) { + this.$('[name="' + this.model.get('propertyFrom') + '"]').val(this.model.get('value').from); + this.$('[name="' + this.model.get('propertyTo') + '"]').val(this.model.get('value').to); + } + } + + }); + + + var FilterBarView = Backbone.Marionette.CompositeView.extend({ + template: '#filterBarTemplate', + itemViewContainer: '.navigator-filters-list', + + collectionEvents: { + 'change': 'changeFilters' + }, + + getItemView: function(item) { + return item.get('type') || BaseFilterView; + }, + + + itemViewOptions: function() { + return { + filterBarView: this + }; + }, + + changeFilters: function() { + var query = {}; + this.collection.each(function(item) { + if (item.get('value')) { + query[item.get('property')] = item.get('value'); + } + }); + this.applyQuery($j.param(query)); + }, + + applyQuery: function(query) { + $j.ajax({ + url: '/dev/issues/search', + type: 'get', + data: query + }).done(function(r) { + $j('.navigator-results').html(r); + }); + } + }); + + + + /* + * Export public classes + */ + + _.extend(window.SS, { + Filter: Filter, + Filters: Filters, + BaseFilterView: BaseFilterView, + FilterBarView: FilterBarView, + SelectFilterView: SelectFilterView, + AjaxSelectFilterView: AjaxSelectFilterView, + RangeFilterView: RangeFilterView + }); + +})(); diff --git a/sonar-server/src/main/webapp/javascripts/third-party/backbone.marionette.min.js b/sonar-server/src/main/webapp/javascripts/third-party/backbone.marionette.min.js new file mode 100644 index 00000000000..58ac9a82c71 --- /dev/null +++ b/sonar-server/src/main/webapp/javascripts/third-party/backbone.marionette.min.js @@ -0,0 +1,21 @@ +// MarionetteJS (Backbone.Marionette) +// ---------------------------------- +// v1.2.1 +// +// Copyright (c)2013 Derick Bailey, Muted Solutions, LLC. +// Distributed under MIT license +// +// http://marionettejs.com + + + +/*! + * Includes BabySitter + * https://github.com/marionettejs/backbone.babysitter/ + * + * Includes Wreqr + * https://github.com/marionettejs/backbone.wreqr/ + */ + +Backbone.ChildViewContainer=function(a,b){var c=function(a){this._views={},this._indexByModel={},this._indexByCustom={},this._updateLength(),b.each(a,this.add,this)};b.extend(c.prototype,{add:function(a,b){var c=a.cid;this._views[c]=a,a.model&&(this._indexByModel[a.model.cid]=c),b&&(this._indexByCustom[b]=c),this._updateLength()},findByModel:function(a){return this.findByModelCid(a.cid)},findByModelCid:function(a){var b=this._indexByModel[a];return this.findByCid(b)},findByCustom:function(a){var b=this._indexByCustom[a];return this.findByCid(b)},findByIndex:function(a){return b.values(this._views)[a]},findByCid:function(a){return this._views[a]},remove:function(a){var c=a.cid;a.model&&delete this._indexByModel[a.model.cid],b.any(this._indexByCustom,function(a,b){return a===c?(delete this._indexByCustom[b],!0):void 0},this),delete this._views[c],this._updateLength()},call:function(a){this.apply(a,b.tail(arguments))},apply:function(a,c){b.each(this._views,function(d){b.isFunction(d[a])&&d[a].apply(d,c||[])})},_updateLength:function(){this.length=b.size(this._views)}});var d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck"];return b.each(d,function(a){c.prototype[a]=function(){var c=b.values(this._views),d=[c].concat(b.toArray(arguments));return b[a].apply(b,d)}}),c}(Backbone,_),Backbone.Wreqr=function(a,b,c){"use strict";var d={};return d.Handlers=function(a,b){var c=function(a){this.options=a,this._wreqrHandlers={},b.isFunction(this.initialize)&&this.initialize(a)};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events,{setHandlers:function(a){b.each(a,function(a,c){var d=null;b.isObject(a)&&!b.isFunction(a)&&(d=a.context,a=a.callback),this.setHandler(c,a,d)},this)},setHandler:function(a,b,c){var d={callback:b,context:c};this._wreqrHandlers[a]=d,this.trigger("handler:add",a,b,c)},hasHandler:function(a){return!!this._wreqrHandlers[a]},getHandler:function(a){var b=this._wreqrHandlers[a];if(!b)throw new Error("Handler not found for '"+a+"'");return function(){var a=Array.prototype.slice.apply(arguments);return b.callback.apply(b.context,a)}},removeHandler:function(a){delete this._wreqrHandlers[a]},removeAllHandlers:function(){this._wreqrHandlers={}}}),c}(a,c),d.CommandStorage=function(){var b=function(a){this.options=a,this._commands={},c.isFunction(this.initialize)&&this.initialize(a)};return c.extend(b.prototype,a.Events,{getCommands:function(a){var b=this._commands[a];return b||(b={command:a,instances:[]},this._commands[a]=b),b},addCommand:function(a,b){var c=this.getCommands(a);c.instances.push(b)},clearCommands:function(a){var b=this.getCommands(a);b.instances=[]}}),b}(),d.Commands=function(a){return a.Handlers.extend({storageType:a.CommandStorage,constructor:function(b){this.options=b||{},this._initializeStorage(this.options),this.on("handler:add",this._executeCommands,this);var c=Array.prototype.slice.call(arguments);a.Handlers.prototype.constructor.apply(this,c)},execute:function(a,b){a=arguments[0],b=Array.prototype.slice.call(arguments,1),this.hasHandler(a)?this.getHandler(a).apply(this,b):this.storage.addCommand(a,b)},_executeCommands:function(a,b,d){var e=this.storage.getCommands(a);c.each(e.instances,function(a){b.apply(d,a)}),this.storage.clearCommands(a)},_initializeStorage:function(a){var b,d=a.storageType||this.storageType;b=c.isFunction(d)?new d:d,this.storage=b}})}(d),d.RequestResponse=function(a){return a.Handlers.extend({request:function(){var a=arguments[0],b=Array.prototype.slice.call(arguments,1);return this.getHandler(a).apply(this,b)}})}(d),d.EventAggregator=function(a,b){var c=function(){};return c.extend=a.Model.extend,b.extend(c.prototype,a.Events),c}(a,c),d}(Backbone,Backbone.Marionette,_);var Marionette=function(a,b,c){"use strict";function d(a){return g.call(a)}function e(a,b){var c=new Error(a);throw c.name=b||"Error",c}var f={};b.Marionette=f,f.$=b.$;var g=Array.prototype.slice;return f.extend=b.Model.extend,f.getOption=function(a,b){if(a&&b){var c;return c=a.options&&b in a.options&&void 0!==a.options[b]?a.options[b]:a[b]}},f.triggerMethod=function(){function a(a,b,c){return c.toUpperCase()}var b=/(^|:)(\w)/gi,d=function(d){var e="on"+d.replace(b,a),f=this[e];return c.isFunction(this.trigger)&&this.trigger.apply(this,arguments),c.isFunction(f)?f.apply(this,c.tail(arguments)):void 0};return d}(),f.MonitorDOMRefresh=function(){function a(a){a._isShown=!0,d(a)}function b(a){a._isRendered=!0,d(a)}function d(a){a._isShown&&a._isRendered&&c.isFunction(a.triggerMethod)&&a.triggerMethod("dom:refresh")}return function(c){c.listenTo(c,"show",function(){a(c)}),c.listenTo(c,"render",function(){b(c)})}}(),function(a){function b(a,b,d,f){var g=f.split(/\s+/);c.each(g,function(c){var f=a[c];f||e("Method '"+c+"' was configured as an event handler, but does not exist."),a.listenTo(b,d,f,a)})}function d(a,b,c,d){a.listenTo(b,c,d,a)}function f(a,b,d,e){var f=e.split(/\s+/);c.each(f,function(c){var e=a[c];a.stopListening(b,d,e,a)})}function g(a,b,c,d){a.stopListening(b,c,d,a)}function h(a,b,d,e,f){b&&d&&(c.isFunction(d)&&(d=d.call(a)),c.each(d,function(d,g){c.isFunction(d)?e(a,b,g,d):f(a,b,g,d)}))}a.bindEntityEvents=function(a,c,e){h(a,c,e,d,b)},a.unbindEntityEvents=function(a,b,c){h(a,b,c,g,f)}}(f),f.Callbacks=function(){this._deferred=f.$.Deferred(),this._callbacks=[]},c.extend(f.Callbacks.prototype,{add:function(a,b){this._callbacks.push({cb:a,ctx:b}),this._deferred.done(function(c,d){b&&(c=b),a.call(c,d)})},run:function(a,b){this._deferred.resolve(b,a)},reset:function(){var a=this._callbacks;this._deferred=f.$.Deferred(),this._callbacks=[],c.each(a,function(a){this.add(a.cb,a.ctx)},this)}}),f.Controller=function(a){this.triggerMethod=f.triggerMethod,this.options=a||{},c.isFunction(this.initialize)&&this.initialize(this.options)},f.Controller.extend=f.extend,c.extend(f.Controller.prototype,b.Events,{close:function(){this.stopListening(),this.triggerMethod("close"),this.unbind()}}),f.Region=function(a){if(this.options=a||{},this.el=f.getOption(this,"el"),!this.el){var b=new Error("An 'el' must be specified for a region.");throw b.name="NoElError",b}if(this.initialize){var c=Array.prototype.slice.apply(arguments);this.initialize.apply(this,c)}},c.extend(f.Region,{buildRegion:function(a,b){var d="string"==typeof a,e="string"==typeof a.selector,f="undefined"==typeof a.regionType,g="function"==typeof a;if(!g&&!d&&!e)throw new Error("Region must be specified as a Region type, a selector string or an object with selector property");var h,i;d&&(h=a),a.selector&&(h=a.selector),g&&(i=a),!g&&f&&(i=b),a.regionType&&(i=a.regionType);var j=new i({el:h});return a.parentEl&&(j.getEl=function(b){var d=a.parentEl;return c.isFunction(d)&&(d=d()),d.find(b)}),j}}),c.extend(f.Region.prototype,b.Events,{show:function(a){this.ensureEl();var b=a.isClosed||c.isUndefined(a.$el),d=a!==this.currentView;d&&this.close(),a.render(),(d||b)&&this.open(a),this.currentView=a,f.triggerMethod.call(this,"show",a),f.triggerMethod.call(a,"show")},ensureEl:function(){this.$el&&0!==this.$el.length||(this.$el=this.getEl(this.el))},getEl:function(a){return f.$(a)},open:function(a){this.$el.empty().append(a.el)},close:function(){var a=this.currentView;a&&!a.isClosed&&(a.close?a.close():a.remove&&a.remove(),f.triggerMethod.call(this,"close"),delete this.currentView)},attachView:function(a){this.currentView=a},reset:function(){this.close(),delete this.$el}}),f.Region.extend=f.extend,f.RegionManager=function(a){var b=a.Controller.extend({constructor:function(b){this._regions={},a.Controller.prototype.constructor.call(this,b)},addRegions:function(a,b){var d={};return c.each(a,function(a,e){"string"==typeof a&&(a={selector:a}),a.selector&&(a=c.defaults({},a,b));var f=this.addRegion(e,a);d[e]=f},this),d},addRegion:function(b,d){var e,f=c.isObject(d),g=c.isString(d),h=!!d.selector;return e=g||f&&h?a.Region.buildRegion(d,a.Region):c.isFunction(d)?a.Region.buildRegion(d,a.Region):d,this._store(b,e),this.triggerMethod("region:add",b,e),e},get:function(a){return this._regions[a]},removeRegion:function(a){var b=this._regions[a];this._remove(a,b)},removeRegions:function(){c.each(this._regions,function(a,b){this._remove(b,a)},this)},closeRegions:function(){c.each(this._regions,function(a){a.close()},this)},close:function(){this.removeRegions();var b=Array.prototype.slice.call(arguments);a.Controller.prototype.close.apply(this,b)},_store:function(a,b){this._regions[a]=b,this._setLength()},_remove:function(a,b){b.close(),delete this._regions[a],this._setLength(),this.triggerMethod("region:remove",a,b)},_setLength:function(){this.length=c.size(this._regions)}}),d=["forEach","each","map","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","toArray","first","initial","rest","last","without","isEmpty","pluck"];return c.each(d,function(a){b.prototype[a]=function(){var b=c.values(this._regions),d=[b].concat(c.toArray(arguments));return c[a].apply(c,d)}}),b}(f),f.TemplateCache=function(a){this.templateId=a},c.extend(f.TemplateCache,{templateCaches:{},get:function(a){var b=this.templateCaches[a];return b||(b=new f.TemplateCache(a),this.templateCaches[a]=b),b.load()},clear:function(){var a,b=d(arguments),c=b.length;if(c>0)for(a=0;c>a;a++)delete this.templateCaches[b[a]];else this.templateCaches={}}}),c.extend(f.TemplateCache.prototype,{load:function(){if(this.compiledTemplate)return this.compiledTemplate;var a=this.loadTemplate(this.templateId);return this.compiledTemplate=this.compileTemplate(a),this.compiledTemplate},loadTemplate:function(a){var b=f.$(a).html();return b&&0!==b.length||e("Could not find template: '"+a+"'","NoTemplateError"),b},compileTemplate:function(a){return c.template(a)}}),f.Renderer={render:function(a,b){if(!a){var c=new Error("Cannot render the template since it's false, null or undefined.");throw c.name="TemplateNotFoundError",c}var d;return d="function"==typeof a?a:f.TemplateCache.get(a),d(b)}},f.View=b.View.extend({constructor:function(a){c.bindAll(this,"render");var d=Array.prototype.slice.apply(arguments);b.View.prototype.constructor.apply(this,d),this.options=a||{},f.MonitorDOMRefresh(this),this.listenTo(this,"show",this.onShowCalled,this)},triggerMethod:f.triggerMethod,getTemplate:function(){return f.getOption(this,"template")},mixinTemplateHelpers:function(a){a=a||{};var b=f.getOption(this,"templateHelpers");return c.isFunction(b)&&(b=b.call(this)),c.extend(a,b)},configureTriggers:function(){if(this.triggers){var a={},b=c.result(this,"triggers");return c.each(b,function(b,d){var e=c.isObject(b),f=e?b.event:b;a[d]=function(a){if(a){var c=a.preventDefault,d=a.stopPropagation,g=e?b.preventDefault:c,h=e?b.stopPropagation:d;g&&c&&c.apply(a),h&&d&&d.apply(a)}var i={view:this,model:this.model,collection:this.collection};this.triggerMethod(f,i)}},this),a}},delegateEvents:function(a){this._delegateDOMEvents(a),f.bindEntityEvents(this,this.model,f.getOption(this,"modelEvents")),f.bindEntityEvents(this,this.collection,f.getOption(this,"collectionEvents"))},_delegateDOMEvents:function(a){a=a||this.events,c.isFunction(a)&&(a=a.call(this));var d={},e=this.configureTriggers();c.extend(d,a,e),b.View.prototype.delegateEvents.call(this,d)},undelegateEvents:function(){var a=Array.prototype.slice.call(arguments);b.View.prototype.undelegateEvents.apply(this,a),f.unbindEntityEvents(this,this.model,f.getOption(this,"modelEvents")),f.unbindEntityEvents(this,this.collection,f.getOption(this,"collectionEvents"))},onShowCalled:function(){},close:function(){if(!this.isClosed){var a=this.triggerMethod("before:close");a!==!1&&(this.isClosed=!0,this.triggerMethod("close"),this.unbindUIElements(),this.remove())}},bindUIElements:function(){if(this.ui){this._uiBindings||(this._uiBindings=this.ui);var a=c.result(this,"_uiBindings");this.ui={},c.each(c.keys(a),function(b){var c=a[b];this.ui[b]=this.$(c)},this)}},unbindUIElements:function(){this.ui&&this._uiBindings&&(c.each(this.ui,function(a,b){delete this.ui[b]},this),this.ui=this._uiBindings,delete this._uiBindings)}}),f.ItemView=f.View.extend({constructor:function(){f.View.prototype.constructor.apply(this,d(arguments))},serializeData:function(){var a={};return this.model?a=this.model.toJSON():this.collection&&(a={items:this.collection.toJSON()}),a},render:function(){this.isClosed=!1,this.triggerMethod("before:render",this),this.triggerMethod("item:before:render",this);var a=this.serializeData();a=this.mixinTemplateHelpers(a);var b=this.getTemplate(),c=f.Renderer.render(b,a);return this.$el.html(c),this.bindUIElements(),this.triggerMethod("render",this),this.triggerMethod("item:rendered",this),this},close:function(){this.isClosed||(this.triggerMethod("item:before:close"),f.View.prototype.close.apply(this,d(arguments)),this.triggerMethod("item:closed"))}}),f.CollectionView=f.View.extend({itemViewEventPrefix:"itemview",constructor:function(){this._initChildViewStorage(),f.View.prototype.constructor.apply(this,d(arguments)),this._initialEvents()},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this.addChildView,this),this.listenTo(this.collection,"remove",this.removeItemView,this),this.listenTo(this.collection,"reset",this.render,this))},addChildView:function(a){this.closeEmptyView();var b=this.getItemView(a),c=this.collection.indexOf(a);this.addItemView(a,b,c)},onShowCalled:function(){this.children.each(function(a){f.triggerMethod.call(a,"show")})},triggerBeforeRender:function(){this.triggerMethod("before:render",this),this.triggerMethod("collection:before:render",this)},triggerRendered:function(){this.triggerMethod("render",this),this.triggerMethod("collection:rendered",this)},render:function(){return this.isClosed=!1,this.triggerBeforeRender(),this._renderChildren(),this.triggerRendered(),this},_renderChildren:function(){this.closeEmptyView(),this.closeChildren(),this.collection&&this.collection.length>0?this.showCollection():this.showEmptyView()},showCollection:function(){var a;this.collection.each(function(b,c){a=this.getItemView(b),this.addItemView(b,a,c)},this)},showEmptyView:function(){var a=this.getEmptyView();if(a&&!this._showingEmptyView){this._showingEmptyView=!0;var c=new b.Model;this.addItemView(c,a,0)}},closeEmptyView:function(){this._showingEmptyView&&(this.closeChildren(),delete this._showingEmptyView)},getEmptyView:function(){return f.getOption(this,"emptyView")},getItemView:function(){var a=f.getOption(this,"itemView");return a||e("An `itemView` must be specified","NoItemViewError"),a},addItemView:function(a,b,d){var e=f.getOption(this,"itemViewOptions");c.isFunction(e)&&(e=e.call(this,a,d));var g=this.buildItemView(a,b,e);this.addChildViewEventForwarding(g),this.triggerMethod("before:item:added",g),this.children.add(g),this.renderItemView(g,d),this._isShown&&f.triggerMethod.call(g,"show"),this.triggerMethod("after:item:added",g)},addChildViewEventForwarding:function(a){var b=f.getOption(this,"itemViewEventPrefix");this.listenTo(a,"all",function(){var c=d(arguments);c[0]=b+":"+c[0],c.splice(1,0,a),f.triggerMethod.apply(this,c)},this)},renderItemView:function(a,b){a.render(),this.appendHtml(this,a,b)},buildItemView:function(a,b,d){var e=c.extend({model:a},d);return new b(e)},removeItemView:function(a){var b=this.children.findByModel(a);this.removeChildView(b),this.checkEmpty()},removeChildView:function(a){a&&(this.stopListening(a),a.close?a.close():a.remove&&a.remove(),this.children.remove(a)),this.triggerMethod("item:removed",a)},checkEmpty:function(){this.collection&&0!==this.collection.length||this.showEmptyView()},appendHtml:function(a,b){a.$el.append(b.el)},_initChildViewStorage:function(){this.children=new b.ChildViewContainer},close:function(){this.isClosed||(this.triggerMethod("collection:before:close"),this.closeChildren(),this.triggerMethod("collection:closed"),f.View.prototype.close.apply(this,d(arguments)))},closeChildren:function(){this.children.each(function(a){this.removeChildView(a)},this),this.checkEmpty()}}),f.CompositeView=f.CollectionView.extend({constructor:function(){f.CollectionView.prototype.constructor.apply(this,d(arguments))},_initialEvents:function(){this.collection&&(this.listenTo(this.collection,"add",this.addChildView,this),this.listenTo(this.collection,"remove",this.removeItemView,this),this.listenTo(this.collection,"reset",this._renderChildren,this))},getItemView:function(){var a=f.getOption(this,"itemView")||this.constructor;return a||e("An `itemView` must be specified","NoItemViewError"),a},serializeData:function(){var a={};return this.model&&(a=this.model.toJSON()),a},render:function(){this.isRendered=!0,this.isClosed=!1,this.resetItemViewContainer(),this.triggerBeforeRender();var a=this.renderModel();return this.$el.html(a),this.bindUIElements(),this.triggerMethod("composite:model:rendered"),this._renderChildren(),this.triggerMethod("composite:rendered"),this.triggerRendered(),this},_renderChildren:function(){this.isRendered&&(f.CollectionView.prototype._renderChildren.call(this),this.triggerMethod("composite:collection:rendered"))},renderModel:function(){var a={};a=this.serializeData(),a=this.mixinTemplateHelpers(a);var b=this.getTemplate();return f.Renderer.render(b,a)},appendHtml:function(a,b){var c=this.getItemViewContainer(a);c.append(b.el)},getItemViewContainer:function(a){if("$itemViewContainer"in a)return a.$itemViewContainer;var b,d=f.getOption(a,"itemViewContainer");if(d){var g=c.isFunction(d)?d():d;b=a.$(g),b.length<=0&&e("The specified `itemViewContainer` was not found: "+a.itemViewContainer,"ItemViewContainerMissingError")}else b=a.$el;return a.$itemViewContainer=b,b},resetItemViewContainer:function(){this.$itemViewContainer&&delete this.$itemViewContainer}}),f.Layout=f.ItemView.extend({regionType:f.Region,constructor:function(a){a=a||{},this._firstRender=!0,this._initializeRegions(a),f.ItemView.prototype.constructor.call(this,a)},render:function(){this.isClosed&&this._initializeRegions(),this._firstRender?this._firstRender=!1:this.isClosed||this._reInitializeRegions();var a=Array.prototype.slice.apply(arguments),b=f.ItemView.prototype.render.apply(this,a);return b},close:function(){if(!this.isClosed){this.regionManager.close();var a=Array.prototype.slice.apply(arguments);f.ItemView.prototype.close.apply(this,a)}},addRegion:function(a,b){var c={};return c[a]=b,this._buildRegions(c)[a]},addRegions:function(a){return this.regions=c.extend({},this.regions,a),this._buildRegions(a)},removeRegion:function(a){return delete this.regions[a],this.regionManager.removeRegion(a)},_buildRegions:function(a){var b=this,c={regionType:f.getOption(this,"regionType"),parentEl:function(){return b.$el}};return this.regionManager.addRegions(a,c)},_initializeRegions:function(a){var b;this._initRegionManager(),b=c.isFunction(this.regions)?this.regions(a):this.regions||{},this.addRegions(b)},_reInitializeRegions:function(){this.regionManager.closeRegions(),this.regionManager.each(function(a){a.reset()})},_initRegionManager:function(){this.regionManager=new f.RegionManager,this.listenTo(this.regionManager,"region:add",function(a,b){this[a]=b,this.trigger("region:add",a,b)}),this.listenTo(this.regionManager,"region:remove",function(a,b){delete this[a],this.trigger("region:remove",a,b)})}}),f.AppRouter=b.Router.extend({constructor:function(a){b.Router.prototype.constructor.apply(this,d(arguments)),this.options=a||{};var c=f.getOption(this,"appRoutes"),e=this._getController();this.processAppRoutes(e,c)},appRoute:function(a,b){var c=this._getController();this._addAppRoute(c,a,b)},processAppRoutes:function(a,b){if(b){var d=c.keys(b).reverse();c.each(d,function(c){this._addAppRoute(a,c,b[c])},this)}},_getController:function(){return f.getOption(this,"controller")},_addAppRoute:function(a,b,d){var e=a[d];if(!e)throw new Error("Method '"+d+"' was not found on the controller");this.route(b,d,c.bind(e,a))}}),f.Application=function(a){this._initRegionManager(),this._initCallbacks=new f.Callbacks,this.vent=new b.Wreqr.EventAggregator,this.commands=new b.Wreqr.Commands,this.reqres=new b.Wreqr.RequestResponse,this.submodules={},c.extend(this,a),this.triggerMethod=f.triggerMethod},c.extend(f.Application.prototype,b.Events,{execute:function(){var a=Array.prototype.slice.apply(arguments);this.commands.execute.apply(this.commands,a)},request:function(){var a=Array.prototype.slice.apply(arguments);return this.reqres.request.apply(this.reqres,a)},addInitializer:function(a){this._initCallbacks.add(a)},start:function(a){this.triggerMethod("initialize:before",a),this._initCallbacks.run(a,this),this.triggerMethod("initialize:after",a),this.triggerMethod("start",a)},addRegions:function(a){return this._regionManager.addRegions(a)},closeRegions:function(){this._regionManager.closeRegions()},removeRegion:function(a){this._regionManager.removeRegion(a)},getRegion:function(a){return this._regionManager.get(a)},module:function(){var a=d(arguments);return a.unshift(this),f.Module.create.apply(f.Module,a)},_initRegionManager:function(){this._regionManager=new f.RegionManager,this.listenTo(this._regionManager,"region:add",function(a,b){this[a]=b}),this.listenTo(this._regionManager,"region:remove",function(a){delete this[a]})}}),f.Application.extend=f.extend,f.Module=function(a,b){this.moduleName=a,this.submodules={},this._setupInitializersAndFinalizers(),this.app=b,this.startWithParent=!0,this.triggerMethod=f.triggerMethod},c.extend(f.Module.prototype,b.Events,{addInitializer:function(a){this._initializerCallbacks.add(a)},addFinalizer:function(a){this._finalizerCallbacks.add(a)},start:function(a){this._isInitialized||(c.each(this.submodules,function(b){b.startWithParent&&b.start(a)}),this.triggerMethod("before:start",a),this._initializerCallbacks.run(a,this),this._isInitialized=!0,this.triggerMethod("start",a))},stop:function(){this._isInitialized&&(this._isInitialized=!1,f.triggerMethod.call(this,"before:stop"),c.each(this.submodules,function(a){a.stop()}),this._finalizerCallbacks.run(void 0,this),this._initializerCallbacks.reset(),this._finalizerCallbacks.reset(),f.triggerMethod.call(this,"stop"))},addDefinition:function(a,b){this._runModuleDefinition(a,b)},_runModuleDefinition:function(a,d){if(a){var e=c.flatten([this,this.app,b,f,f.$,c,d]);a.apply(this,e)}},_setupInitializersAndFinalizers:function(){this._initializerCallbacks=new f.Callbacks,this._finalizerCallbacks=new f.Callbacks}}),c.extend(f.Module,{create:function(a,b,e){var f=a,g=d(arguments);g.splice(0,3),b=b.split(".");var h=b.length,i=[];return i[h-1]=e,c.each(b,function(b,c){var d=f;f=this._getModule(d,b,a),this._addModuleDefinition(d,f,i[c],g)},this),f},_getModule:function(a,b,c){var d=a[b];return d||(d=new f.Module(b,c),a[b]=d,a.submodules[b]=d),d},_addModuleDefinition:function(a,b,d,e){var f,g;c.isFunction(d)?(f=d,g=!0):c.isObject(d)?(f=d.define,g=d.startWithParent):g=!0,f&&b.addDefinition(f,e),b.startWithParent=b.startWithParent&&g,b.startWithParent&&!b.startWithParentIsConfigured&&(b.startWithParentIsConfigured=!0,a.addInitializer(function(a){b.startWithParent&&b.start(a)}))}}),f}(this,Backbone,_); +//# sourceMappingURL=backbone.marionette.map \ No newline at end of file diff --git a/sonar-server/src/main/webapp/stylesheets/mixins.css b/sonar-server/src/main/webapp/stylesheets/mixins.css new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sonar-server/src/main/webapp/stylesheets/mixins.less b/sonar-server/src/main/webapp/stylesheets/mixins.less new file mode 100644 index 00000000000..31e7542d8c4 --- /dev/null +++ b/sonar-server/src/main/webapp/stylesheets/mixins.less @@ -0,0 +1,154 @@ +.clearfix() { + &:before, &:after { display: table; content: ""; line-height: 0; } + &:after { clear: both; } +} + +.size(@width, @height) { + width: @width; + height: @height; +} + +.square(@size) { + .size(@size, @size); +} + +.topLeft(@top, @left) { + top: @top; + left: @left; +} + +.topRight(@top, @right) { + top: @top; + right: @right; +} + +.bottomLeft(@bottom, @left) { + bottom: @bottom; + left: @left; +} + +.bottomRight(@bottom, @right) { + bottom: @bottom; + right: @left; +} + +.rotate(@degrees) { + -webkit-transform: rotate(@degrees); + -ms-transform: rotate(@degrees); + transform: rotate(@degrees); +} +.scale(@ratio) { + -webkit-transform: scale(@ratio); + -ms-transform: scale(@ratio); + transform: scale(@ratio); +} +.scale2(@w, @h) { + -webkit-transform: scale(@w, @h); + -ms-transform: scale(@w, @h); + transform: scale(@w, @h); +} +.translate(@x, @y) { + -webkit-transform: translate(@x, @y); + -ms-transform: translate(@x, @y); + transform: translate(@x, @y); +} +.skew(@x, @y) { + -webkit-transform: skew(@x, @y); + -ms-transform: skew(@x, @y); + transform: skew(@x, @y); +} +.translate3d(@x, @y, @z) { + -webkit-transform: translate3d(@x, @y, @z); + transform: translate3d(@x, @y, @z); +} + +.box-sizing(@boxmodel) { + -moz-box-sizing: @boxmodel; + box-sizing: @boxmodel; +} + +.horizontal-gradient(@startColor: #555, @endColor: #333) { + background-color: @endColor; + background-image: -moz-linear-gradient(left, @startColor, @endColor); // FF 3.6+ + background-image: -webkit-gradient(linear, 0 0, 100% 0, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(left, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(left, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(to right, @startColor, @endColor); // Standard, IE10 + background-repeat: repeat-x; +} +.vertical-gradient(@startColor: #555, @endColor: #333) { + background-color: mix(@startColor, @endColor, 60%); + background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+ + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+ + background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(to bottom, @startColor, @endColor); // Standard, IE10 + background-repeat: repeat-x; +} +.directional-gradient(@startColor: #555, @endColor: #333, @deg: 45deg) { + background-color: @endColor; + background-repeat: repeat-x; + background-image: -moz-linear-gradient(@deg, @startColor, @endColor); // FF 3.6+ + background-image: -webkit-linear-gradient(@deg, @startColor, @endColor); // Safari 5.1+, Chrome 10+ + background-image: -o-linear-gradient(@deg, @startColor, @endColor); // Opera 11.10 + background-image: linear-gradient(@deg, @startColor, @endColor); // Standard, IE10 +} +.vertical-three-colors-gradient(@startColor: #00b3ee, @midColor: #7a43b6, @colorStop: 50%, @endColor: #c3325f) { + background-color: mix(@midColor, @endColor, 80%); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), color-stop(@colorStop, @midColor), to(@endColor)); + background-image: -webkit-linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-image: -moz-linear-gradient(top, @startColor, @midColor @colorStop, @endColor); + background-image: -o-linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-image: linear-gradient(@startColor, @midColor @colorStop, @endColor); + background-repeat: no-repeat; +} +.radial-gradient(@innerColor: #555, @outerColor: #333) { + background-color: @outerColor; + background-image: -webkit-gradient(radial, center center, 0, center center, 460, from(@innerColor), to(@outerColor)); + background-image: -webkit-radial-gradient(circle, @innerColor, @outerColor); + background-image: -moz-radial-gradient(circle, @innerColor, @outerColor); + background-image: -o-radial-gradient(circle, @innerColor, @outerColor); + background-repeat: no-repeat; +} +.striped-gradient(@color, @angle: 45deg) { + background-color: @color; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, rgba(255,255,255,.15)), color-stop(.25, transparent), color-stop(.5, transparent), color-stop(.5, rgba(255,255,255,.15)), color-stop(.75, rgba(255,255,255,.15)), color-stop(.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(@angle, rgba(255,255,255,.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.15) 50%, rgba(255,255,255,.15) 75%, transparent 75%, transparent); +} + +.webkit-scrollbar() { + &::-webkit-scrollbar { + width: 11px; + background-color: transparent; + background-clip: content-box; + } + &::-webkit-scrollbar-button { + background-color: transparent; + } + &::-webkit-scrollbar-corner { + background-color: transparent; + } + &::-webkit-scrollbar-thumb { + border: solid transparent; + border-width: 1px 1px 1px 2px; + background-color: #c5c5c5; + background-clip: content-box; + + &:hover { + background-color: darken(#ccc, 5%); + } + } + &::-webkit-scrollbar-track { + border: solid #fff; + border-width: 1px 1px 1px 2px; + background-color: #fff; + background-clip: content-box; + } + &::-webkit-scrollbar-track-piece { + border-left: 1px solid #ccc; + background-color: transparent; + } +} diff --git a/sonar-server/src/main/webapp/stylesheets/navigator.css b/sonar-server/src/main/webapp/stylesheets/navigator.css new file mode 100644 index 00000000000..7541faff673 --- /dev/null +++ b/sonar-server/src/main/webapp/stylesheets/navigator.css @@ -0,0 +1,81 @@ +/* + * Colors + */ +.navigator .select2-container .select2-choice, +.navigator .select2-container-multi .select2-choices { + border: 1px solid #aaa; + border-radius: 0; + background: #ffffff; +} +.navigator .select2-container-active .select2-choice, +.navigator .select2-container-active .select2-choices { + box-shadow: none; +} +.navigator .select2-container-multi .select2-choices { + white-space: nowrap; +} +.navigator .select2-container-multi .select2-choices li { + float: none; + display: inline-block; + vertical-align: middle; +} +.navigator-filters { + margin-bottom: 10px; + padding: 10px; + border: 1px solid #cdcdcd; + background: #efefef; + font-size: 0; +} +.navigator-filters-favorite { + display: inline-block; + vertical-align: middle; + margin-right: 15px; + padding-right: 14px; + border-right: 1px solid #cdcdcd; +} +.navigator-filters-favorite-toggle { + display: block; + width: 16px; + height: 16px; + background: url(../images/star.png) no-repeat left center; + cursor: pointer; +} +.navigator-filters-list { + display: inline-block; + vertical-align: middle; + font-size: 0; +} +input.navigator-filters-search[type=submit] { + display: inline-block; + vertical-align: middle; + margin-left: 20px; +} +.navigator-filter { + display: inline-block; + vertical-align: top; +} +.navigator-filter + .navigator-filter { + margin-left: 20px; +} +.navigator-filter-label { + display: inline-block; + vertical-align: middle; + margin-right: 5px; + color: #666; + font-size: 14px; +} +.navigator-filter-label:after { + content: ":"; +} +.navigator-filter-body { + display: inline-block; + vertical-align: middle; + color: #000; + font-size: 14px; +} +.navigator-filter-body input { + font-size: 12px; +} +.navigator-filter-range-input { + width: 80px; +} diff --git a/sonar-server/src/main/webapp/stylesheets/navigator.less b/sonar-server/src/main/webapp/stylesheets/navigator.less new file mode 100644 index 00000000000..5903791c4c5 --- /dev/null +++ b/sonar-server/src/main/webapp/stylesheets/navigator.less @@ -0,0 +1,103 @@ +@import "mixins"; +@import "variables"; + +.navigator { + + .select2-container .select2-choice, + .select2-container-multi .select2-choices { + border: 1px solid #aaa; + border-radius: 0; + background: @white; + } + + .select2-container-active .select2-choice, + .select2-container-active .select2-choices { + box-shadow: none; + } + + .select2-container-multi .select2-choices { + white-space: nowrap; + } + + .select2-container-multi .select2-choices li { + float: none; + display: inline-block; + vertical-align: middle; + } + +} + +.navigator-filters { + margin-bottom: 10px; + padding: 10px; + border: 1px solid @darkGrey; + background: @grey; + font-size: 0; +} + +.navigator-filters-favorite { + display: inline-block; + vertical-align: middle; + margin-right: 15px; + padding-right: 14px; + border-right: 1px solid #cdcdcd; +} + +.navigator-filters-favorite-toggle { + display: block; + .size(16px, 16px); + background: url(../images/star.png) no-repeat left center; + cursor: pointer; +} + +.navigator-filters-list { + display: inline-block; + vertical-align: middle; + font-size: 0; +} + +input.navigator-filters-search[type=submit] { + display: inline-block; + vertical-align: middle; + margin-left: 20px; +} + +.navigator-filter { + display: inline-block; + vertical-align: top; +} + +.navigator-filter + .navigator-filter { + margin-left: 20px; +// padding-left: 14px; +// border-left: 1px solid @darkGrey; +} + +.navigator-filter-label { + display: inline-block; + vertical-align: middle; + margin-right: 5px; + color: #666; + font-size: 14px; + + &:after { content: ":"; } +} + +.navigator-filter-body { + display: inline-block; + vertical-align: middle; + color: #000; + font-size: 14px; + + input { + font-size: 12px; + } +} + +.navigator-filter-range-input { + width: 80px; +} + +.navigator-results { + +} diff --git a/sonar-server/src/main/webapp/stylesheets/variables.css b/sonar-server/src/main/webapp/stylesheets/variables.css new file mode 100644 index 00000000000..cf549c1e46d --- /dev/null +++ b/sonar-server/src/main/webapp/stylesheets/variables.css @@ -0,0 +1,3 @@ +/* + * Colors + */ diff --git a/sonar-server/src/main/webapp/stylesheets/variables.less b/sonar-server/src/main/webapp/stylesheets/variables.less new file mode 100644 index 00000000000..80028758a9c --- /dev/null +++ b/sonar-server/src/main/webapp/stylesheets/variables.less @@ -0,0 +1,8 @@ +/* + * Colors + */ + +@black: #000000; +@white: #ffffff; +@grey: #efefef; +@darkGrey: #cdcdcd; diff --git a/sonar-server/wro.xml b/sonar-server/wro.xml index f1d1929e746..a5272ad6db0 100644 --- a/sonar-server/wro.xml +++ b/sonar-server/wro.xml @@ -11,6 +11,7 @@ /stylesheets/sonar-colorizer.css /stylesheets/dashboard.css /stylesheets/select-list.css + /stylesheets/navigator.css /javascripts/third-party/prototype.js /javascripts/third-party/scriptaculous.js @@ -20,6 +21,7 @@ /javascripts/third-party/d3.v3.min.js /javascripts/third-party/underscore-min.js /javascripts/third-party/backbone-min.js + /javascripts/third-party/backbone.marionette.min.js /javascripts/third-party/jquery.ba-throttle-debounce.min.js /javascripts/third-party/select2.min.js @@ -28,6 +30,10 @@ /javascripts/widgets/stack-area.js /javascripts/select-list.js + + /javascripts/navigator/filters.js + /javascripts/navigator/app.js + /javascripts/application.js /javascripts/dashboard.js /javascripts/duplication.js -- 2.39.5