"manual_measures",
"measure_data",
"measure_filters",
+ "measure_filter_favourites",
"metrics",
"notifications",
"projects",
*/
public class DatabaseVersion implements BatchComponent, ServerComponent {
- public static final int LAST_VERSION = 357;
+ public static final int LAST_VERSION = 358;
public static enum Status {
UP_TO_DATE, REQUIRES_UPGRADE, REQUIRES_DOWNGRADE, FRESH_INSTALL
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('355');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('356');
INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('357');
+INSERT INTO SCHEMA_MIGRATIONS(VERSION) VALUES ('358');
INSERT INTO USERS(ID, LOGIN, NAME, EMAIL, CRYPTED_PASSWORD, SALT, CREATED_AT, UPDATED_AT, REMEMBER_TOKEN, REMEMBER_TOKEN_EXPIRES_AT) VALUES (1, 'admin', 'Administrator', '', 'a373a0e667abb2604c1fd571eb4ad47fe8cc0878', '48bc4b0d93179b5103fd3885ea9119498e9d161b', '2011-09-26 22:27:48.0', '2011-09-26 22:27:48.0', null, null);
ALTER TABLE USERS ALTER COLUMN ID RESTART WITH 2;
"UPDATED_AT" TIMESTAMP
);
+CREATE TABLE "MEASURE_FILTER_FAVOURITES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "USER_ID" INTEGER NOT NULL,
+ "MEASURE_FILTER_ID" INTEGER NOT NULL,
+ "CREATED_AT" TIMESTAMP
+);
+
-- ----------------------------------------------
-- DDL Statements for indexes
-- ----------------------------------------------
CREATE UNIQUE INDEX "UNIQ_AUTHOR_LOGINS" ON "AUTHORS" ("LOGIN");
-CREATE INDEX "MEASURE_FILTERS_NAME" ON "MEASURE_FILTERS" ("NAME");
\ No newline at end of file
+CREATE INDEX "MEASURE_FILTERS_NAME" ON "MEASURE_FILTERS" ("NAME");
+
+CREATE INDEX "MEASURE_FILTER_FAVS_USERID" ON "MEASURE_FILTER_FAVOURITES" ("USER_ID");
\ No newline at end of file
favourite_id=params[:id]
if current_user.favourite?(favourite_id)
current_user.delete_favourite(favourite_id)
- @style='notfav'
- @tooltip='Click to add to favourites'
+ style='notfav'
+ tooltip='Click to add to favourites'
else
current_user.add_favourite(favourite_id)
- @style='fav'
- @tooltip='Click to remove from favourites'
+ style='fav'
+ tooltip='Click to remove from favourites'
end
star_id=params[:elt]
render :update do |page|
page.element.removeClassName(star_id, 'notfav')
page.element.removeClassName(star_id, 'fav')
- page.element.addClassName(star_id, @style)
- page.element.writeAttribute(star_id, 'alt', @tooltip)
- page.element.writeAttribute(star_id, 'title', @tooltip)
+ page.element.addClassName(star_id, style)
+ page.element.writeAttribute(star_id, 'alt', tooltip)
+ page.element.writeAttribute(star_id, 'title', tooltip)
end
end
SECTION=Navigation::SECTION_HOME
+ # GET /measures/index
def index
@filter = MeasureFilter.new
render :action => 'search'
end
# Load existing filter
+ # GET /measures/filter/<filter id>
def filter
require_parameters :id
verify_post_request
access_denied unless logged_in?
+ add_to_favourites=false
if params[:id].present?
@filter = find_filter(params[:id])
else
@filter = MeasureFilter.new
@filter.user_id=current_user.id
+ add_to_favourites=true
end
@filter.name=params[:name]
@filter.description=params[:description]
@filter.shared=(params[:shared]=='true')
@filter.data=URI.unescape(params[:data])
if @filter.save
+ current_user.favourited_measure_filters<<@filter
render :text => @filter.id.to_s, :status => 200
else
render :partial => 'measures/save_form', :status => 400
# GET /measures/manage
def manage
access_denied unless logged_in?
+ @shared_filters = MeasureFilter.find(:all,
+ :include => :user,
+ :conditions => ['shared=? and user_id<>?', true, current_user.id])
+ @fav_filter_ids = current_user.measure_filter_favourites.map { |fav| fav.measure_filter_id }
+ Api::Utils.insensitive_sort!(@shared_filters) { |elt| elt.name }
end
+ # GET /measures/edit_form/<filter id>
def edit_form
require_parameters :id
@filter = find_filter(params[:id])
render :partial => 'measures/edit_form'
end
+ # POST /measures/edit/<filter id>?name=<name>&description=<description>&shared=<true|false>
def edit
verify_post_request
access_denied unless logged_in?
end
end
+ # POST /measures/delete/<filter id>
def delete
verify_post_request
access_denied unless logged_in?
redirect_to :action => 'manage'
end
+ # POST /measures/toggle_fav/<filter id>
+ def toggle_fav
+ access_denied unless logged_in?
+ verify_ajax_request
+ require_parameters :id
+
+ favourites = MeasureFilterFavourite.find(:all,
+ :conditions => ['user_id=? and measure_filter_id=?', current_user.id, params[:id]])
+ if favourites.empty?
+ filter = find_filter(params[:id])
+ current_user.favourited_measure_filters<<filter if filter.shared || owner?(filter)
+ is_favourite = true
+ else
+ favourites.each { |fav| fav.delete }
+ is_favourite = false
+ end
+
+ render :text => is_favourite.to_s, :status => 200
+ end
+
private
def find_filter(id)
filter = MeasureFilter.find(id)
def owner?(filter)
current_user && filter.user_id==current_user.id
end
+
end
html
end
end
+
+ def measure_filter_star(filter, is_favourite)
+ if is_favourite
+ style='fav'
+ title=message('click_to_remove_from_favourites')
+ else
+ style='notfav'
+ title=message('click_to_add_to_favourites')
+ end
+
+ "<a href='#' class='measure-filter-star #{style}' filter-id='#{filter.id}' title='#{title}'></a>"
+ end
end
attr_reader :base_result, :results
belongs_to :user
+ has_many :measure_filter_favourites, :dependent => :delete_all
+
validates_presence_of :name, :message => Api::Utils.message('measure_filter.missing_name')
validates_length_of :name, :maximum => 100, :message => Api::Utils.message('measure_filter.name_too_long')
validates_length_of :description, :allow_nil => true, :maximum => 4000
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# Sonar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+class MeasureFilterFavourite < ActiveRecord::Base
+ belongs_to :user
+ belongs_to :measure_filter
+end
\ No newline at end of file
has_many :filters, :dependent => :destroy
has_many :active_dashboards, :dependent => :destroy, :order => 'order_index'
has_many :dashboards, :dependent => :destroy
- has_many :measure_filters, :class_name => 'MeasureFilter', :dependent => :destroy
+ has_many :measure_filters, :class_name => 'MeasureFilter', :dependent => :delete_all
+
+ # measure filters that are marked as favourites
+ has_many :favourited_measure_filters, :class_name => 'MeasureFilter', :through => :measure_filter_favourites, :source => :measure_filter
+
+ # the join table MEASURE_FILTER_FAVOURITES
+ has_many :measure_filter_favourites, :class_name => 'MeasureFilterFavourite', :dependent => :delete_all
include Authentication
include Authentication::ByPassword
# do not validate user, for example when user created via SSO has no password
self.save(false)
- self.user_roles.each { |role| role.delete }
- self.properties.each { |prop| prop.delete }
- self.filters.each { |f| f.destroy }
- self.dashboards.each { |d| d.destroy }
- self.active_dashboards.each { |ad| ad.destroy }
+ self.user_roles.clear
+ self.properties.clear
+ self.filters.clear
+ self.dashboards.clear
+ self.active_dashboards.clear
+ self.measure_filter_favourites.clear
+ self.measure_filters.clear
end
# SONAR-3258
-<div class="admin_page">
- <table class="data" id="actives">
- <thead>
- <tr>
- <th><%= message('name') -%></th>
- <th><%= message('sharing') -%></th>
- <th class="right"><%= message('operations') -%></th>
+<% content_for :script do %>
+ <script>
+ $j(document).ready(function () {
+ $j(".measure-filter-star").click(function () {
+ var filterId = $j(this).attr('filter-id');
+ var star = $j(this);
+ $j.ajax({
+ type: 'POST',
+ url:baseUrl + "/measures/toggle_fav",
+ data:{id: filterId},
+ success:function (data) {
+ if (data=='true') {
+ star.removeClass('notfav').addClass('fav');
+ star.attr('title', '<%= escape_javascript message('click_to_remove_from_favourites') -%>');
+ } else {
+ star.removeClass('fav').addClass('notfav');
+ star.attr('title', '<%= escape_javascript message('click_to_add_to_favourites') -%>');
+ }
+ }
+ });
+ });
+ });
+ </script>
+<% end %>
+
+<h2>My Measure Filters</h2>
+<table class="data" id="my-filters">
+ <thead>
+ <tr>
+ <th class="thin"></th>
+ <th><%= message('name') -%></th>
+ <th><%= message('sharing') -%></th>
+ <th class="right"><%= message('operations') -%></th>
+ </tr>
+ </thead>
+ <tbody>
+ <% if current_user.measure_filters.empty? %>
+ <tr class="even">
+ <td colspan="4"><%= message('filters.no_filters') -%></td>
</tr>
- </thead>
- <tbody>
- <% if current_user.measure_filters.empty? %>
- <tr class="even">
- <td colspan="3"><%= message('filters.no_filters') -%></td>
+ <% else %>
+ <% current_user.measure_filters.each do |filter| %>
+ <tr id="my-<%= filter.name.parameterize -%>" class="<%= cycle('even', 'odd', :name => 'my-filters') -%>">
+ <td>
+ <%= measure_filter_star(filter, @fav_filter_ids.include?(filter.id)) -%>
+ </td>
+ <td>
+ <%= link_to h(filter.name), :action => 'filter', :id => filter.id -%>
+ <% if filter.description %>
+ <div><%= h filter.description -%></div>
+ <% end %>
+ </td>
+ <td>
+ <% if filter.shared %>
+ Shared with all users
+ <% else %>
+ Private
+ <% end %>
+ </td>
+ <td class="thin nowrap right">
+ <a id="edit_<%= filter.name.parameterize -%>" href="<%= ApplicationController.root_context -%>/measures/edit_form/<%= filter.id -%>" class="link-action open-modal"><%= message('edit') -%></a>
+
+ <%= link_to_action message('delete'), "#{ApplicationController.root_context}/measures/delete/#{filter.id}",
+ :class => 'link-action link-red',
+ :id => "delete_#{filter.name.parameterize}",
+ :confirm_button => message('delete'),
+ :confirm_title => 'measure_filters.delete_confirm_title',
+ :confirm_msg => 'measure_filters.are_you_sure_want_delete_filter_x',
+ :confirm_msg_params => [filter.name] -%>
+ </td>
</tr>
- <% else %>
- <% current_user.measure_filters.each do |filter| %>
- <tr id="active-<%= u filter.name -%>" class="<%= cycle('even', 'odd', :name => 'actives') -%>">
- <td>
- <%= link_to h(filter.name), :action => 'filter', :id => filter.id -%>
- <% if filter.description %>
- <div><%= h filter.description -%></div>
- <% end %>
- </td>
- <td>
- <% if filter.shared %>
- Shared with all users
- <% else %>
- Private
- <% end %>
- </td>
- <td class="thin nowrap right">
- <a id="edit_<%= filter.name.parameterize -%>" href="<%= ApplicationController.root_context -%>/measures/edit_form/<%= filter.id -%>" class="link-action open-modal"><%= message('edit') -%></a>
-
- <%= link_to_action message('delete'), "#{ApplicationController.root_context}/measures/delete/#{filter.id}",
- :class => 'link-action link-red',
- :id => "delete_#{filter.name.parameterize}",
- :confirm_button => message('delete'),
- :confirm_title => 'measure_filters.delete_confirm_title',
- :confirm_msg => 'measure_filters.are_you_sure_want_delete_filter_x',
- :confirm_msg_params => [filter.name] -%>
- </td>
- </tr>
- <% end %>
<% end %>
- </tbody>
- </table>
-</div>
+ <% end %>
+ </tbody>
+</table>
+
+<br>
+
+<h2>Shared Measure Filters</h2>
+<table class="data" id="shared-filters">
+ <thead>
+ <tr>
+ <th class="thin"></th>
+ <th><%= message('name') -%></th>
+ <th><%= message('shared_by') -%></th>
+ </tr>
+ </thead>
+ <tbody>
+ <% if @shared_filters.empty? %>
+ <tr class="even">
+ <td colspan="3"><%= message('filters.no_filters') -%></td>
+ </tr>
+ <% else %>
+ <% @shared_filters.each do |filter| %>
+ <tr id="shared-<%= filter.name.parameterize -%>" class="<%= cycle('even', 'odd', :name => 'shared-filters') -%>">
+ <td>
+ <%= measure_filter_star(filter, @fav_filter_ids.include?(filter.id)) -%>
+ </td>
+ <td>
+ <%= link_to h(filter.name), :action => 'filter', :id => filter.id -%>
+ <% if filter.description %>
+ <div><%= h filter.description -%></div>
+ <% end %>
+ </td>
+ <td>
+ <%= h filter.user.name -%>
+ </td>
+ </tr>
+
+ <% end %>
+ <% end %>
+ </tbody>
+</table>
<tr>
<td>
<input type="submit" name="search" value="Search">
- <a href="<%= ApplicationController.root_context -%>/measures">Reset</a>
+ <a href="<%= ApplicationController.root_context -%>/measures">New search</a>
</td>
</tr>
</tbody>
<% if logged_in? %>
<ul id="my-filters">
- <% current_user.measure_filters.each do |my_filter| %>
+ <% current_user.favourited_measure_filters.each do |my_filter| %>
<li>
<a href="<%= ApplicationController.root_context -%>/measures/filter/<%= my_filter.id -%>"><%= h my_filter.name -%></a>
</li>
<% end %>
</ul>
+ <a href="<%= ApplicationController.root_context -%>/measures/manage" class="link-action">Manage</a>
<% end %>
</div>
</div>
<% end %>
- </p>
</div>
\ No newline at end of file
--- /dev/null
+#
+# Sonar, entreprise quality control tool.
+# Copyright (C) 2008-2012 SonarSource
+# mailto:contact AT sonarsource DOT com
+#
+# Sonar is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 3 of the License, or (at your option) any later version.
+#
+# Sonar is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with Sonar; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
+#
+
+#
+# Sonar 3.4
+#
+class CreateMeasureFilterFavourites < ActiveRecord::Migration
+ def self.up
+ create_table 'measure_filter_favourites' do |t|
+ t.column 'user_id', :integer, :null => false
+ t.column 'measure_filter_id', :integer, :null => false
+ t.column 'created_at', :datetime
+ end
+ add_index 'measure_filter_favourites', 'user_id', :name => 'measure_filter_favs_userid'
+ end
+end
+