Skip to content

Commit 5822734

Browse files
committed
[DREAM-688] Use BorderBoxList for document types
Migrate the document types admin index to BorderBoxListComponent, mirroring the enumerations migration. The old two-column header (Type / Documents) is replaced by the list header with a type count; each row renders its document count as a Counter using the same options as the list header counter, minus the primary scheme. Adds spec coverage. https://community.openproject.org/wp/DREAM-688
1 parent 40afbe7 commit 5822734

5 files changed

Lines changed: 110 additions & 30 deletions

File tree

modules/documents/app/components/documents/admin/document_types/index_component.html.erb

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,27 @@
4848
end
4949

5050
flex.with_row do
51-
render(border_box_container(data: drop_target_config)) do |component|
52-
component.with_header(font_weight: :bold) do
53-
grid_layout("op-documents-types-list--header", tag: :div, align_items: :center) do |grid|
54-
grid.with_area(:name, tag: :div, mr: 3) do
55-
render(Primer::Beta::Text.new(font_weight: :semibold)) { I18n.t("documents.index_page.type") }
56-
end
51+
render(
52+
OpenProject::Common::BorderBoxListComponent.new(
53+
container: "#{wrapper_key}-list",
54+
position: :relative,
55+
data: drop_target_config
56+
)
57+
) do |list|
58+
list.with_header(
59+
title: DocumentType.model_name.human(count: :other),
60+
title_tag: :h3,
61+
count: document_types.size
62+
)
5763

58-
grid.with_area(:"documents-count", tag: :div, hide: :sm) do
59-
render(Primer::Beta::Text.new(font_weight: :semibold)) { I18n.t("label_documents") }
60-
end
61-
end
62-
end
64+
list.with_empty_state(
65+
title: t(:no_results_title_text),
66+
spacious: true
67+
)
6368

64-
if document_types.empty?
65-
component.with_row do
66-
render(Primer::Beta::Text.new(color: :subtle)) { t(:no_results_title_text) }
67-
end
68-
else
69-
document_types.each do |document_type|
70-
component.with_row(test_selector: "document-type-row-#{document_type.id}", data: draggable_item_config(document_type)) do
71-
render(item_component_class.new(enumeration: document_type, max_position: max_position))
72-
end
69+
document_types.each do |document_type|
70+
list.with_item(test_selector: "document-type-row-#{document_type.id}", data: draggable_item_config(document_type)) do
71+
render(item_component_class.new(enumeration: document_type, max_position: max_position))
7372
end
7473
end
7574
end

modules/documents/app/components/documents/admin/document_types/index_component.sass

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
.op-documents-types-list--header,
21
.op-documents-types-list--item
32
display: grid
4-
grid-template-columns: 20px 2fr 1fr 1fr
3+
grid-template-columns: auto auto 1fr auto
54
grid-template-areas: "drag-handle name documents-count actions"
5+
column-gap: var(--stack-gap-condensed)
66

7-
&--actions
8-
justify-self: end
7+
&--drag-handle
8+
align-self: center
9+
padding-right: var(--stack-gap-condensed)
10+
cursor: grab
11+
color: var(--fgColor-muted)
912

1013
@media screen and (max-width: $breakpoint-sm)
11-
.op-documents-types-list--header,
1214
.op-documents-types-list--item
13-
grid-template-columns: 20px 1fr 1fr
15+
grid-template-columns: auto 1fr auto
1416
grid-template-areas: "drag-handle name actions"
15-
column-gap: 5px

modules/documents/app/components/documents/admin/document_types/item_component.html.erb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,15 @@
6767
end
6868

6969
grid.with_area(:"documents-count", tag: :div, hide: :sm) do
70-
render(Primer::Beta::Text.new(color: :subtle, test_selector: "documents-count")) do
71-
document_type.documents_count.to_s
72-
end
70+
render(
71+
Primer::Beta::Counter.new(
72+
count: document_type.documents_count,
73+
round: true,
74+
limit: 1_000,
75+
hide_if_zero: true,
76+
test_selector: "documents-count"
77+
)
78+
)
7379
end
7480

7581
grid.with_area(:actions, tag: :div, classes: "hide-when-print") do

modules/documents/config/locales/en.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ en:
4141
document_type:
4242
one_or_more_required: "Cannot delete the last document type"
4343
models:
44+
document_type:
45+
one: "Type"
46+
other: "Types"
4447
document: "Document"
4548
documents: "Documents"
4649
attributes:
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
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 version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
require "rails_helper"
32+
33+
RSpec.describe Documents::Admin::DocumentTypes::IndexComponent, type: :component do
34+
subject(:rendered_component) do
35+
with_controller_class(Documents::Admin::Settings::DocumentTypesController) do
36+
with_request_url("/admin/settings/document_types") do
37+
render_inline(described_class.new(enumerations: document_types))
38+
end
39+
end
40+
end
41+
42+
let(:document_types) { DocumentType.order(:position) }
43+
44+
context "with document types" do
45+
let!(:note_type) { create(:document_type, name: "Note", position: 1) }
46+
let!(:report_type) { create(:document_type, name: "Report", position: 2) }
47+
48+
let(:draggable_records) { [note_type, report_type] }
49+
let(:row_test_selector_prefix) { "document-type-row-" }
50+
let(:move_path_base) { "/admin/settings/document_types" }
51+
52+
it "renders the add action and the list heading with a count", :aggregate_failures do
53+
expect(rendered_component).to have_css("[data-test-selector='admin-document-types-subheader']")
54+
expect(rendered_component).to have_link(I18n.t("documents.button_add_type"))
55+
expect(rendered_component).to have_css("h3", text: DocumentType.model_name.human(count: :other))
56+
expect(rendered_component).to have_css(".Counter", text: "2")
57+
end
58+
59+
it_behaves_like "rendering Box", row_count: 2
60+
it_behaves_like "a reorderable Border Box List"
61+
end
62+
63+
context "without document types" do
64+
it "renders the existing empty result text" do
65+
expect(rendered_component).to have_text(I18n.t(:no_results_title_text))
66+
end
67+
68+
it_behaves_like "rendering Box", row_count: 1
69+
it_behaves_like "rendering Blank Slate", heading: I18n.t(:no_results_title_text)
70+
end
71+
end

0 commit comments

Comments
 (0)