Skip to content

Commit

Permalink
apply text attribute component to overview page - using text expander
Browse files Browse the repository at this point in the history
  • Loading branch information
ulferts committed Mar 28, 2024
1 parent f8b746a commit 99b1ac1
Show file tree
Hide file tree
Showing 25 changed files with 544 additions and 464 deletions.
32 changes: 27 additions & 5 deletions app/components/open_project/common/attribute_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,24 +1,46 @@
<div
data-controller="attribute"
data-application-target="dynamic"
data-attribute-background-reference-id-value="<%= background_reference_id %>"
class="op-long-text-attribute">

<%= render(
Primer::Beta::Text.new(tag: :div,
classes: ['op-long-text-attribute--text', PARAGRAPH_CSS_CLASS],
color: text_color,
style: "max-height: #{max_height};",
data: {
'attribute-target': "descriptionText"
})) { short_text } %>
})) { short_text }
%>

<%= render(
Primer::Beta::Text.new(tag: :div,
display: display_expand_button_value,
classes: 'op-long-text-attribute--text-hider',
data: { 'attribute-target': 'textHider' }))
%>

<%= render(
Primer::Alpha::HiddenTextExpander.new(inline: false,
"aria-label": I18n.t('label_attribute_expand_text', attribute: name),
display: display_expand_button_value,
data: {
'attribute-target': 'expandButton',
'test-selector': 'expand-button'
},
button_arguments: { 'data-show-dialog-id': id },
classes: 'op-long-text-attribute--text-expander'
))
%>

<%= render(
Primer::Alpha::Dialog.new(id: id,
data: {
'test-selector': 'attribute-dialog'
},
title: name,
size: :large)) do |component|
component.with_show_button(scheme: :link,
display: display_expand_button_value,
ml: 1,
data: { 'attribute-target': 'expandButton' }) { I18n.t('js.label_expand') }
component.with_body(mt: 2) { full_text }
component.with_header(variant: :large)
end
Expand Down
14 changes: 11 additions & 3 deletions app/components/open_project/common/attribute_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,20 @@ module Common
class AttributeComponent < Primer::Component
attr_reader :id,
:name,
:description
:description,
:lines,
:background_reference_id

PARAGRAPH_CSS_CLASS = "op-uc-p".freeze

def initialize(id, name, description, **args)
def initialize(id, name, description, lines: 1, background_reference_id: "content", **args)
super
@id = id
@name = name
@description = description
@system_arguments = args
@lines = lines
@background_reference_id = background_reference_id
end

def short_text
Expand All @@ -64,6 +68,10 @@ def text_color
:muted if multi_type?
end

def max_height
"#{lines * 1.6}em"
end

private

def first_paragraph
Expand All @@ -88,7 +96,7 @@ def body_children
end

def multi_type?
first_paragraph.include?("figure") || first_paragraph.include?("macro")
first_paragraph.include?("figure") || first_paragraph.include?("macro") || (body_children.any? && first_paragraph.blank?)
end
end
end
Expand Down
18 changes: 14 additions & 4 deletions app/components/open_project/common/attribute_component.sass
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
.op-long-text-attribute
display: flex
align-items: center
position: relative

&--text
@include text-shortener
overflow: hidden
margin: 0
flex-grow: 1
&--text-hider
position: absolute
bottom: 0
right: 0
height: 1.5em
width: 2em
&--text-expander
position: absolute
bottom: 1px
right: 0
float: right
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<%=
component_wrapper do
flex_layout(align_items: :center, justify_content: :space_between, classes: 'op-project-custom-field', data: {
qa_selector: "project-custom-field-#{@project_custom_field.id}"
test_selector: "project-custom-field-#{@project_custom_field.id}"
}) do |custom_field_container|
custom_field_container.with_column(flex_layout: true) do |title_container|
title_container.with_column(pt: 1, mr: 2) do
render(Primer::Beta::Text.new) do
render(Primer::Beta::Text.new) do
@project_custom_field.name
end
end
title_container.with_column(pt: 1, mr: 2, data: { qa_selector: "custom-field-type" } ) do
title_container.with_column(pt: 1, mr: 2, data: { test_selector: "custom-field-type" } ) do
render(Primer::Beta::Text.new(font_size: :small, color: :subtle)) do
@project_custom_field.field_format.capitalize
end
Expand Down Expand Up @@ -37,7 +37,7 @@
),
csrf_token: form_authenticity_token,
data: { 'turbo-method': :put, 'turbo-stream': true,
qa_selector: "toggle-project-custom-field-mapping-#{@project_custom_field.id}" },
test_selector: "toggle-project-custom-field-mapping-#{@project_custom_field.id}" },
checked: active_in_project?,
enabled: !@project_custom_field.required?, # required fields cannot be disabled
size: :small,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<%=
component_wrapper do
render(Primer::Beta::BorderBox.new(mt: 3, classes: 'op-project-custom-field-section', data: {
qa_selector: "project-custom-field-section-#{@project_custom_field_section.id}"
test_selector: "project-custom-field-section-#{@project_custom_field_section.id}"
})) do |component|
component.with_header(font_weight: :bold, py: 2) do
flex_layout(justify_content: :space_between, align_items: :center) do |section_header_container|
Expand All @@ -26,7 +26,7 @@
font_weight: :bold,
color: :subtle,
'aria-label': t('projects.settings.project_custom_fields.actions.label_enable_all'),
data: { 'turbo-method': :put, 'turbo-stream': true, qa_selector: "enable-all-project-custom-field-mappings-#{@project_custom_field_section.id}" }
data: { 'turbo-method': :put, 'turbo-stream': true, test_selector: "enable-all-project-custom-field-mappings-#{@project_custom_field_section.id}" }
)) do |button|
button.with_leading_visual_icon(icon: 'check-circle', color: :subtle)
t('projects.settings.project_custom_fields.actions.label_enable_all')
Expand All @@ -45,7 +45,7 @@
font_weight: :bold,
color: :subtle,
'aria-label': t('projects.settings.project_custom_fields.actions.label_disable_all'),
data: { 'turbo-method': :put, 'turbo-stream': true, qa_selector: "disable-all-project-custom-field-mappings-#{@project_custom_field_section.id}" }
data: { 'turbo-method': :put, 'turbo-stream': true, test_selector: "disable-all-project-custom-field-mappings-#{@project_custom_field_section.id}" }
)) do |button|
button.with_leading_visual_icon(icon: 'x-circle', color: :subtle)
t('projects.settings.project_custom_fields.actions.label_disable_all')
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%=
component_wrapper(class: "op-project-custom-field-container", data: { qa_selector: "project-custom-field-container-#{@project_custom_field.id}" }) do
component_wrapper(class: "op-project-custom-field-container", data: { test_selector: "project-custom-field-container-#{@project_custom_field.id}" }) do
flex_layout(justify_content: :space_between, align_items: :center) do |main_container|
main_container.with_column(flex_layout: true, align_items: :center) do |content_container|
content_container.with_column(mr: 2) do
Expand Down Expand Up @@ -36,7 +36,7 @@
end
end
main_container.with_column do
render(Primer::Alpha::ActionMenu.new(data: { qa_selector: "project-custom-field-action-menu" })) do |menu|
render(Primer::Alpha::ActionMenu.new(data: { test_selector: "project-custom-field-action-menu" })) do |menu|
menu.with_show_button(icon: "kebab-horizontal", 'aria-label': t("settings.project_attributes.label_project_custom_field_actions"), scheme: :invisible)
edit_action_item(menu)
move_actions(menu)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def initialize(project_custom_field:, first_and_last:)
def edit_action_item(menu)
menu.with_item(label: t("label_edit"),
href: edit_admin_settings_project_custom_field_path(@project_custom_field),
data: { turbo: "false", qa_selector: "project-custom-field-edit" }) do |item|
data: { turbo: "false", test_selector: "project-custom-field-edit" }) do |item|
item.with_leading_visual_icon(icon: :pencil)
end
end
Expand All @@ -68,7 +68,7 @@ def move_action_item(menu, move_to, label_text, icon)
menu.with_item(label: label_text,
href: move_admin_settings_project_custom_field_path(@project_custom_field, move_to:),
form_arguments: {
method: :put, data: { 'turbo-stream': true, qa_selector: "project-custom-field-move-#{move_to}" }
method: :put, data: { "turbo-stream": true, test_selector: "project-custom-field-move-#{move_to}" }
}) do |item|
item.with_leading_visual_icon(icon:)
end
Expand All @@ -79,8 +79,8 @@ def delete_action_item(menu)
scheme: :danger,
href: admin_settings_project_custom_field_path(@project_custom_field),
form_arguments: {
method: :delete, data: { confirm: t("text_are_you_sure"), 'turbo-stream': true,
qa_selector: "project-custom-field-delete" }
method: :delete, data: { confirm: t("text_are_you_sure"), "turbo-stream": true,
test_selector: "project-custom-field-delete" }
}) do |item|
item.with_leading_visual_icon(icon: :trash)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<%=
component_wrapper(class: "op-project-custom-field-section-container", data: { qa_selector: "project-custom-field-section-container-#{@project_custom_field_section.id}" }) do
component_wrapper(class: "op-project-custom-field-section-container", data: { test_selector: "project-custom-field-section-container-#{@project_custom_field_section.id}" }) do
render(Primer::Beta::BorderBox.new(mt: 3, data: drag_and_drop_target_config)) do |component|
component.with_header(font_weight: :bold) do
flex_layout(justify_content: :space_between, align_items: :center) do |section_header_container|
Expand All @@ -15,7 +15,7 @@
end
section_header_container.with_column(flex_layout: true, justify_content: :flex_end) do |actions_container|
actions_container.with_column do
render(Primer::Alpha::ActionMenu.new(data: { qa_selector: "project-custom-field-section-action-menu" })) do |menu|
render(Primer::Alpha::ActionMenu.new(data: { test_selector: "project-custom-field-section-action-menu" })) do |menu|
menu.with_show_button(icon: "kebab-horizontal", 'aria-label': t("settings.project_attributes.label_section_actions"), scheme: :invisible)
edit_action_item(menu)
move_actions(menu)
Expand Down Expand Up @@ -50,7 +50,7 @@
type: "ProjectCustomField", custom_field_section_id: @project_custom_field_section.id
),
scheme: :secondary,
data: { turbo: "false", qa_selector: "new-project-custom-field-button" }
data: { turbo: "false", test_selector: "new-project-custom-field-button" }
)) do |button|
button.with_leading_visual_icon(icon: :plus)
t('settings.project_attributes.label_new_attribute')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,18 @@ def wrapper_uniq_by

def drag_and_drop_target_config
{
'is-drag-and-drop-target': true,
'target-container-accessor': '.Box > ul', # the accessor of the container that contains the drag and drop items
'target-id': @project_custom_field_section.id, # the id of the target
'target-allowed-drag-type': 'custom-field' # the type of dragged items which are allowed to be dropped in this target
"is-drag-and-drop-target": true,
"target-container-accessor": ".Box > ul", # the accessor of the container that contains the drag and drop items
"target-id": @project_custom_field_section.id, # the id of the target
"target-allowed-drag-type": "custom-field" # the type of dragged items which are allowed to be dropped in this target
}
end

def draggable_item_config(project_custom_field)
{
'draggable-id': project_custom_field.id,
'draggable-type': 'custom-field',
'drop-url': drop_admin_settings_project_custom_field_path(project_custom_field)
"draggable-id": project_custom_field.id,
"draggable-type": "custom-field",
"drop-url": drop_admin_settings_project_custom_field_path(project_custom_field)
}
end

Expand All @@ -82,7 +82,8 @@ def move_action_item(menu, move_to, label_text, icon)
menu.with_item(label: label_text,
href: move_admin_settings_project_custom_field_section_path(@project_custom_field_section, move_to:),
form_arguments: {
method: :put, data: { 'turbo-stream': true, qa_selector: "project-custom-field-section-move-#{move_to}" }
method: :put, data: { "turbo-stream": true,
test_selector: "project-custom-field-section-move-#{move_to}" }
}) do |item|
item.with_leading_visual_icon(icon:)
end
Expand All @@ -99,8 +100,8 @@ def edit_action_item(menu)
menu.with_item(label: t("settings.project_attributes.label_edit_section"),
tag: :button,
content_arguments: {
'data-show-dialog-id': "project-custom-field-section-dialog#{@project_custom_field_section.id}",
'data-qa-selector': "project-custom-field-section-edit"
"data-show-dialog-id": "project-custom-field-section-dialog#{@project_custom_field_section.id}",
"data-test-selector": "project-custom-field-section-edit"
},
value: "") do |item|
item.with_leading_visual_icon(icon: :pencil)
Expand All @@ -112,8 +113,8 @@ def delete_action_item(menu)
scheme: :danger,
href: admin_settings_project_custom_field_section_path(@project_custom_field_section),
form_arguments: {
method: :delete, data: { confirm: t("text_are_you_sure"), 'turbo-stream': true,
qa_selector: "project-custom-field-section-delete" }
method: :delete, data: { confirm: t("text_are_you_sure"), "turbo-stream": true,
test_selector: "project-custom-field-section-delete" }
}) do |item|
item.with_leading_visual_icon(icon: :trash)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

<%=
component_wrapper do
component_wrapper do
render Primer::OpenProject::PageHeader.new do |header|
header.with_title(variant: :default) { t('settings.project_attributes.heading') }
header.with_description { t('settings.project_attributes.heading_description') }
Expand All @@ -11,7 +11,7 @@
tag: :a,
href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"),
scheme: :primary,
data: { turbo: "false", qa_selector: "new-project-custom-field-button" }
data: { turbo: "false", test_selector: "new-project-custom-field-button" }
)) do |button|
button.with_leading_visual_icon(icon: :plus)
t('settings.project_attributes.label_new_attribute')
Expand Down
3 changes: 2 additions & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1821,6 +1821,7 @@ Project attributes and sections are defined in the <a href=%{admin_settings_url}
label_ldap_auth_source_new: "New LDAP connection"
label_ldap_auth_source: "LDAP connection"
label_ldap_auth_source_plural: "LDAP connections"
label_attribute_expand_text: "The complete text for '%{attribute}'"
label_authentication: "Authentication"
label_available_global_roles: "Available global roles"
label_available_project_forums: "Available forums"
Expand Down Expand Up @@ -2153,7 +2154,7 @@ Project attributes and sections are defined in the <a href=%{admin_settings_url}
label_precedes: "precedes"
label_preferences: "Preferences"
label_preview: "Preview"
label_preview_not_available: "(Preview not available)"
label_preview_not_available: "Preview not available"
label_previous: "Previous"
label_previous_week: "Previous week"
label_principal_invite_via_email: " or invite new users via email"
Expand Down
36 changes: 31 additions & 5 deletions frontend/src/stimulus/controllers/dynamic/attribute.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,46 @@ import { Controller } from '@hotwired/stimulus';

export default class AttributeController extends Controller {
static targets = [
'descriptionText',
'expandButton',
'textHider',
];

declare readonly descriptionTextTarget:HTMLParagraphElement;
static values = {
backgroundReferenceId: { type: String, default: 'content' },
};

declare backgroundReferenceIdValue:string;

declare readonly expandButtonTarget:HTMLButtonElement;
declare readonly textHiderTarget:HTMLElement;

descriptionTextTargetConnected(element:HTMLParagraphElement) {
if (this.isEllipssed(element)) {
this.expandButtonTarget.classList.remove('d-none');
this.setBackgroundToReference();
this.unhideElement(this.textHiderTarget);
this.unhideElement(this.expandButtonTarget);
}
}

private isEllipssed(e:HTMLElement) {
return (e.offsetWidth < e.scrollWidth || e.offsetHeight < e.scrollHeight);
}

// Sets the background of the text hider element (the one below the expand button) to the background of the reference.
// That reference by default is the `#content` element. This is necessary so that the text hider can actually lay on top
// of the text and hide it without being obvious. It would have been sufficient to just use the button element for this
// if that button were not using a background color with an 0.2 alpha value. Without the text hider, the text would
// shine through.
private setBackgroundToReference() {
const backgroundReference = document.getElementById(this.backgroundReferenceIdValue);
if (backgroundReference) {
const backgroundColor = window.getComputedStyle(backgroundReference).backgroundColor;
this.textHiderTarget.style.backgroundColor = backgroundColor;
this.textHiderTarget.classList.remove('d-none');
}
}

isEllipssed(e:HTMLElement) {
return (e.offsetWidth < e.scrollWidth);
private unhideElement(element:HTMLElement) {
element.classList.remove('d-none');
}
}
Loading

0 comments on commit 99b1ac1

Please sign in to comment.