]> source.dussan.org Git - sonarqube.git/commitdiff
New Issues Page: Load saved filters
authorStas Vilchik <vilchiks@gmail.com>
Thu, 16 Jan 2014 08:02:27 +0000 (14:02 +0600)
committerStas Vilchik <vilchiks@gmail.com>
Thu, 16 Jan 2014 08:02:38 +0000 (14:02 +0600)
13 files changed:
sonar-server/src/main/webapp/WEB-INF/app/views/issues/search2.html.erb
sonar-server/src/main/webapp/WEB-INF/app/views/issues/templates/_header.hbs.erb [new file with mode: 0644]
sonar-server/src/main/webapp/WEB-INF/app/views/issues/templates/_issues_details_favorite_filter.hbs.erb [new file with mode: 0644]
sonar-server/src/main/webapp/javascripts/navigator/filters/ajax-select-filters.js
sonar-server/src/main/webapp/javascripts/navigator/filters/base-filters.js
sonar-server/src/main/webapp/javascripts/navigator/filters/favorite-filters.js
sonar-server/src/main/webapp/javascripts/navigator/filters/select-filters.js
sonar-server/src/main/webapp/javascripts/navigator/issues-app.js
sonar-server/src/main/webapp/javascripts/navigator/issues.js
sonar-server/src/main/webapp/stylesheets/navigator.css
sonar-server/src/main/webapp/stylesheets/navigator/base.css
sonar-server/src/main/webapp/stylesheets/navigator/base.less
sonar-server/src/main/webapp/stylesheets/variables.less

index 81a1393186a5aa8c4e3dcceda8d337f31da27d54..5ff347b151bc2c775af5b3699c3c4d5cdc88d99c 100644 (file)
@@ -1,28 +1,22 @@
 <div class="navigator">
-
-  <div class="navigator-header">
-    <h1 class="navigator-header-title">Issues</h1>
-  </div>
-
+  <div class="navigator-header"></div>
   <div class="navigator-filters"></div>
   <div class="navigator-results"></div>
   <div class="navigator-details"></div>
-
   <div class="navigator-actions"></div>
-
 </div>
 
-
 <script id="filterBarTemplate" type="text/template">
   <div class="navigator-filters-list"></div>
   <button class="navigator-filter-submit"><%= message('search_verb') -%></button>
 </script>
 
 <%= render :partial => '/navigator/filter_templates' -%>
+<%= render :partial => '/issues/templates/header.hbs' -%>
 <%= render :partial => '/issues/templates/issue.hbs' -%>
 <%= render :partial => '/issues/templates/issues_actions.hbs' -%>
 <%= render :partial => '/issues/templates/no_issues.hbs' -%>
-
+<%= render :partial => '/issues/templates/issues_details_favorite_filter.hbs' -%>
 
 <script>
   _.templateSettings = {
@@ -41,7 +35,6 @@
       'any':           '<%= escape_javascript message('any') -%>',
       'anytime':       '<%= escape_javascript message('anytime') -%>',
       'all':           '<%= escape_javascript message('all') -%>',
-      'manage':        '<%= escape_javascript message('manage') -%>',
       'to':            '<%= escape_javascript message('to') -%>',
       'project':       '<%= escape_javascript message('issue_filter.criteria.project') -%>',
       'severity':      '<%= escape_javascript message('issue_filter.criteria.severity') -%>',
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/templates/_header.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/templates/_header.hbs.erb
new file mode 100644 (file)
index 0000000..4ab7782
--- /dev/null
@@ -0,0 +1,11 @@
+<script id="issues-header-template" type="text/x-handlebars-template">
+  <h1 class="navigator-header-title">{{#if name}}{{name}}{{else}}<%= message ('issues') -%>{{/if}}</h1>
+
+  <div class="navigator-header-actions">
+    <button id="issues-new-search"><%= message ('issue_filter.new_search') -%></button>
+    {{#if canSave}}<button id="issues-filter-save"><%= message('save') -%></button>{{/if}}
+    {{#if canSaveAs}}<button id="issues-filter-save-as"><%= message('save_as') -%></button>{{/if}}
+    {{#if canCopy}}<button id="issues-filter-copy"><%= message('copy') -%></button>{{/if}}
+    {{#if canEdit}}<button id="issues-filter-edit"><%= message('edit') -%></button>{{/if}}
+  </div>
+</script>
diff --git a/sonar-server/src/main/webapp/WEB-INF/app/views/issues/templates/_issues_details_favorite_filter.hbs.erb b/sonar-server/src/main/webapp/WEB-INF/app/views/issues/templates/_issues_details_favorite_filter.hbs.erb
new file mode 100644 (file)
index 0000000..22d0b4a
--- /dev/null
@@ -0,0 +1,13 @@
+<script id="issues-details-favorite-filter-template" type="text/x-handlebars-template">
+  <ul class="navigator-filter-select-list">
+    {{#each items}}
+      <li>
+        <label data-id="{{id}}">{{{name}}}</label>
+      </li>
+    {{/each}}
+    <li class="line"></li>
+    <li class="manage">
+      <label id="manage-favorites"><%= message('manage') -%></label>
+    </li>
+  </ul>
+</script>
index 595354bb4ca38df58e01ac4c9146119097e35b02..c68c8aaad9f15801f4c151a78b588f722af7d8b1 100644 (file)
@@ -209,12 +209,20 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
 
       if (this.choices && this.selection && value.length > 0) {
         this.selection.reset([]);
+        this.model.set({
+          value: value,
+          enabled: true
+        }, {
+          silent: true
+        });
 
         if (_.isArray(param.text) && param.text.length === value.length) {
           this.restoreFromText(value, param.text);
         } else {
           this.restoreByRequests(value);
         }
+      } else {
+        this.clear();
       }
     },
 
@@ -245,12 +253,16 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
 
     onRestore: function(value) {
       this.detailsView.updateLists();
-      this.model.set({
-        value: value,
-        enabled: true
-      }, {
-        silent: true
-      });
+      this.renderBase();
+    },
+
+
+    clear: function() {
+      this.model.unset('value');
+      if (this.selection && this.choices) {
+        this.choices.reset([]);
+        this.selection.reset([]);
+      }
       this.renderBase();
     },
 
@@ -300,8 +312,8 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
         detailsView: AjaxSelectDetailsFilterView
       });
 
-      this.selection = new ProjectSuggestions();
-      this.choices = new ProjectSuggestions();
+      this.selection = new ComponentSuggestions();
+      this.choices = new ComponentSuggestions();
     },
 
 
index 1d177b58ff7dcbb3073362594df74605271ca9d9..b7cf7201ea9b06da28510029108b0c67172c7543 100644 (file)
@@ -164,6 +164,8 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
       var param = _.findWhere(q, { key: this.model.get('property') });
       if (param && param.value) {
         this.restore(param.value, param);
+      } else {
+        this.clear();
       }
     },
 
@@ -174,6 +176,11 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
     },
 
 
+    clear: function() {
+      this.model.unset('value');
+    },
+
+
     disable: function(e) {
       e.stopPropagation();
       this.hideDetails();
@@ -222,7 +229,8 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
 
     itemViewOptions: function() {
       return {
-        filterBarView: this
+        filterBarView: this,
+        app: this.options.app
       };
     },
 
@@ -249,7 +257,8 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
     render: function() {
       Backbone.Marionette.CompositeView.prototype.render.apply(this, arguments);
 
-      if (this.collection.where({ type: window.SS.FavoriteFilterView }).length > 0) {
+      if (this.collection.where({ type: window.SS.FavoriteFilterView }).length > 0 ||
+          this.collection.where({ type: window.SS.IssuesFavoriteFilterView }).length > 0) {
         this.$el.addClass('navigator-filter-list-favorite');
       }
     },
index 39d861b8a2e523b8c3ef1af2e79118423a0aa5b9..04bfde2afb2c03084c13339d3ae469c0c8292966 100644 (file)
@@ -76,6 +76,7 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
    */
 
   _.extend(window.SS, {
+    DetailsFavoriteFilterView: DetailsFavoriteFilterView,
     FavoriteFilterView: FavoriteFilterView
   });
 
index d4e54059f4bc90ef94a83deba06a08dc3c45b7d0..f14ca27f83921dee2d41f83fd0c9e6d2d807742d 100644 (file)
@@ -287,7 +287,22 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
         });
 
         this.renderBase();
+      } else {
+        this.clear();
+      }
+    },
+
+
+    clear: function() {
+      var that = this;
+      this.model.unset('value');
+      if (this.selection && this.choices) {
+        this.selection.each(function(m) {
+          that.choices.add(m);
+        });
+        this.selection.reset([]);
       }
+      this.renderBase();
     },
 
 
index b2e3ae5301baa83992ee1e40c8affc596039df4c..d47cca1947c555c8764bbe0eecea724e068f42fe 100644 (file)
@@ -10,6 +10,7 @@ jQuery(function() {
 
 
   NavigatorApp.addRegions({
+    headerRegion: '.navigator-header',
     filtersRegion: '.navigator-filters',
     resultsRegion: '.navigator-results',
     actionsRegion: '.navigator-actions'
@@ -20,6 +21,13 @@ jQuery(function() {
     this.issues = new window.SS.Issues();
     this.issuesPage = 1;
 
+    this.favoriteFilter = new window.SS.FavoriteFilter();
+    this.issuesHeaderView = new window.SS.IssuesHeaderView({
+      app: this,
+      model: this.favoriteFilter
+    });
+    this.headerRegion.show(this.issuesHeaderView);
+
     this.issuesView = new window.SS.IssuesView({
       collection: this.issues
     });
@@ -36,18 +44,6 @@ jQuery(function() {
   NavigatorApp.addInitializer(function() {
     this.filters = new window.SS.Filters();
 
-    if (_.isObject(window.SS.favorites)) {
-      this.filters.add([
-        new window.SS.Filter({
-          type: window.SS.FavoriteFilterView,
-          enabled: true,
-          optional: false,
-          choices: window.SS.favorites,
-          favoriteUrl: '/issues/filter',
-          manageUrl: '/issues/manage'
-        })]);
-    }
-
     this.filters.add([
       new window.SS.Filter({
         name: window.SS.phrases.project,
@@ -141,6 +137,20 @@ jQuery(function() {
     ]);
 
 
+    this.favoriteFilters = new window.SS.FavoriteFilters();
+    this.filters.unshift([
+      new window.SS.Filter({
+        type: window.SS.IssuesFavoriteFilterView,
+        enabled: true,
+        optional: false,
+        choices: this.favoriteFilters,
+        manageUrl: '/issues/manage'
+      })]);
+    this.favoriteFilters.fetch({
+      reset: true
+    });
+
+
     this.filterBarView = new window.SS.IssuesFilterBarView({
       app: this,
       collection: this.filters,
@@ -158,7 +168,12 @@ jQuery(function() {
     this.router = new window.SS.IssuesRouter({
       app: this
     });
-    Backbone.history.start()
+    Backbone.history.start();
+
+    var router = this.router;
+    this.favoriteFilter.on('change:query', function(model, query) {
+      router.navigate(query, { trigger: true });
+    });
   });
 
 
@@ -182,7 +197,7 @@ jQuery(function() {
 
     var queryString = _.map(fullQuery, function(v, k) {
       return [k, encodeURIComponent(v)].join('=');
-    }).join('&');
+    }).join('|');
     this.router.navigate(queryString);
   };
 
index 2bc0011f044b1f3395709a61174dbe1b7eb50bd1..fea1bebe48034559faab633bcfad5dbafaced6c1 100644 (file)
@@ -4,12 +4,7 @@ window.SS = typeof window.SS === 'object' ? window.SS : {};
 
 jQuery(function() {
 
-  var Issue = Backbone.Model.extend({
-
-  });
-
-
-
+  var Issue = Backbone.Model.extend({});
   var Issues = Backbone.Collection.extend({
     model: Issue,
 
@@ -40,6 +35,36 @@ jQuery(function() {
 
 
 
+  var FavoriteFilter = Backbone.Model.extend({
+
+    url: function() {
+      return baseUrl + '/api/issue_filters/show/' + this.get('id');
+    },
+
+
+    parse: function(r) {
+      return r.filter ? r.filter : r;
+    }
+  });
+
+
+
+  var FavoriteFilters = Backbone.Collection.extend({
+    model: FavoriteFilter,
+
+
+    url: function() {
+      return baseUrl + '/api/issue_filters/favorites';
+    },
+
+
+    parse: function(r) {
+      return r.favoriteFilters;
+    }
+  });
+
+
+
   var IssueView = Backbone.Marionette.ItemView.extend({
     template: Handlebars.compile(jQuery('#issue-template').html() || ''),
     tagName: 'li',
@@ -220,6 +245,69 @@ jQuery(function() {
 
 
 
+  var IssuesHeaderView = Backbone.Marionette.ItemView.extend({
+    template: Handlebars.compile(jQuery('#issues-header-template').html() || ''),
+
+
+    modelEvents: {
+      'change': 'render'
+    },
+
+
+    events: {
+      'click #issues-new-search': 'newSearch'
+    },
+
+
+    newSearch: function() {
+      this.options.app.router.navigate('', { trigger: true });
+    }
+
+  });
+
+
+
+  var IssuesDetailsFavoriteFilterView = window.SS.DetailsFavoriteFilterView.extend({
+    template: Handlebars.compile(jQuery('#issues-details-favorite-filter-template').html() || ''),
+
+
+    applyFavorite: function(e) {
+      var id = $j(e.target).data('id'),
+          filter = this.model.get('choices').get(id),
+          app = this.options.filterView.options.app;
+
+      filter.fetch({
+        success: function() {
+          app.favoriteFilter.set(filter.toJSON());
+        }
+      });
+
+      this.options.filterView.hideDetails();
+    },
+
+
+    serializeData: function() {
+      return _.extend({}, this.model.toJSON(), {
+        items: this.model.get('choices').toJSON()
+      });
+    }
+  });
+
+
+
+  var IssuesFavoriteFilterView = window.SS.FavoriteFilterView.extend({
+
+    initialize: function() {
+      window.SS.BaseFilterView.prototype.initialize.call(this, {
+        detailsView: IssuesDetailsFavoriteFilterView
+      });
+
+      this.listenTo(this.model.get('choices'), 'reset', this.render);
+    }
+  });
+
+
+
   var IssuesRouter = Backbone.Router.extend({
 
     routes: {
@@ -234,7 +322,7 @@ jQuery(function() {
 
 
     index: function(query) {
-      var params = (query || '').split('&').map(function(t) {
+      var params = (query || '').split('|').map(function(t) {
         return {
           key: t.split('=')[0],
           value: decodeURIComponent(t.split('=')[1])
@@ -255,10 +343,14 @@ jQuery(function() {
   _.extend(window.SS, {
     Issue: Issue,
     Issues: Issues,
+    FavoriteFilter: FavoriteFilter,
+    FavoriteFilters: FavoriteFilters,
     IssueView: IssueView,
     IssuesView: IssuesView,
     IssuesActionsView: IssuesActionsView,
     IssuesFilterBarView: IssuesFilterBarView,
+    IssuesHeaderView: IssuesHeaderView,
+    IssuesFavoriteFilterView: IssuesFavoriteFilterView,
     IssuesRouter: IssuesRouter
   });
 
index 456acc9d921a9d97cf93ee7f470cfa980726ef4a..ce63a7ec412d5d4c8b7d60dc599eef281d54e7c2 100644 (file)
   padding: 0 10px;
   border-bottom: 1px solid #cdcdcd;
   background-color: #efefef;
+  font-size: 0;
 }
 .navigator-header-title {
+  position: relative;
+  top: -2px;
+  display: inline-block;
+  vertical-align: middle;
   font-size: 20px;
   line-height: 34px;
 }
+.navigator-header-actions {
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 24px;
+}
+.navigator-header-actions > button {
+  position: relative;
+  z-index: 2;
+  display: inline-block;
+  vertical-align: middle;
+  margin: 0;
+  padding: 2px 8px;
+  font-size: 11px;
+  font-weight: normal;
+  cursor: pointer;
+}
+.navigator-header-actions > button:hover,
+.navigator-header-actions > button:focus {
+  z-index: 3;
+}
+.navigator-header-actions > button + button {
+  left: -1px;
+}
 .navigator-results {
   border-right: 1px solid #e1e1e1;
   background-color: #ffffff;
index 4d4430bf99f09358ed9f5c92db07da6b531ac2a6..2db6f1fd15a820e286bccf603d6e9f78c7ce9165 100644 (file)
   padding: 0 10px;
   border-bottom: 1px solid #cdcdcd;
   background-color: #efefef;
+  font-size: 0;
 }
 .navigator-header-title {
+  position: relative;
+  top: -2px;
+  display: inline-block;
+  vertical-align: middle;
   font-size: 20px;
   line-height: 34px;
 }
+.navigator-header-actions {
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 24px;
+}
+.navigator-header-actions > button {
+  position: relative;
+  z-index: 2;
+  display: inline-block;
+  vertical-align: middle;
+  margin: 0;
+  padding: 2px 8px;
+  font-size: 11px;
+  font-weight: normal;
+  cursor: pointer;
+}
+.navigator-header-actions > button:hover,
+.navigator-header-actions > button:focus {
+  z-index: 3;
+}
+.navigator-header-actions > button + button {
+  left: -1px;
+}
 .navigator-results {
   border-right: 1px solid #e1e1e1;
   background-color: #ffffff;
index 98f1d5fe0a0036d7ee3f602b0e2a10b043afa035..2546e3477160b3916d77075bb16bbb345be90386 100644 (file)
   padding: 0 @navigatorPadding;
   border-bottom: 1px solid @navigatorBorderColor;
   background-color: @navigatorBarBackground;
+  font-size: 0;
 }
 
 .navigator-header-title {
+  position: relative;
+  top: -2px;
+  display: inline-block;
+  vertical-align: middle;
   font-size: 20px;
   line-height: @navigatorHeaderHeight;
 }
 
+.navigator-header-actions {
+  display: inline-block;
+  vertical-align: middle;
+  margin-left: 24px;
+
+  & > button {
+    position: relative;
+    z-index: 2;
+    display: inline-block;
+    vertical-align: middle;
+    margin: 0;
+    padding: 2px 8px;
+    font-size: @smallFontSize;
+    font-weight: normal;
+    cursor: pointer;
+
+    &:hover, &:focus {
+      z-index: 3;
+    }
+  }
+
+  & > button + button {
+    left: -1px;
+  }
+}
+
 
 
 // Results
index b57b91b5fbd9392d3b72e251193e19ae7499a70e..51d6da6a4051149d787127e5760818d9229e6685 100644 (file)
@@ -4,6 +4,7 @@
 
 @baseFontSize: 13px;
 @baseFontColor: #444;
+@smallFontSize: 11px;