Revision 1297:0a574315af3e .svn/pristine/99
| .svn/pristine/99/99427a60ba43ee192719046d5e81ce5c2ae0e96f.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# FileSystem adapter |
|
| 5 |
# File written by Paul Rivier, at Demotera. |
|
| 6 |
# |
|
| 7 |
# This program is free software; you can redistribute it and/or |
|
| 8 |
# modify it under the terms of the GNU General Public License |
|
| 9 |
# as published by the Free Software Foundation; either version 2 |
|
| 10 |
# of the License, or (at your option) any later version. |
|
| 11 |
# |
|
| 12 |
# This program is distributed in the hope that it will be useful, |
|
| 13 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 14 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 15 |
# GNU General Public License for more details. |
|
| 16 |
# |
|
| 17 |
# You should have received a copy of the GNU General Public License |
|
| 18 |
# along with this program; if not, write to the Free Software |
|
| 19 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 20 |
|
|
| 21 |
require 'redmine/scm/adapters/abstract_adapter' |
|
| 22 |
require 'find' |
|
| 23 |
|
|
| 24 |
module Redmine |
|
| 25 |
module Scm |
|
| 26 |
module Adapters |
|
| 27 |
class FilesystemAdapter < AbstractAdapter |
|
| 28 |
|
|
| 29 |
class << self |
|
| 30 |
def client_available |
|
| 31 |
true |
|
| 32 |
end |
|
| 33 |
end |
|
| 34 |
|
|
| 35 |
def initialize(url, root_url=nil, login=nil, password=nil, |
|
| 36 |
path_encoding=nil) |
|
| 37 |
@url = with_trailling_slash(url) |
|
| 38 |
@path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding |
|
| 39 |
end |
|
| 40 |
|
|
| 41 |
def path_encoding |
|
| 42 |
@path_encoding |
|
| 43 |
end |
|
| 44 |
|
|
| 45 |
def format_path_ends(path, leading=true, trailling=true) |
|
| 46 |
path = leading ? with_leading_slash(path) : |
|
| 47 |
without_leading_slash(path) |
|
| 48 |
trailling ? with_trailling_slash(path) : |
|
| 49 |
without_trailling_slash(path) |
|
| 50 |
end |
|
| 51 |
|
|
| 52 |
def info |
|
| 53 |
info = Info.new({:root_url => target(),
|
|
| 54 |
:lastrev => nil |
|
| 55 |
}) |
|
| 56 |
info |
|
| 57 |
rescue CommandFailed |
|
| 58 |
return nil |
|
| 59 |
end |
|
| 60 |
|
|
| 61 |
def entries(path="", identifier=nil, options={})
|
|
| 62 |
entries = Entries.new |
|
| 63 |
trgt_utf8 = target(path) |
|
| 64 |
trgt = scm_iconv(@path_encoding, 'UTF-8', trgt_utf8) |
|
| 65 |
Dir.new(trgt).each do |e1| |
|
| 66 |
e_utf8 = scm_iconv('UTF-8', @path_encoding, e1)
|
|
| 67 |
next if e_utf8.blank? |
|
| 68 |
relative_path_utf8 = format_path_ends( |
|
| 69 |
(format_path_ends(path,false,true) + e_utf8),false,false) |
|
| 70 |
t1_utf8 = target(relative_path_utf8) |
|
| 71 |
t1 = scm_iconv(@path_encoding, 'UTF-8', t1_utf8) |
|
| 72 |
relative_path = scm_iconv(@path_encoding, 'UTF-8', relative_path_utf8) |
|
| 73 |
e1 = scm_iconv(@path_encoding, 'UTF-8', e_utf8) |
|
| 74 |
if File.exist?(t1) and # paranoid test |
|
| 75 |
%w{file directory}.include?(File.ftype(t1)) and # avoid special types
|
|
| 76 |
not File.basename(e1).match(/^\.+$/) # avoid . and .. |
|
| 77 |
p1 = File.readable?(t1) ? relative_path : "" |
|
| 78 |
utf_8_path = scm_iconv('UTF-8', @path_encoding, p1)
|
|
| 79 |
entries << |
|
| 80 |
Entry.new({ :name => scm_iconv('UTF-8', @path_encoding, File.basename(e1)),
|
|
| 81 |
# below : list unreadable files, but dont link them. |
|
| 82 |
:path => utf_8_path, |
|
| 83 |
:kind => (File.directory?(t1) ? 'dir' : 'file'), |
|
| 84 |
:size => (File.directory?(t1) ? nil : [File.size(t1)].pack('l').unpack('L').first),
|
|
| 85 |
:lastrev => |
|
| 86 |
Revision.new({:time => (File.mtime(t1)) })
|
|
| 87 |
}) |
|
| 88 |
end |
|
| 89 |
end |
|
| 90 |
entries.sort_by_name |
|
| 91 |
rescue => err |
|
| 92 |
logger.error "scm: filesystem: error: #{err.message}"
|
|
| 93 |
raise CommandFailed.new(err.message) |
|
| 94 |
end |
|
| 95 |
|
|
| 96 |
def cat(path, identifier=nil) |
|
| 97 |
p = scm_iconv(@path_encoding, 'UTF-8', target(path)) |
|
| 98 |
File.new(p, "rb").read |
|
| 99 |
rescue => err |
|
| 100 |
logger.error "scm: filesystem: error: #{err.message}"
|
|
| 101 |
raise CommandFailed.new(err.message) |
|
| 102 |
end |
|
| 103 |
|
|
| 104 |
private |
|
| 105 |
|
|
| 106 |
# AbstractAdapter::target is implicitly made to quote paths. |
|
| 107 |
# Here we do not shell-out, so we do not want quotes. |
|
| 108 |
def target(path=nil) |
|
| 109 |
# Prevent the use of .. |
|
| 110 |
if path and !path.match(/(^|\/)\.\.(\/|$)/) |
|
| 111 |
return "#{self.url}#{without_leading_slash(path)}"
|
|
| 112 |
end |
|
| 113 |
return self.url |
|
| 114 |
end |
|
| 115 |
end |
|
| 116 |
end |
|
| 117 |
end |
|
| 118 |
end |
|
| .svn/pristine/99/997184000368211e968189a862af8cf1d5978fee.svn-base | ||
|---|---|---|
| 1 |
<%= error_messages_for 'time_entry' %> |
|
| 2 |
<%= back_url_hidden_field_tag %> |
|
| 3 |
|
|
| 4 |
<div class="box tabular"> |
|
| 5 |
<% if @time_entry.new_record? %> |
|
| 6 |
<% if params[:project_id] || @time_entry.issue %> |
|
| 7 |
<%= f.hidden_field :project_id %> |
|
| 8 |
<% else %> |
|
| 9 |
<p><%= f.select :project_id, project_tree_options_for_select(Project.allowed_to(:log_time).all, :selected => @time_entry.project), :required => true %></p> |
|
| 10 |
<% end %> |
|
| 11 |
<% end %> |
|
| 12 |
<p><%= f.text_field :issue_id, :size => 6 %> <em><%= h("#{@time_entry.issue.tracker.name} ##{@time_entry.issue.id}: #{@time_entry.issue.subject}") if @time_entry.issue %></em></p>
|
|
| 13 |
<p><%= f.text_field :spent_on, :size => 10, :required => true %><%= calendar_for('time_entry_spent_on') %></p>
|
|
| 14 |
<p><%= f.text_field :hours, :size => 6, :required => true %></p> |
|
| 15 |
<p><%= f.text_field :comments, :size => 100 %></p> |
|
| 16 |
<p><%= f.select :activity_id, activity_collection_for_select_options(@time_entry), :required => true %></p> |
|
| 17 |
<% @time_entry.custom_field_values.each do |value| %> |
|
| 18 |
<p><%= custom_field_tag_with_label :time_entry, value %></p> |
|
| 19 |
<% end %> |
|
| 20 |
<%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %>
|
|
| 21 |
</div> |
|
| 22 |
|
|
| 23 |
<%= javascript_tag "observeAutocompleteField('time_entry_issue_id', '#{escape_javascript auto_complete_issues_path(:project_id => @project, :scope => (@project ? nil : 'all'))}')" %>
|
|
| .svn/pristine/99/998dc4f658daf9b604937796605070d71a9c3bd4.svn-base | ||
|---|---|---|
| 1 |
# Redmine - project management software |
|
| 2 |
# Copyright (C) 2006-2012 Jean-Philippe Lang |
|
| 3 |
# |
|
| 4 |
# This program is free software; you can redistribute it and/or |
|
| 5 |
# modify it under the terms of the GNU General Public License |
|
| 6 |
# as published by the Free Software Foundation; either version 2 |
|
| 7 |
# of the License, or (at your option) any later version. |
|
| 8 |
# |
|
| 9 |
# This program is distributed in the hope that it will be useful, |
|
| 10 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
| 11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
| 12 |
# GNU General Public License for more details. |
|
| 13 |
# |
|
| 14 |
# You should have received a copy of the GNU General Public License |
|
| 15 |
# along with this program; if not, write to the Free Software |
|
| 16 |
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
| 17 |
|
|
| 18 |
class TimeEntryActivity < Enumeration |
|
| 19 |
has_many :time_entries, :foreign_key => 'activity_id' |
|
| 20 |
|
|
| 21 |
OptionName = :enumeration_activities |
|
| 22 |
|
|
| 23 |
def option_name |
|
| 24 |
OptionName |
|
| 25 |
end |
|
| 26 |
|
|
| 27 |
def objects_count |
|
| 28 |
time_entries.count |
|
| 29 |
end |
|
| 30 |
|
|
| 31 |
def transfer_relations(to) |
|
| 32 |
time_entries.update_all("activity_id = #{to.id}")
|
|
| 33 |
end |
|
| 34 |
end |
|
| .svn/pristine/99/999fdff2052b71cf3f29b97c581e2f895bcdf162.svn-base | ||
|---|---|---|
| 1 |
require 'SVG/Graph/Plot' |
|
| 2 |
|
|
| 3 |
module SVG |
|
| 4 |
module Graph |
|
| 5 |
# === For creating SVG plots of scalar temporal data |
|
| 6 |
# |
|
| 7 |
# = Synopsis |
|
| 8 |
# |
|
| 9 |
# require 'SVG/Graph/TimeSeriess' |
|
| 10 |
# |
|
| 11 |
# # Data sets are x,y pairs |
|
| 12 |
# data1 = ["6/17/72", 11, "1/11/72", 7, "4/13/04 17:31", 11, |
|
| 13 |
# "9/11/01", 9, "9/1/85", 2, "9/1/88", 1, "1/15/95", 13] |
|
| 14 |
# data2 = ["8/1/73", 18, "3/1/77", 15, "10/1/98", 4, |
|
| 15 |
# "5/1/02", 14, "3/1/95", 6, "8/1/91", 12, "12/1/87", 6, |
|
| 16 |
# "5/1/84", 17, "10/1/80", 12] |
|
| 17 |
# |
|
| 18 |
# graph = SVG::Graph::TimeSeries.new( {
|
|
| 19 |
# :width => 640, |
|
| 20 |
# :height => 480, |
|
| 21 |
# :graph_title => title, |
|
| 22 |
# :show_graph_title => true, |
|
| 23 |
# :no_css => true, |
|
| 24 |
# :key => true, |
|
| 25 |
# :scale_x_integers => true, |
|
| 26 |
# :scale_y_integers => true, |
|
| 27 |
# :min_x_value => 0, |
|
| 28 |
# :min_y_value => 0, |
|
| 29 |
# :show_data_labels => true, |
|
| 30 |
# :show_x_guidelines => true, |
|
| 31 |
# :show_x_title => true, |
|
| 32 |
# :x_title => "Time", |
|
| 33 |
# :show_y_title => true, |
|
| 34 |
# :y_title => "Ice Cream Cones", |
|
| 35 |
# :y_title_text_direction => :bt, |
|
| 36 |
# :stagger_x_labels => true, |
|
| 37 |
# :x_label_format => "%m/%d/%y", |
|
| 38 |
# }) |
|
| 39 |
# |
|
| 40 |
# graph.add_data({
|
|
| 41 |
# :data => projection |
|
| 42 |
# :title => 'Projected', |
|
| 43 |
# }) |
|
| 44 |
# |
|
| 45 |
# graph.add_data({
|
|
| 46 |
# :data => actual, |
|
| 47 |
# :title => 'Actual', |
|
| 48 |
# }) |
|
| 49 |
# |
|
| 50 |
# print graph.burn() |
|
| 51 |
# |
|
| 52 |
# = Description |
|
| 53 |
# |
|
| 54 |
# Produces a graph of temporal scalar data. |
|
| 55 |
# |
|
| 56 |
# = Examples |
|
| 57 |
# |
|
| 58 |
# http://www.germane-software/repositories/public/SVG/test/timeseries.rb |
|
| 59 |
# |
|
| 60 |
# = Notes |
|
| 61 |
# |
|
| 62 |
# The default stylesheet handles upto 10 data sets, if you |
|
| 63 |
# use more you must create your own stylesheet and add the |
|
| 64 |
# additional settings for the extra data sets. You will know |
|
| 65 |
# if you go over 10 data sets as they will have no style and |
|
| 66 |
# be in black. |
|
| 67 |
# |
|
| 68 |
# Unlike the other types of charts, data sets must contain x,y pairs: |
|
| 69 |
# |
|
| 70 |
# [ "12:30", 2 ] # A data set with 1 point: ("12:30",2)
|
|
| 71 |
# [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and
|
|
| 72 |
# # ("14:20",6)
|
|
| 73 |
# |
|
| 74 |
# Note that multiple data sets within the same chart can differ in length, |
|
| 75 |
# and that the data in the datasets needn't be in order; they will be ordered |
|
| 76 |
# by the plot along the X-axis. |
|
| 77 |
# |
|
| 78 |
# The dates must be parseable by ParseDate, but otherwise can be |
|
| 79 |
# any order of magnitude (seconds within the hour, or years) |
|
| 80 |
# |
|
| 81 |
# = See also |
|
| 82 |
# |
|
| 83 |
# * SVG::Graph::Graph |
|
| 84 |
# * SVG::Graph::BarHorizontal |
|
| 85 |
# * SVG::Graph::Bar |
|
| 86 |
# * SVG::Graph::Line |
|
| 87 |
# * SVG::Graph::Pie |
|
| 88 |
# * SVG::Graph::Plot |
|
| 89 |
# |
|
| 90 |
# == Author |
|
| 91 |
# |
|
| 92 |
# Sean E. Russell <serATgermaneHYPHENsoftwareDOTcom> |
|
| 93 |
# |
|
| 94 |
# Copyright 2004 Sean E. Russell |
|
| 95 |
# This software is available under the Ruby license[LICENSE.txt] |
|
| 96 |
# |
|
| 97 |
class TimeSeries < Plot |
|
| 98 |
# In addition to the defaults set by Graph::initialize and |
|
| 99 |
# Plot::set_defaults, sets: |
|
| 100 |
# [x_label_format] '%Y-%m-%d %H:%M:%S' |
|
| 101 |
# [popup_format] '%Y-%m-%d %H:%M:%S' |
|
| 102 |
def set_defaults |
|
| 103 |
super |
|
| 104 |
init_with( |
|
| 105 |
#:max_time_span => '', |
|
| 106 |
:x_label_format => '%Y-%m-%d %H:%M:%S', |
|
| 107 |
:popup_format => '%Y-%m-%d %H:%M:%S' |
|
| 108 |
) |
|
| 109 |
end |
|
| 110 |
|
|
| 111 |
# The format string use do format the X axis labels. |
|
| 112 |
# See Time::strformat |
|
| 113 |
attr_accessor :x_label_format |
|
| 114 |
# Use this to set the spacing between dates on the axis. The value |
|
| 115 |
# must be of the form |
|
| 116 |
# "\d+ ?(days|weeks|months|years|hours|minutes|seconds)?" |
|
| 117 |
# |
|
| 118 |
# EG: |
|
| 119 |
# |
|
| 120 |
# graph.timescale_divisions = "2 weeks" |
|
| 121 |
# |
|
| 122 |
# will cause the chart to try to divide the X axis up into segments of |
|
| 123 |
# two week periods. |
|
| 124 |
attr_accessor :timescale_divisions |
|
| 125 |
# The formatting used for the popups. See x_label_format |
|
| 126 |
attr_accessor :popup_format |
|
| 127 |
|
|
| 128 |
# Add data to the plot. |
|
| 129 |
# |
|
| 130 |
# d1 = [ "12:30", 2 ] # A data set with 1 point: ("12:30",2)
|
|
| 131 |
# d2 = [ "01:00",2, "14:20",6] # A data set with 2 points: ("01:00",2) and
|
|
| 132 |
# # ("14:20",6)
|
|
| 133 |
# graph.add_data( |
|
| 134 |
# :data => d1, |
|
| 135 |
# :title => 'One' |
|
| 136 |
# ) |
|
| 137 |
# graph.add_data( |
|
| 138 |
# :data => d2, |
|
| 139 |
# :title => 'Two' |
|
| 140 |
# ) |
|
| 141 |
# |
|
| 142 |
# Note that the data must be in time,value pairs, and that the date format |
|
| 143 |
# may be any date that is parseable by ParseDate. |
|
| 144 |
def add_data data |
|
| 145 |
@data = [] unless @data |
|
| 146 |
|
|
| 147 |
raise "No data provided by #{@data.inspect}" unless data[:data] and
|
|
| 148 |
data[:data].kind_of? Array |
|
| 149 |
raise "Data supplied must be x,y pairs! "+ |
|
| 150 |
"The data provided contained an odd set of "+ |
|
| 151 |
"data points" unless data[:data].length % 2 == 0 |
|
| 152 |
return if data[:data].length == 0 |
|
| 153 |
|
|
| 154 |
|
|
| 155 |
x = [] |
|
| 156 |
y = [] |
|
| 157 |
data[:data].each_index {|i|
|
|
| 158 |
if i%2 == 0 |
|
| 159 |
t = DateTime.parse( data[:data][i] ).to_time |
|
| 160 |
x << t.to_i |
|
| 161 |
else |
|
| 162 |
y << data[:data][i] |
|
| 163 |
end |
|
| 164 |
} |
|
| 165 |
sort( x, y ) |
|
| 166 |
data[:data] = [x,y] |
|
| 167 |
@data << data |
|
| 168 |
end |
|
| 169 |
|
|
| 170 |
|
|
| 171 |
protected |
|
| 172 |
|
|
| 173 |
def min_x_value=(value) |
|
| 174 |
@min_x_value = DateTime.parse( value ).to_time |
|
| 175 |
end |
|
| 176 |
|
|
| 177 |
|
|
| 178 |
def format x, y |
|
| 179 |
Time.at( x ).strftime( popup_format ) |
|
| 180 |
end |
|
| 181 |
|
|
| 182 |
def get_x_labels |
|
| 183 |
get_x_values.collect { |v| Time.at(v).strftime( x_label_format ) }
|
|
| 184 |
end |
|
| 185 |
|
|
| 186 |
private |
|
| 187 |
def get_x_values |
|
| 188 |
rv = [] |
|
| 189 |
min, max, scale_division = x_range |
|
| 190 |
if timescale_divisions |
|
| 191 |
timescale_divisions =~ /(\d+) ?(day|week|month|year|hour|minute|second)?/ |
|
| 192 |
division_units = $2 ? $2 : "day" |
|
| 193 |
amount = $1.to_i |
|
| 194 |
if amount |
|
| 195 |
step = nil |
|
| 196 |
case division_units |
|
| 197 |
when "month" |
|
| 198 |
cur = min |
|
| 199 |
while cur < max |
|
| 200 |
rv << cur |
|
| 201 |
arr = Time.at( cur ).to_a |
|
| 202 |
arr[4] += amount |
|
| 203 |
if arr[4] > 12 |
|
| 204 |
arr[5] += (arr[4] / 12).to_i |
|
| 205 |
arr[4] = (arr[4] % 12) |
|
| 206 |
end |
|
| 207 |
cur = Time.local(*arr).to_i |
|
| 208 |
end |
|
| 209 |
when "year" |
|
| 210 |
cur = min |
|
| 211 |
while cur < max |
|
| 212 |
rv << cur |
|
| 213 |
arr = Time.at( cur ).to_a |
|
| 214 |
arr[5] += amount |
|
| 215 |
cur = Time.local(*arr).to_i |
|
| 216 |
end |
|
| 217 |
when "week" |
|
| 218 |
step = 7 * 24 * 60 * 60 * amount |
|
| 219 |
when "day" |
|
| 220 |
step = 24 * 60 * 60 * amount |
|
| 221 |
when "hour" |
|
| 222 |
step = 60 * 60 * amount |
|
| 223 |
when "minute" |
|
| 224 |
step = 60 * amount |
|
| 225 |
when "second" |
|
| 226 |
step = amount |
|
| 227 |
end |
|
| 228 |
min.step( max, step ) {|v| rv << v} if step
|
|
| 229 |
|
|
| 230 |
return rv |
|
| 231 |
end |
|
| 232 |
end |
|
| 233 |
min.step( max, scale_division ) {|v| rv << v}
|
|
| 234 |
return rv |
|
| 235 |
end |
|
| 236 |
end |
|
| 237 |
end |
|
| 238 |
end |
|
| .svn/pristine/99/99e2701a14c4f2125c8873be0b1ded74098d370b.svn-base | ||
|---|---|---|
| 1 |
#!/usr/bin/env ruby |
|
| 2 |
|
|
| 3 |
require File.dirname(__FILE__) + '/../config/boot' |
|
| 4 |
require File.dirname(__FILE__) + '/../config/environment' |
|
| 5 |
|
|
| 6 |
class Rack::PathInfoRewriter |
|
| 7 |
def initialize(app) |
|
| 8 |
@app = app |
|
| 9 |
end |
|
| 10 |
|
|
| 11 |
def call(env) |
|
| 12 |
env.delete('SCRIPT_NAME')
|
|
| 13 |
parts = env['REQUEST_URI'].split('?')
|
|
| 14 |
env['PATH_INFO'] = parts[0] |
|
| 15 |
env['QUERY_STRING'] = parts[1].to_s |
|
| 16 |
@app.call(env) |
|
| 17 |
end |
|
| 18 |
end |
|
| 19 |
|
|
| 20 |
Rack::Handler::FastCGI.run Rack::PathInfoRewriter.new(RedmineApp::Application) |
|
| .svn/pristine/99/99facf87c9773fe164f63d4ddf92909973ba997e.svn-base | ||
|---|---|---|
| 1 |
<%= error_messages_for 'query' %> |
|
| 2 |
|
|
| 3 |
<div class="box"> |
|
| 4 |
<div class="tabular"> |
|
| 5 |
<p><label for="query_name"><%=l(:field_name)%></label> |
|
| 6 |
<%= text_field 'query', 'name', :size => 80 %></p> |
|
| 7 |
|
|
| 8 |
<% if User.current.admin? || User.current.allowed_to?(:manage_public_queries, @project) %> |
|
| 9 |
<p><label for="query_is_public"><%=l(:field_is_public)%></label> |
|
| 10 |
<%= check_box 'query', 'is_public', |
|
| 11 |
:onchange => (User.current.admin? ? nil : 'if (this.checked) {$("#query_is_for_all").removeAttr("checked"); $("#query_is_for_all").attr("disabled", true);} else {$("#query_is_for_all").removeAttr("disabled");}') %></p>
|
|
| 12 |
<% end %> |
|
| 13 |
|
|
| 14 |
<p><label for="query_is_for_all"><%=l(:field_is_for_all)%></label> |
|
| 15 |
<%= check_box_tag 'query_is_for_all', 1, @query.project.nil?, |
|
| 16 |
:disabled => (!@query.new_record? && (@query.project.nil? || (@query.is_public? && !User.current.admin?))) %></p> |
|
| 17 |
|
|
| 18 |
<p><label for="query_default_columns"><%=l(:label_default_columns)%></label> |
|
| 19 |
<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns', |
|
| 20 |
:onclick => 'if (this.checked) {$("#columns").hide();} else {$("#columns").show();}' %></p>
|
|
| 21 |
|
|
| 22 |
<p><label for="query_group_by"><%= l(:field_group_by) %></label> |
|
| 23 |
<%= select 'query', 'group_by', @query.groupable_columns.collect {|c| [c.caption, c.name.to_s]}, :include_blank => true %></p>
|
|
| 24 |
|
|
| 25 |
<p><label><%= l(:button_show) %></label> |
|
| 26 |
<%= available_block_columns_tags(@query) %></p> |
|
| 27 |
</div> |
|
| 28 |
|
|
| 29 |
<fieldset id="filters"><legend><%= l(:label_filter_plural) %></legend> |
|
| 30 |
<%= render :partial => 'queries/filters', :locals => {:query => query}%>
|
|
| 31 |
</fieldset> |
|
| 32 |
|
|
| 33 |
<fieldset><legend><%= l(:label_sort) %></legend> |
|
| 34 |
<% 3.times do |i| %> |
|
| 35 |
<%= i+1 %>: |
|
| 36 |
<%= label_tag "query_sort_criteria_attribute_" + i.to_s, |
|
| 37 |
l(:description_query_sort_criteria_attribute), :class => "hidden-for-sighted" %> |
|
| 38 |
<%= select_tag("query[sort_criteria][#{i}][]",
|
|
| 39 |
options_for_select([[]] + query.available_columns.select(&:sortable?).collect {|column| [column.caption, column.name.to_s]}, @query.sort_criteria_key(i)),
|
|
| 40 |
:id => "query_sort_criteria_attribute_" + i.to_s)%> |
|
| 41 |
<%= label_tag "query_sort_criteria_direction_" + i.to_s, |
|
| 42 |
l(:description_query_sort_criteria_direction), :class => "hidden-for-sighted" %> |
|
| 43 |
<%= select_tag("query[sort_criteria][#{i}][]",
|
|
| 44 |
options_for_select([[], [l(:label_ascending), 'asc'], [l(:label_descending), 'desc']], @query.sort_criteria_order(i)), |
|
| 45 |
:id => "query_sort_criteria_direction_" + i.to_s) %> |
|
| 46 |
<br /> |
|
| 47 |
<% end %> |
|
| 48 |
</fieldset> |
|
| 49 |
|
|
| 50 |
<%= content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %> |
|
| 51 |
<legend><%= l(:field_column_names) %></legend> |
|
| 52 |
<%= render :partial => 'queries/columns', :locals => {:query => query}%>
|
|
| 53 |
<% end %> |
|
| 54 |
|
|
| 55 |
</div> |
|
Also available in: Unified diff