Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#55021] Free choice of columns in exports #16705

Merged
merged 4 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/components/projects/row_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
module Projects
class RowComponent < ::RowComponent
delegate :favored_project_ids, to: :table
delegate :identifier, to: :project

def project
model.first
Expand Down Expand Up @@ -107,6 +108,10 @@ def required_disk_space
number_to_human_size(project.required_disk_space, precision: 2)
end

def id
project.id.to_s
end

def name
content = content_tag(:i, "", class: "projects-table--hierarchy-icon")

Expand Down
9 changes: 1 addition & 8 deletions app/models/projects/exports/query_exporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class QueryExporter < Exports::Exporter
alias :query :object

def columns
@columns ||= (forced_columns + selected_columns)
@columns ||= selected_columns
end

def page
Expand All @@ -51,13 +51,6 @@ def projects

private

def forced_columns
[
{ name: :id, caption: Project.human_attribute_name(:id) },
{ name: :identifier, caption: Project.human_attribute_name(:identifier) }
]
end

def selected_columns
query
.selects
Expand Down
2 changes: 1 addition & 1 deletion app/models/queries/projects/orders/default_order.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ class Queries::Projects::Orders::DefaultOrder < Queries::Orders::Base
self.model = Project

def self.key
/\A(id|created_at|public|lft)\z/
/\A(id|identifier|created_at|public|lft)\z/
end
end
4 changes: 2 additions & 2 deletions app/models/queries/projects/selects/default.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -- copyright
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
Expand Down Expand Up @@ -27,7 +27,7 @@
# ++

class Queries::Projects::Selects::Default < Queries::Selects::Base
KEYS = %i[status_explanation hierarchy name public description].freeze
KEYS = %i[id identifier status_explanation hierarchy name public description].freeze

def self.key
Regexp.new(KEYS.join("|"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@

it "performs a successful export" do
expect(rows.count).to eq(1)
expect(sheet.row(1)).to eq [project.id.to_s, project.identifier,
project.name, project.description, "Off track", "false"]
expect(sheet.row(1)).to eq [project.name, project.description, "Off track", "false"]
end

context "with project description containing html" do
Expand All @@ -38,8 +37,7 @@

it "performs a successful export" do
expect(rows.count).to eq(1)
expect(sheet.row(1)).to eq [project.id.to_s, project.identifier, project.name,
"This is an html description.", "Off track", "false"]
expect(sheet.row(1)).to eq [project.name, "This is an html description.", "Off track", "false"]
end
end

Expand All @@ -48,12 +46,21 @@

it "performs a successful export" do
expect(rows.count).to eq(1)
expect(sheet.row(1)).to eq [project.id.to_s, project.identifier,
project.name, project.description,
expect(sheet.row(1)).to eq [project.name, project.description,
"Off track", project.status_explanation, "false"]
end
end

context "with id and identifier enabled" do
let(:query_columns) { %w[name description project_status public id identifier] }

it "performs a successful export" do
expect(rows.count).to eq(1)
expect(sheet.row(1)).to eq [project.name, project.description, "Off track",
"false", project.id.to_s, project.identifier]
end
end

describe "custom field columns selected" do
let(:query_columns) { %w[name description project_status public] + global_project_custom_fields.map(&:column_name) }

Expand All @@ -66,7 +73,7 @@

it "renders all those columns" do
cf_names = global_project_custom_fields.map(&:name)
expect(header).to eq ["ID", "Identifier", "Name", "Description", "Status", "Public", *cf_names]
expect(header).to eq ["Name", "Description", "Status", "Public", *cf_names]

expect(header).to include not_used_string_cf.name
expect(header).to include hidden_cf.name
Expand All @@ -85,8 +92,7 @@
end

expect(sheet.row(1))
.to eq [project.id.to_s, project.identifier, project.name, project.description, "Off track", "false",
*custom_values]
.to eq [project.name, project.description, "Off track", "false", *custom_values]

# The column for the project-level-disabled custom field is blank
expect(sheet.row(1)[header.index(not_used_string_cf.name)]).to be_nil
Expand All @@ -97,7 +103,7 @@
it "renders available project custom fields in the header if enabled in any project" do
cf_names = global_project_custom_fields.map(&:name)

expect(header).to eq ["ID", "Identifier", "Name", "Description", "Status", "Public", *cf_names]
expect(header).to eq ["Name", "Description", "Status", "Public", *cf_names]

expect(header).not_to include not_used_string_cf.name
expect(header).not_to include hidden_cf.name
Expand All @@ -116,19 +122,18 @@
end

expect(sheet.row(1))
.to eq [project.id.to_s, project.identifier, project.name, project.description, "Off track", "false",
*custom_values]
.to eq [project.name, project.description, "Off track", "false", *custom_values]
end
end

context "without view_project_attributes permission" do
let(:permissions) { %i(view_projects) }

it "does not render project custom fields in the header" do
expect(header).to eq ["ID", "Identifier", "Name", "Description", "Status", "Public"]
expect(header).to eq %w[Name Description Status Public]

expect(sheet.row(1))
.to eq [project.id.to_s, project.identifier, project.name, project.description, "Off track", "false"]
.to eq [project.name, project.description, "Off track", "false"]
end
end
end
Expand Down
31 changes: 18 additions & 13 deletions spec/models/projects/exporter/csv_integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,29 @@

it "performs a successful export" do
expect(parsed.size).to eq(2)
expect(parsed.last).to eq [project.id.to_s, project.identifier,
project.name, project.description, "Off track", "false"]
expect(parsed.last).to eq [project.name, project.description, "Off track", "false"]
end

context "with status_explanation enabled" do
let(:query_columns) { %w[name description project_status status_explanation public] }

it "performs a successful export" do
expect(parsed.size).to eq(2)
expect(parsed.last).to eq [project.id.to_s, project.identifier,
project.name, project.description,
expect(parsed.last).to eq [project.name, project.description,
"Off track", "some explanation", "false"]
end
end

context "with id and identifier selected" do
let(:query_columns) { %w[name description id identifier project_status public] }

it "performs a successful export" do
expect(parsed.size).to eq(2)
expect(parsed.last).to eq [project.name, project.description, project.id.to_s,
project.identifier, "Off track", "false"]
end
end

describe "custom field columns selected" do
let(:query_columns) do
%w[name description project_status public] + global_project_custom_fields.map(&:column_name)
Expand All @@ -74,13 +82,12 @@
it "does not render project custom fields in the header" do
expect(parsed.size).to eq 2

expect(header).to eq ["\xEF\xBB\xBFid", "Identifier", "Name", "Description", "Status", "Public"]
expect(header).to eq ["\xEF\xBB\xBFName", "Description", "Status", "Public"]
end

it "does not render the custom field values in the rows if enabled for a project" do
expect(rows.first)
.to eq [project.id.to_s, project.identifier, project.name,
project.description, "Off track", "false"]
.to eq [project.name, project.description, "Off track", "false"]
end
end

Expand All @@ -93,7 +100,7 @@
expect(cf_names).not_to include(not_used_string_cf.name)
expect(cf_names).not_to include(hidden_cf.name)

expect(header).to eq ["\xEF\xBB\xBFid", "Identifier", "Name", "Description", "Status", "Public", *cf_names]
expect(header).to eq ["\xEF\xBB\xBFName", "Description", "Status", "Public", *cf_names]
end

it "renders the custom field values in the rows if enabled for a project" do
Expand All @@ -110,8 +117,7 @@
end
end
expect(rows.first)
.to eq [project.id.to_s, project.identifier, project.name,
project.description, "Off track", "false", *custom_values]
.to eq [project.name, project.description, "Off track", "false", *custom_values]
end
end

Expand All @@ -126,7 +132,7 @@
expect(cf_names).to include(not_used_string_cf.name)
expect(cf_names).to include(hidden_cf.name)

expect(header).to eq ["\xEF\xBB\xBFid", "Identifier", "Name", "Description", "Status", "Public", *cf_names]
expect(header).to eq ["\xEF\xBB\xBFName", "Description", "Status", "Public", *cf_names]
end

it "renders the custom field values in the rows if enabled for a project" do
Expand All @@ -145,8 +151,7 @@
end
end
expect(rows.first)
.to eq [project.id.to_s, project.identifier, project.name,
project.description, "Off track", "false", *custom_values]
.to eq [project.name, project.description, "Off track", "false", *custom_values]
end
end
end
Expand Down
4 changes: 4 additions & 0 deletions spec/models/queries/projects/project_query_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@
it "lists registered selects" do
expect(instance.available_selects.map(&:attribute))
.to match_array(%i[
id
identifier
name
favored
public
Expand All @@ -151,6 +153,8 @@
it "includes admin columns" do
expect(instance.available_selects.map(&:attribute))
.to match_array(%i[
id
identifier
name
favored
public
Expand Down