diff --git a/app/assets/javascripts/timelines.js b/app/assets/javascripts/timelines.js index 786596435f..6b877b502f 100644 --- a/app/assets/javascripts/timelines.js +++ b/app/assets/javascripts/timelines.js @@ -4079,7 +4079,7 @@ Timeline = { rebuildTree: function() { var where = this.getUiRoot().find('.tl-left-main'); var tree = this.getLefthandTree(); - var table = jQuery('
'); + var table = jQuery('
'); var body = jQuery(''); var head = jQuery(''); var row, cell, link, span, text; diff --git a/app/assets/javascripts/timelines_autocompleter.js b/app/assets/javascripts/timelines_autocompleter.js index 85df82353e..5096edba4f 100644 --- a/app/assets/javascripts/timelines_autocompleter.js +++ b/app/assets/javascripts/timelines_autocompleter.js @@ -33,34 +33,41 @@ if (!(this.element.attr("data-ajaxURL") === "" || this.element.attr("data-ajaxURL") === null || this.element.attr("data-ajaxURL") === undefined)) { this.opts.ajax.url = this.element.attr("data-ajaxURL"); } - + if (!($(this.element).attr("data-values") === "" || $(this.element).attr("data-values") === null || $(this.element).attr("data-values") === undefined)) { + this.opts.data.results = JSON.parse($(this.element).attr('data-values')); + delete this.opts.ajax; + } }, setupInput: function () { var attrs_to_copy = {}, currentName, select2id, values = []; - $("input[name='" + $(this.element).attr("name")+"']").remove(); + if ($(this.element).is("input")) { + this.fakeInput = $(this.element); + } else { + $("input[name='" + $(this.element).attr("name")+"']").remove(); - for(var i = 0; i < $(this.element).get(0).attributes.length; i++) { - currentName = $(this.element).get(0).attributes[i].name; - if(currentName.indexOf("data-") === 0 || $.inArray(currentName, this.opts.allowedAttributes) !== -1) { //only ones starting with data- - attrs_to_copy[currentName] = $(this.element).attr(currentName); + for(var i = 0; i < $(this.element).get(0).attributes.length; i++) { + currentName = $(this.element).get(0).attributes[i].name; + if(currentName.indexOf("data-") === 0 || $.inArray(currentName, this.opts.allowedAttributes) !== -1) { //only ones starting with data- + attrs_to_copy[currentName] = $(this.element).attr(currentName); + } } - } - select2id = $(this.element).attr("id"); - this.fakeInput = $(this.element).after("").siblings(":input#" + select2id); - this.fakeInput.attr(attrs_to_copy); - if (!($(this.element).attr("data-selected") === "" || $(this.element).attr("data-selected") === null || $(this.element).attr("data-selected") === undefined)) { - JSON.parse($(this.element).attr('data-selected')).each(function (elem) { - values.push(elem[1]); - }); - this.fakeInput.val(values); + select2id = $(this.element).attr("id"); + this.fakeInput = $(this.element).after("").siblings(":input#" + select2id); + this.fakeInput.attr(attrs_to_copy); + if (!($(this.element).attr("data-selected") === "" || $(this.element).attr("data-selected") === null || $(this.element).attr("data-selected") === undefined)) { + JSON.parse($(this.element).attr('data-selected')).each(function (elem) { + values.push(elem[1]); + }); + this.fakeInput.val(values); + } + $(this.element).remove(); } }, initSelect2: function () { - $(this.element).remove(); $(this.fakeInput).select2(this.opts); if (this.opts.sortable) { @@ -85,10 +92,11 @@ $(this).each(function () { autocompleter = new TimelinesAutocompleter($(this), args); }); - } + }; $.fn.timelinesAutocomplete.defaults = { multiple: true, + data: {}, allowedAttributes: ["title", "placeholder", "id", "name"], minimumInputLength: 0, ajax: { @@ -147,8 +155,22 @@ JSON.parse($(element).attr('data-selected')).each(function (elem) { data.push({id: elem[1], name: elem[0]}); }); + } else if (element.is("input") && !(element.attr("data-values") === "" || element.attr("data-values") === null || element.attr("data-values") === undefined)) { + var possible = JSON.parse(element.attr('data-values')); + var vals = element.val().split(","); + var byID = {}; + + var i; + for (i = 0; i < possible.length; i += 1) { + byID[possible[i].id] = possible[i]; + } + + for (i = 0; i < vals.length; i += 1) { + data.push(byID[vals[i]]); + } } - return callback(data); + + callback(data); } - } + }; }(jQuery)); \ No newline at end of file diff --git a/app/assets/javascripts/timelines_select_boxes.js b/app/assets/javascripts/timelines_select_boxes.js index 2dddc161af..140430d595 100644 --- a/app/assets/javascripts/timelines_select_boxes.js +++ b/app/assets/javascripts/timelines_select_boxes.js @@ -15,7 +15,6 @@ jQuery(document).ready(function($) { [ $("#reporting_reported_project_status_id"), $("#timeline_select"), - $("#timeline_options_columns"), $("#timeline_options_initial_outline_expansion"), $("#timeline_options_zoom_factor"), $("#timeline_options_compare_to_relative_unit"), @@ -44,6 +43,11 @@ jQuery(document).ready(function($) { $(item).timelinesAutocomplete({ ajax: {null_element: {id: -1, name: I18n.t("js.timelines.filter.none")}} }) }); + var item = $("#timeline_options_columns_"); + item.timelinesAutocomplete({ + sortable: true + }); + [ $("#reporting_reporting_to_project_id"), $("#project_association_select_project_b_id") diff --git a/app/assets/stylesheets/timelines.css b/app/assets/stylesheets/timelines.css index 09db016911..fa9463973b 100644 --- a/app/assets/stylesheets/timelines.css +++ b/app/assets/stylesheets/timelines.css @@ -50,7 +50,7 @@ li.select2-result.select2-visible-selected-parent { margin-bottom: 8px; } -#s2id_timeline_options_grouping_one_selection .select2-search-choice { +#content .ui-sortable .select2-search-choice { cursor: move; } diff --git a/app/helpers/timelines_helper.rb b/app/helpers/timelines_helper.rb index 7e8b0c31fc..387110fa5d 100644 --- a/app/helpers/timelines_helper.rb +++ b/app/helpers/timelines_helper.rb @@ -270,6 +270,15 @@ module TimelinesHelper collection end + def internationalized_columns_select_object(collection) + collection.map do |t| + { + :name => l("timelines.filter.column." + t), + :id => t + } + end + end + def internationalized_columns_select(collection) collection.map do |t| [l("timelines.filter.column." + t), t] diff --git a/app/models/timeline.rb b/app/models/timeline.rb index 3254d4fbf3..d08daa9fdb 100644 --- a/app/models/timeline.rb +++ b/app/models/timeline.rb @@ -167,18 +167,18 @@ class Timeline < ActiveRecord::Base # that are reporting into the project that this timeline is # referencing. - PlanningElementType.find(:all, :order => :name) + Type.find(:all, :order => :name) end def selected_planning_element_types resolve_with_none_element(:planning_element_types) do |ary| - PlanningElementType.find(ary) + Type.find(ary) end end def selected_planning_element_time_types resolve_with_none_element(:planning_element_time_types) do |ary| - PlanningElementType.find(ary) + Type.find(ary) end end diff --git a/app/views/timelines/_general.html.erb b/app/views/timelines/_general.html.erb index c781fe3560..b0597a5366 100644 --- a/app/views/timelines/_general.html.erb +++ b/app/views/timelines/_general.html.erb @@ -87,13 +87,21 @@ See doc/COPYRIGHT.rdoc for more details. <%= label_tag 'timeline_options_columns', l("timelines.filter.columns") %> - <%= select("timeline[options]", - :columns, - internationalized_columns_select(timeline.available_columns), - {:selected => timeline.selected_columns}, - {:multiple => true, - :size => 12}) %> - + <% if User.current.impaired? %> + <%= select("timeline[options]", + :columns, + internationalized_columns_select(timeline.available_columns), + {:selected => timeline.selected_columns}, + {:multiple => true, + :size => 12}) %> + <% else %> + <%= hidden_field_tag("timeline[options][columns][]", + timeline.selected_columns.join(","), + { + :"data-values" => internationalized_columns_select_object(timeline.available_columns).to_json + } + ) %> + <% end %>

diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md index 6ff4306390..6ffa70e3d4 100644 --- a/doc/CHANGELOG.md +++ b/doc/CHANGELOG.md @@ -12,6 +12,7 @@ See doc/COPYRIGHT.rdoc for more details. # Changelog +* `#1913` [Timelines] Enable drag&drop for select2 items in order to rearrange the order of the columns * `#2019` Migrate auto completes controller tests ## 3.0.0pre16 diff --git a/features/step_definitions/timelines_then_steps.rb b/features/step_definitions/timelines_then_steps.rb index cd398e2da0..d3a9d2f6c9 100644 --- a/features/step_definitions/timelines_then_steps.rb +++ b/features/step_definitions/timelines_then_steps.rb @@ -16,6 +16,21 @@ Then /^I should see a modal window with selector "(.*?)"$/ do |selector| dialog["class"].include?("ui-dialog-content").should be_true end +Then(/^I should see the column "(.*?)" before the column "(.*?)" in the timelines table$/) do |content1, content2| + steps %Q{ + Then I should see the column "#{content1}" before the column "#{content2}" in ".tl-main-table" + } +end +Then(/^I should see the column "(.*?)" before the column "(.*?)" in "(.*?)"$/) do |content1, content2, table| + #Check that the things really exist and wait until the exist + steps %Q{ + Then I should see "#{content1}" within "#{table}" + Then I should see "#{content2}" within "#{table}" + } + + elements = find_lowest_containing_element content2, table + elements[-1].should have_xpath("preceding::th/descendant-or-self::*[text()='#{content1}']") +end Then /^I should see a modal window$/ do steps 'Then I should see a modal window with selector "#modalDiv"' end diff --git a/features/step_definitions/timelines_when_steps.rb b/features/step_definitions/timelines_when_steps.rb index 9fa995ad1f..e6a8a1eea5 100644 --- a/features/step_definitions/timelines_when_steps.rb +++ b/features/step_definitions/timelines_when_steps.rb @@ -86,7 +86,28 @@ When (/^I set the second level grouping criteria to "(.*?)" for the timeline "(. page.execute_script("jQuery('#timeline_options_grouping_two_selection').val('#{project_type.id}')") page.execute_script("jQuery('#content form').submit()") end +When(/^I set the columns shown in the timeline to:$/) do |table| + timeline_name = @timeline_name + project_name = @project.name + steps %Q{ + When I go to the edit page of the timeline "#{timeline_name}" of the project called "#{project_name}" + } + result = [] + table.raw.each do |_perm| + perm = _perm.first + unless perm.blank? + result.push(perm) + end + end + results = result.join(","); + + #we need to wait for our submit form to load ... + page.should have_selector("#timeline_options_columns_", :visible => false) + + page.execute_script("jQuery('#timeline_options_columns_').val('#{results}')") + page.execute_script("jQuery('#content form').submit()") +end When (/^I set the first level grouping criteria to:$/) do |table| timeline_name = @timeline_name project_name = @project.name diff --git a/features/timelines/timeline_view.feature b/features/timelines/timeline_view.feature index d2b2c2ab55..68b7d820ed 100644 --- a/features/timelines/timeline_view.feature +++ b/features/timelines/timeline_view.feature @@ -47,6 +47,19 @@ Feature: Timeline View Tests And I wait for timeline to load table Then the first table column should not take more than 25% of the space + @javascript + Scenario: Select columns + Given I am working in the timeline "Testline" of the project called "ecookbook" + When there is a timeline "Testline" for project "ecookbook" + And I set the columns shown in the timeline to: + | start_date | + | type | + | end_date | + Then I should see the column "Start date" before the column "End date" in the timelines table + And I should see the column "Start date" before the column "Type" in the timelines table + And I should see the column "Type" before the column "End date" in the timelines table + + @javascript Scenario: switch timeline When there is a timeline "Testline" for project "ecookbook"