Project

General

Profile

Feature #34307 » 34307-copy-custom-field.patch

Takenori TAKAKI, 2020-12-04 01:56

View differences:

app/controllers/custom_fields_controller.rb
98 98
    if @custom_field.nil?
99 99
      render :action => 'select_type'
100 100
    else
101
      if params[:copy].present? && @copy_from = CustomField.find_by_id(params[:copy])
102
        @custom_field.copy_from(@copy_from)
103
      end
101 104
      @custom_field.safe_attributes = params[:custom_field]
102 105
    end
103 106
  end
app/models/custom_field.rb
95 95
    'extensions_allowed',
96 96
    'full_width_layout')
97 97

  
98
  def copy_from(arg, options={})
99
    return if arg.blank?
100
    custom_field = arg.is_a?(CustomField) ? arg : CustomField.find_by_id(arg.to_s)
101
    self.attributes = custom_field.attributes.dup.except("id", "name", "position")
102
    custom_field.enumerations.each do |e|
103
      new_enumeration = self.enumerations.build
104
      new_enumeration.attributes = e.attributes.except("id")
105
    end
106
    self.default_value = nil if custom_field.enumerations.any?
107
    if %w(IssueCustomField TimeEntryCustomField ProjectCustomField VersionCustomField).include?(self.class.name)
108
      self.role_ids = custom_field.role_ids.dup
109
    end
110
    if self.is_a?(IssueCustomField)
111
      self.tracker_ids = custom_field.tracker_ids.dup
112
      self.project_ids = custom_field.project_ids.dup
113
    end
114
    self
115
  end
116

  
98 117
  def format
99 118
    @format ||= Redmine::FieldFormat.find(field_format)
100 119
  end
app/views/custom_fields/_index.html.erb
22 22
      <% end %>
23 23
      <td class="buttons">
24 24
        <%= reorder_handle(custom_field, :url => custom_field_path(custom_field), :param => 'custom_field') %>
25
        <%= link_to_function l(:button_copy), "location.href = '#{new_custom_field_path(:copy => custom_field)}&type=' + encodeURIComponent(($('.tabs a.selected').attr('id')||'').split('tab-').pop())", :class => 'icon icon-copy' %>
25 26
        <%= delete_link custom_field_path(custom_field) %>
26 27
      </td>
27 28
    </tr>
app/views/custom_fields/new.html.erb
3 3
<%= labelled_form_for :custom_field, @custom_field, :url => custom_fields_path, :html => {:id => 'custom_field_form'} do |f| %>
4 4
<%= render :partial => 'form', :locals => { :f => f } %>
5 5
<%= hidden_field_tag 'type', @custom_field.type %>
6
<%= hidden_field_tag 'copy', @copy_from.id if @copy_from %>
6 7
<% end %>
7 8

  
8 9
<%= javascript_tag do %>
test/functional/custom_fields_controller_test.rb
325 325
    assert_select 'input[type=radio][name=type]'
326 326
  end
327 327

  
328
  def test_new_with_copy
329
    role_ids = [1, 2]
330
    tracker_ids = [1, 2]
331
    project_ids = [1, 2, 3]
332

  
333
    copy_from = CustomField.find(1)
334
    copy_from.role_ids = role_ids
335
    copy_from.tracker_ids = tracker_ids
336
    copy_from.project_ids = project_ids
337
    copy_from.save
338

  
339
    get :new, :params => {:copy => copy_from.id.to_s, :type => IssueCustomField}
340
    assert_response :success
341

  
342
    assert_select 'form' do
343
      # field_format selected
344
      assert_select 'select[name=?]', 'custom_field[field_format]' do
345
        assert_select "option[value=\"#{copy_from.field_format}\"][selected=selected]"
346
      end
347
      # blank name
348
      assert_select 'input[name=?][value=""]', 'custom_field[name]'
349
      # description copied
350
      assert_select 'textarea[name=?]', 'custom_field[description]', :text => copy_from.description
351
      # role checked
352
      role_ids.each do |role_id|
353
        assert_select "input[type=checkbox][name=?][value=#{role_id}][checked=checked]", 'custom_field[role_ids][]'
354
      end
355
      # role not checked
356
      (Role.givable.pluck(:id) - role_ids).each do |role_id|
357
        assert_select "input[type=checkbox][name=?][value=#{role_id}]", 'custom_field[role_ids][]'
358
      end
359
      # tracker checked
360
      tracker_ids.each do |tracker_id|
361
        assert_select "input[type=checkbox][name=?][value=#{tracker_id}][checked=checked]", 'custom_field[tracker_ids][]'
362
      end
363
      # tracker not checked
364
      (Tracker.all.pluck(:id) - tracker_ids).each do |tracker_id|
365
        assert_select "input[type=checkbox][name=?][value=#{tracker_id}]", 'custom_field[tracker_ids][]'
366
      end
367
      # project checked
368
      project_ids.each do |project_id|
369
        assert_select "input[type=checkbox][name=?][value=#{project_id}][checked=checked]", 'custom_field[project_ids][]'
370
      end
371
      # project not checked
372
      (Project.all.pluck(:id) - project_ids).each do |project_id|
373
        assert_select "input[type=checkbox][name=?][value=#{project_id}]", 'custom_field[project_ids][]'
374
      end
375
    end
376
  end
377

  
328 378
  def test_create_list_custom_field
329 379
    field = new_record(IssueCustomField) do
330 380
      post(
......
423 473
    assert_select 'input[type=radio][name=type]'
424 474
  end
425 475

  
476
  def test_create_with_enumerations
477
    custom_field = IssueCustomField.create(:field_format => 'enumeration', :name => 'IssueCustomField')
478
    custom_field.enumerations.build(:name => 'enumeration1', :position => 1)
479
    custom_field.enumerations.build(:name => 'enumeration2', :position => 2)
480
    assert custom_field.save
481

  
482
    assert_difference 'CustomField.count' do
483
      post(
484
        :create,
485
        :params => {
486
          :type => "IssueCustomField",
487
          :copy => custom_field.id,
488
          :custom_field => { :name => "Copy" }
489
        }
490
      )
491
      assert_response 302
492
    end
493
    field = IssueCustomField.order("id desc").first
494
    assert_equal "Copy", field.name
495
    assert_equal ["enumeration1", "enumeration2"], field.enumerations.pluck(:name).sort
496
    assert_equal [1, 2], field.enumerations.pluck(:position).sort
497
  end
498

  
426 499
  def test_edit
427 500
    get(
428 501
      :edit,
test/unit/custom_field_test.rb
372 372
    field2 = IssueCustomField.create!(:name => 'Another long text', :field_format => 'text')
373 373
    assert !field2.full_text_formatting?
374 374
  end
375

  
376
  def test_copy_from
377
    custom_field = CustomField.find(1)
378
    copy = CustomField.new.copy_from(custom_field)
379

  
380
    assert_nil copy.id
381
    assert_equal '', copy.name
382
    assert_nil copy.position
383
    (custom_field.attribute_names - ['id', 'name', 'position']).each do |attribute_name|
384
      assert_equal custom_field.send(attribute_name).to_s, copy.send(attribute_name).to_s
385
    end
386

  
387
    copy.name = 'Copy'
388
    assert copy.save
389
  end
390

  
391
  def test_copy_from_should_copy_enumerations
392
    custom_field = CustomField.create(:field_format => 'enumeration', :name => 'CustomField')
393
    custom_field.enumerations.build(:name => 'enumeration1', :position => 1)
394
    custom_field.enumerations.build(:name => 'enumeration2', :position => 2)
395
    assert custom_field.save
396

  
397
    copy = CustomField.new.copy_from(custom_field)
398
    copy.name = 'Copy'
399
    assert copy.save
400
    assert_equal ['enumeration1', 'enumeration2'], copy.enumerations.pluck(:name)
401
    assert_equal [1, 2], copy.enumerations.pluck(:position)
402
  end
403

  
404
  def test_copy_from_should_copy_roles
405
    %w(IssueCustomField TimeEntryCustomField ProjectCustomField VersionCustomField).each do |klass_name|
406
      klass = klass_name.constantize
407
      custom_field = klass.new(:name => klass_name, :role_ids => [1, 2, 3, 4, 5])
408
      copy = klass.new.copy_from(custom_field)
409
      assert_equal [1, 2, 3, 4, 5], copy.role_ids.sort
410
    end
411
  end
412

  
413
  def test_copy_from_should_copy_trackers
414
    issue_custom_field = IssueCustomField.new(:name => 'IssueCustomField', :tracker_ids => [1, 2, 3])
415
    copy = IssueCustomField.new.copy_from(issue_custom_field)
416
    assert_equal [1, 2, 3], copy.tracker_ids
417
  end
418

  
419
  def test_copy_from_should_copy_projects
420
    issue_custom_field = IssueCustomField.new(:name => 'IssueCustomField', :project_ids => [1, 2, 3, 4, 5, 6])
421
    copy = IssueCustomField.new.copy_from(issue_custom_field)
422
    assert_equal [1, 2, 3, 4, 5, 6], copy.project_ids
423
  end
375 424
end
(2-2/2)