Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. <% @gantt.view = self %>
  2. <div class="contextual">
  3. </div>
  4. <h2><%= @query.new_record? ? l(:label_gantt) : @query.name %></h2>
  5. <%= form_tag({:controller => 'gantts', :action => 'show',
  6. :project_id => @project, :month => params[:month],
  7. :year => params[:year], :months => params[:months]},
  8. :method => :get, :id => 'query_form') do %>
  9. <%= hidden_field_tag 'set_filter', '1' %>
  10. <%= hidden_field_tag 'gantt', '1' %>
  11. <div id="query_form_with_buttons" class="hide-when-print">
  12. <div id="query_form_content">
  13. <fieldset id="filters" class="collapsible <%= @query.new_record? ? "" : "collapsed" %>">
  14. <legend onclick="toggleFieldset(this);" class="icon icon-<%= @query.new_record? ? "expanded" : "collapsed" %>"><%= l(:label_filter_plural) %></legend>
  15. <div style="<%= @query.new_record? ? "" : "display: none;" %>">
  16. <%= render :partial => 'queries/filters', :locals => {:query => @query} %>
  17. </div>
  18. </fieldset>
  19. <fieldset id="options" class="collapsible collapsed">
  20. <legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_options) %></legend>
  21. <div style="display: none;">
  22. <div>
  23. <fieldset>
  24. <legend>
  25. <%= l(:field_column_names) %>
  26. </legend>
  27. <div id="list-definition">
  28. <div>
  29. <label for="draw_selected_columns">
  30. <%= check_box 'query', 'draw_selected_columns', :id => 'draw_selected_columns', 'data-enables' => '#list-definition .query-columns select, #list-definition .query-columns input' %>
  31. <%= l(:label_display) %>
  32. </label>
  33. </div>
  34. <div>
  35. <%= render_query_columns_selection(@query) %>
  36. </div>
  37. </div>
  38. </fieldset>
  39. <fieldset>
  40. <legend><%= l(:label_related_issues) %></legend>
  41. <label for="draw_relations">
  42. <%= check_box 'query', 'draw_relations', :id => 'draw_relations' %>
  43. <% rels = [IssueRelation::TYPE_BLOCKS, IssueRelation::TYPE_PRECEDES] %>
  44. <% rels.each do |rel| %>
  45. <% color = Redmine::Helpers::Gantt::DRAW_TYPES[rel][:color] %>
  46. <%= content_tag(:span, '&nbsp;&nbsp;&nbsp;'.html_safe,
  47. :style => "background-color: #{color}") %>
  48. <%= l(IssueRelation::TYPES[rel][:name]) %>
  49. <% end %>
  50. </label>
  51. </fieldset>
  52. <fieldset>
  53. <legend><%= l(:label_gantt_progress_line) %></legend>
  54. <label for="draw_progress_line">
  55. <%= check_box 'query', 'draw_progress_line', :id => 'draw_progress_line' %>
  56. <%= l(:label_display) %>
  57. </label>
  58. </fieldset>
  59. </div>
  60. </div>
  61. </fieldset>
  62. </div>
  63. <p class="contextual">
  64. <span>
  65. <%= gantt_zoom_link(@gantt, :in) %>
  66. <%= gantt_zoom_link(@gantt, :out) %>
  67. </span>
  68. <span>
  69. <%= link_to_previous_month(@gantt.year_from, @gantt.month_from, :accesskey => accesskey(:previous)) %> | <%= link_to_next_month(@gantt.year_from, @gantt.month_from, :accesskey => accesskey(:next)) %>
  70. </span>
  71. </p>
  72. <p class="buttons">
  73. <%= number_field_tag 'months', @gantt.months, :min => 1, :max => Setting.gantt_months_limit.to_i, :autocomplete => false %>
  74. <%= l(:label_months_from) %>
  75. <%= select_month(@gantt.month_from, :prefix => "month", :discard_type => true) %>
  76. <%= select_year(@gantt.year_from, :prefix => "year", :discard_type => true) %>
  77. <%= hidden_field_tag 'zoom', @gantt.zoom %>
  78. <%= link_to_function l(:button_apply), '$("#query_form").submit()',
  79. :class => 'icon icon-checked' %>
  80. <%= link_to l(:button_clear), { :project_id => @project, :set_filter => 1 },
  81. :class => 'icon icon-reload' %>
  82. <% if @query.new_record? && User.current.allowed_to?(:save_queries, @project, :global => true) %>
  83. <%= link_to_function l(:button_save_object, object_name: l(:label_query).downcase),
  84. "$('#query_form').attr('action', '#{ @project ? new_project_query_path(@project) : new_query_path }').submit();",
  85. :class => 'icon icon-save' %>
  86. <% end %>
  87. <% if !@query.new_record? && @query.editable_by?(User.current) %>
  88. <%= link_to l(:button_edit_object, object_name: l(:label_query).downcase), edit_query_path(@query, :gantt => 1), :class => 'icon icon-edit' %>
  89. <%= delete_link query_path(@query, :gantt => 1), {}, l(:button_delete_object, object_name: l(:label_query).downcase) %>
  90. <% end %>
  91. </p>
  92. </div>
  93. <% end %>
  94. <%= error_messages_for 'query' %>
  95. <% if @query.valid? %>
  96. <%
  97. zoom = 1
  98. @gantt.zoom.times { zoom = zoom * 2 }
  99. subject_width = 330
  100. header_height = 18
  101. headers_height = header_height
  102. show_weeks = false
  103. show_days = false
  104. show_day_num = false
  105. if @gantt.zoom > 1
  106. show_weeks = true
  107. headers_height = 2 * header_height
  108. if @gantt.zoom > 2
  109. show_days = true
  110. headers_height = 3 * header_height
  111. if @gantt.zoom > 3
  112. show_day_num = true
  113. headers_height = 4 * header_height
  114. end
  115. end
  116. end
  117. # Width of the entire chart
  118. g_width = ((@gantt.date_to - @gantt.date_from + 1) * zoom).to_i
  119. @gantt.render(:top => headers_height + 8,
  120. :zoom => zoom,
  121. :g_width => g_width,
  122. :subject_width => subject_width)
  123. g_height = [(20 * (@gantt.number_of_rows + 6)) + 150, 206].max
  124. t_height = g_height + headers_height
  125. %>
  126. <% if @gantt.truncated %>
  127. <p class="warning"><%= l(:notice_gantt_chart_truncated, :max => @gantt.max_rows) %></p>
  128. <% end %>
  129. <table class='gantt-table'>
  130. <tr>
  131. <td style="width:<%= @query.draw_selected_columns ? subject_width + 1 : subject_width + 2 %>px;" class="gantt_subjects_column">
  132. <%
  133. style = ""
  134. style += "position:relative;"
  135. style += "height: #{t_height + 24}px;"
  136. style += "width: #{subject_width + 1}px;"
  137. %>
  138. <%= content_tag(:div, :style => style, :class => "gantt_subjects_container #{'draw_selected_columns' if @query.draw_selected_columns}") do %>
  139. <%
  140. style = ""
  141. style += "width: #{subject_width + 1}px;"
  142. style += "height: #{headers_height}px;"
  143. style += 'background: #eee;'
  144. %>
  145. <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
  146. <%
  147. style = ""
  148. style += "z-index: 1;"
  149. style += "width: #{subject_width + 1}px;"
  150. style += "height: #{t_height}px;"
  151. style += 'overflow: hidden;'
  152. %>
  153. <%= content_tag(:div, "", :style => style, :class => "gantt_hdr") %>
  154. <%= content_tag(:div, :class => "gantt_subjects") do %>
  155. <%= form_tag({}, :data => {:cm_url => issues_context_menu_path}) do -%>
  156. <%= hidden_field_tag 'back_url', url_for(:params => request.query_parameters), :id => nil %>
  157. <%= @gantt.subjects.html_safe %>
  158. <% end %>
  159. <% end %>
  160. <% end %>
  161. </td>
  162. <%
  163. @query.columns.each do |column|
  164. next if Redmine::Helpers::Gantt::UNAVAILABLE_COLUMNS.include?(column.name)
  165. column_name = column.name.to_s.tr('.', '_')
  166. %>
  167. <td class="gantt_<%= column_name %>_column gantt_selected_column <%= 'last_gantt_selected_column' if @query.columns.last == column %>" id="<%= column_name %>">
  168. <%
  169. style = "position: relative;"
  170. style += "height: #{t_height + 24}px;"
  171. %>
  172. <%= content_tag(:div, :style => style, :class => "gantt_#{column_name}_container gantt_selected_column_container") do %>
  173. <%
  174. style = "height: #{t_height}px;"
  175. style += 'overflow: hidden;'
  176. %>
  177. <%= content_tag(:div, '', :style => style, :class => "gantt_hdr") %>
  178. <%
  179. style = "height: #{headers_height}px;"
  180. style += 'background: #eee;'
  181. %>
  182. <%= content_tag(:div, content_tag(:p, column.caption, :class => 'gantt_hdr_selected_column_name'), :style => style, :class => "gantt_hdr") %>
  183. <%= content_tag(:div, :class => "gantt_#{column_name} gantt_selected_column_content") do %>
  184. <%= @gantt.selected_column_content({:column => column, :top => headers_height + 8, :zoom => zoom, :g_width => g_width}).html_safe %>
  185. <% end %>
  186. <% end %>
  187. </td>
  188. <% end %>
  189. <td>
  190. <div style="position:relative;height:<%= t_height + 24 %>px;overflow:auto;" id="gantt_area">
  191. <%
  192. style = ""
  193. style += "width: #{g_width - 1}px;"
  194. style += "height: #{headers_height}px;"
  195. style += 'background: #eee;'
  196. %>
  197. <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :class => "gantt_hdr") %>
  198. <% ###### Months headers ###### %>
  199. <%
  200. month_f = @gantt.date_from
  201. left = 0
  202. height = (show_weeks ? header_height : header_height + g_height)
  203. %>
  204. <% @gantt.months.times do %>
  205. <%
  206. width = (((month_f >> 1) - month_f) * zoom - 1).to_i
  207. style = ""
  208. style += "left: #{left}px;"
  209. style += "width: #{width}px;"
  210. style += "height: #{height}px;"
  211. %>
  212. <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
  213. <%= link_to "#{month_f.year}-#{month_f.month}",
  214. @gantt.params.merge(:year => month_f.year, :month => month_f.month),
  215. :title => "#{month_name(month_f.month)} #{month_f.year}" %>
  216. <% end %>
  217. <%
  218. left = left + width + 1
  219. month_f = month_f >> 1
  220. %>
  221. <% end %>
  222. <% ###### Weeks headers ###### %>
  223. <% if show_weeks %>
  224. <%
  225. left = 0
  226. height = (show_days ? header_height - 1 : header_height - 1 + g_height)
  227. %>
  228. <% if @gantt.date_from.cwday == 1 %>
  229. <%
  230. # @date_from is monday
  231. week_f = @gantt.date_from
  232. %>
  233. <% else %>
  234. <%
  235. # find next monday after @date_from
  236. week_f = @gantt.date_from + (7 - @gantt.date_from.cwday + 1)
  237. width = (7 - @gantt.date_from.cwday + 1) * zoom - 1
  238. style = ""
  239. style += "left: #{left}px;"
  240. style += "top: 19px;"
  241. style += "width: #{width}px;"
  242. style += "height: #{height}px;"
  243. %>
  244. <%= content_tag(:div, '&nbsp;'.html_safe,
  245. :style => style, :class => "gantt_hdr") %>
  246. <% left = left + width + 1 %>
  247. <% end %>
  248. <% while week_f <= @gantt.date_to %>
  249. <%
  250. width = ((week_f + 6 <= @gantt.date_to) ?
  251. 7 * zoom - 1 :
  252. (@gantt.date_to - week_f + 1) * zoom - 1).to_i
  253. style = ""
  254. style += "left: #{left}px;"
  255. style += "top: 19px;"
  256. style += "width: #{width}px;"
  257. style += "height: #{height}px;"
  258. %>
  259. <%= content_tag(:div, :style => style, :class => "gantt_hdr") do %>
  260. <%= content_tag(:small) do %>
  261. <%= week_f.cweek if width >= 16 %>
  262. <% end %>
  263. <% end %>
  264. <%
  265. left = left + width + 1
  266. week_f = week_f + 7
  267. %>
  268. <% end %>
  269. <% end %>
  270. <% ###### Day numbers headers ###### %>
  271. <% if show_day_num %>
  272. <%
  273. left = 0
  274. height = g_height + header_height*2 - 1
  275. wday = @gantt.date_from.cwday
  276. day_num = @gantt.date_from
  277. %>
  278. <% (@gantt.date_to - @gantt.date_from + 1).to_i.times do %>
  279. <%
  280. width = zoom - 1
  281. style = ""
  282. style += "left:#{left}px;"
  283. style += "top:37px;"
  284. style += "width:#{width}px;"
  285. style += "height:#{height}px;"
  286. style += "font-size:0.7em;"
  287. clss = "gantt_hdr"
  288. clss << " nwday" if @gantt.non_working_week_days.include?(wday)
  289. %>
  290. <%= content_tag(:div, :style => style, :class => clss) do %>
  291. <%= day_num.day %>
  292. <% end %>
  293. <%
  294. left = left + width+1
  295. day_num = day_num + 1
  296. wday = wday + 1
  297. wday = 1 if wday > 7
  298. %>
  299. <% end %>
  300. <% end %>
  301. <% ###### Days headers ####### %>
  302. <% if show_days %>
  303. <%
  304. left = 0
  305. height = g_height + header_height - 1
  306. top = (show_day_num ? 55 : 37)
  307. %>
  308. <% (@gantt.date_from..@gantt.date_to).each do |g_date| %>
  309. <%
  310. width = zoom - 1
  311. style = ""
  312. style += "left: #{left}px;"
  313. style += "top: #{top}px;"
  314. style += "width: #{width}px;"
  315. style += "height: #{height}px;"
  316. style += "font-size:0.7em;"
  317. clss = "gantt_hdr"
  318. clss << " nwday" if @gantt.non_working_week_days.include?(g_date.cwday)
  319. %>
  320. <%= content_tag(:div, :style => style, :class => clss) do %>
  321. <%= day_letter(g_date.cwday) %>
  322. <% end %>
  323. <%
  324. left = left + width + 1
  325. %>
  326. <% end %>
  327. <% end %>
  328. <%= form_tag({}, :data => {:cm_url => issues_context_menu_path}) do -%>
  329. <%= hidden_field_tag 'back_url', url_for(:params => request.query_parameters), :id => nil %>
  330. <%= @gantt.lines.html_safe %>
  331. <% end %>
  332. <% ###### Today red line (excluded from cache) ###### %>
  333. <% if User.current.today >= @gantt.date_from and User.current.today <= @gantt.date_to %>
  334. <%
  335. today_left = (((User.current.today - @gantt.date_from + 1) * zoom).floor() - 1).to_i
  336. style = ""
  337. style += "position: absolute;"
  338. style += "height: #{g_height}px;"
  339. style += "top: #{headers_height + 1}px;"
  340. style += "left: #{today_left}px;"
  341. style += "width:10px;"
  342. style += "border-left: 1px dashed red;"
  343. %>
  344. <%= content_tag(:div, '&nbsp;'.html_safe, :style => style, :id => 'today_line') %>
  345. <% end %>
  346. <%
  347. style = ""
  348. style += "position: absolute;"
  349. style += "height: #{g_height}px;"
  350. style += "top: #{headers_height + 1}px;"
  351. style += "left: 0px;"
  352. style += "width: #{g_width - 1}px;"
  353. %>
  354. <%= content_tag(:div, '', :style => style, :id => "gantt_draw_area") %>
  355. </div>
  356. </td>
  357. </tr>
  358. </table>
  359. <span class="pagination">
  360. <ul class="pages">
  361. <li class="previous page">
  362. <%= link_to("\xc2\xab " + l(:label_previous),
  363. {:params => request.query_parameters.merge(@gantt.params_previous)},
  364. :accesskey => accesskey(:previous)) %>
  365. </li><li class="next page">
  366. <%= link_to(l(:label_next) + " \xc2\xbb",
  367. {:params => request.query_parameters.merge(@gantt.params_next)},
  368. :accesskey => accesskey(:next)) %>
  369. </li>
  370. </ul>
  371. </span>
  372. <% other_formats_links do |f| %>
  373. <%= f.link_to_with_query_parameters 'PDF', @gantt.params %>
  374. <%= f.link_to_with_query_parameters('PNG', @gantt.params) if @gantt.respond_to?('to_image') %>
  375. <% end %>
  376. <% end # query.valid? %>
  377. <% content_for :sidebar do %>
  378. <%= render :partial => 'issues/sidebar' %>
  379. <% end %>
  380. <% html_title(l(:label_gantt)) -%>
  381. <% content_for :header_tags do %>
  382. <%= javascript_include_tag 'raphael' %>
  383. <%= javascript_include_tag 'gantt' %>
  384. <% end %>
  385. <%= javascript_tag do %>
  386. var issue_relation_type = <%= raw Redmine::Helpers::Gantt::DRAW_TYPES.to_json %>;
  387. $(function() {
  388. disable_unavailable_columns('<%= Redmine::Helpers::Gantt::UNAVAILABLE_COLUMNS.map(&:to_s).join(',') %>'.split(','));
  389. drawGanttHandler();
  390. resizableSubjectColumn();
  391. drawSelectedColumns();
  392. $("#draw_relations, #draw_progress_line, #draw_selected_columns").change(drawGanttHandler);
  393. $('div.gantt_subjects .expander').on('click', ganttEntryClick);
  394. });
  395. $(window).resize(function() {
  396. drawGanttHandler();
  397. resizableSubjectColumn();
  398. });
  399. <% end %>
  400. <%= context_menu %>