erb_lint auto fix layout

This commit is contained in:
Ivan Kuchin
2025-02-06 18:00:11 +01:00
parent fb715f21b9
commit 0f6a12da3a
553 changed files with 6474 additions and 4808 deletions
@@ -33,10 +33,14 @@ See COPYRIGHT and LICENSE files for more details.
<ul class="op-activity-list">
<%=
render(Activities::ItemComponent.with_collection(events,
current_project: @current_project,
display_user: @display_user,
activity_page: @activity_page))
render(
Activities::ItemComponent.with_collection(
events,
current_project: @current_project,
display_user: @display_user,
activity_page: @activity_page
)
)
%>
</ul>
<% end -%>
@@ -37,13 +37,15 @@ See COPYRIGHT and LICENSE files for more details.
<%= project_suffix %>
</div>
<%=
render(Activities::ItemSubtitleComponent.new(
user: display_user? && @event.event_author,
datetime: @event.event_datetime,
is_creation: initial?,
is_deletion: deletion?,
is_work_package: work_package?,
journable_type: @event.journal.journable_type)
render(
Activities::ItemSubtitleComponent.new(
user: display_user? && @event.event_author,
datetime: @event.event_datetime,
is_creation: initial?,
is_deletion: deletion?,
is_work_package: work_package?,
journable_type: @event.journal.journable_type
)
)
%>
<% if comment.present? -%>
@@ -29,7 +29,8 @@ See COPYRIGHT and LICENSE files for more details.
<div class="op-activity-list--item-subtitle">
<%=
I18n.t(i18n_key,
I18n.t(
i18n_key,
user: user_html,
datetime: datetime_html
).html_safe
+14 -10
View File
@@ -1,10 +1,14 @@
<%= render(Primer::ButtonComponent.new(scheme: :primary,
aria: { label: aria_label },
title:,
test_selector:,
tag: :a,
id:,
href: dynamic_path) ) do |button|
button.with_leading_visual_icon(icon: :plus)
label_text
end %>
<%= render(
Primer::ButtonComponent.new(
scheme: :primary,
aria: { label: aria_label },
title:,
test_selector:,
tag: :a,
id:,
href: dynamic_path
)
) do |button|
button.with_leading_visual_icon(icon: :plus)
label_text
end %>
@@ -30,22 +30,24 @@ See COPYRIGHT and LICENSE files for more details.
<% helpers.html_title t(:label_administration), @title %>
<%= render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { t(:"attributes.attachments") }
header.with_breadcrumbs([{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_storages_path, text: t("project_module_storages") },
t(:"attributes.attachments")])
header.with_tab_nav(label: nil) do |tab_nav|
tab_nav.with_tab(selected: @selected == 1, href: admin_settings_attachments_path) do |tab|
tab.with_text { t("settings.general") }
end
tab_nav.with_tab(selected: @selected == 2, href: admin_settings_virus_scanning_path) do |tab|
tab.with_icon(icon: :"op-enterprise-addons") unless EnterpriseToken.allows_to?("virus_scanning")
tab.with_text { t(:"settings.antivirus.title") }
end
if User.current.admin? && (EnterpriseToken.allows_to?(:virus_scanning) || Attachment.status_quarantined.any?)
tab_nav.with_tab(selected: @selected == 3, href: admin_quarantined_attachments_path) do |tab|
tab.with_text { t(:"antivirus_scan.quarantined_attachments.title") }
header.with_title { t(:"attributes.attachments") }
header.with_breadcrumbs(
[{ href: admin_index_path, text: t("label_administration") },
{ href: admin_settings_storages_path, text: t("project_module_storages") },
t(:"attributes.attachments")]
)
header.with_tab_nav(label: nil) do |tab_nav|
tab_nav.with_tab(selected: @selected == 1, href: admin_settings_attachments_path) do |tab|
tab.with_text { t("settings.general") }
end
tab_nav.with_tab(selected: @selected == 2, href: admin_settings_virus_scanning_path) do |tab|
tab.with_icon(icon: :"op-enterprise-addons") unless EnterpriseToken.allows_to?("virus_scanning")
tab.with_text { t(:"settings.antivirus.title") }
end
if User.current.admin? && (EnterpriseToken.allows_to?(:virus_scanning) || Attachment.status_quarantined.any?)
tab_nav.with_tab(selected: @selected == 3, href: admin_quarantined_attachments_path) do |tab|
tab.with_text { t(:"antivirus_scan.quarantined_attachments.title") }
end
end
end
end
end
end %>
end %>
@@ -29,34 +29,40 @@ See COPYRIGHT and LICENSE files for more details.
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { t(:label_backup) }
header.with_breadcrumbs([{ href: admin_index_path, text: t(:label_administration) },
t(:label_backup)])
header.with_breadcrumbs(
[{ href: admin_index_path, text: t(:label_administration) },
t(:label_backup)]
)
header.with_action_button(tag: :a,
scheme: button_scheme,
mobile_label: button_title,
mobile_icon: button_icon,
size: :medium,
href: reset_token_admin_backups_path,
aria: { label: button_title },
title: button_title) do |button|
header.with_action_button(
tag: :a,
scheme: button_scheme,
mobile_label: button_title,
mobile_icon: button_icon,
size: :medium,
href: reset_token_admin_backups_path,
aria: { label: button_title },
title: button_title
) do |button|
button.with_leading_visual_icon(icon: button_icon)
button_title
end
if @backup_token.present?
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t("backup.label_delete_token"),
size: :medium,
href: delete_token_admin_backups_path,
aria: { label: I18n.t("backup.label_delete_token") },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :post
},
title: I18n.t(:button_delete)) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t("backup.label_delete_token"),
size: :medium,
href: delete_token_admin_backups_path,
aria: { label: I18n.t("backup.label_delete_token") },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :post
},
title: I18n.t(:button_delete)
) do |button|
button.with_leading_visual_icon(icon: :trash)
t("backup.label_delete_token")
end
@@ -30,22 +30,28 @@ See COPYRIGHT and LICENSE files for more details.
<%=
component_wrapper do
primer_form_with(
model: ,
model:,
url:,
data: { turbo: true },
method: :post
) do |form|
concat(render(Primer::Alpha::Dialog::Body.new(
id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title },
classes: "Overlay-body_autocomplete_height"
)) do
render(Projects::CustomFields::CustomFieldMappingForm.new(form, project_mapping: @custom_field_project_mapping))
end)
concat(
render(
Primer::Alpha::Dialog::Body.new(
id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title },
classes: "Overlay-body_autocomplete_height"
)
) do
render(Projects::CustomFields::CustomFieldMappingForm.new(form, project_mapping: @custom_field_project_mapping))
end
)
concat(render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do
concat(render(Primer::ButtonComponent.new(data: { 'close-dialog-id': dialog_id })) { cancel_button_text })
concat(render(Primer::ButtonComponent.new(scheme: :primary, type: :submit)) { submit_button_text })
end)
concat(
render(Primer::Alpha::Dialog::Footer.new(show_divider: false)) do
concat(render(Primer::ButtonComponent.new(data: { 'close-dialog-id': dialog_id })) { cancel_button_text })
concat(render(Primer::ButtonComponent.new(scheme: :primary, type: :submit)) { submit_button_text })
end
)
end
end
%>
@@ -28,12 +28,14 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%=
render(Primer::OpenProject::DangerDialog.new(
title: I18n.t("custom_fields.admin.items.delete_dialog.title"),
form_arguments:,
size: :large,
test_selector: TEST_SELECTOR
)) do |dialog|
render(
Primer::OpenProject::DangerDialog.new(
title: I18n.t("custom_fields.admin.items.delete_dialog.title"),
form_arguments:,
size: :large,
test_selector: TEST_SELECTOR
)
) do |dialog|
dialog.with_confirmation_message do |message|
message.with_heading(tag: :h2) { I18n.t("custom_fields.admin.items.delete_dialog.heading") }
message.with_description_content(I18n.t("custom_fields.admin.items.delete_dialog.description"))
@@ -58,9 +58,11 @@ See COPYRIGHT and LICENSE files for more details.
item_container.with_column do
render(Primer::Alpha::ActionMenu.new(test_selector: "op-hierarchy-item--action-menu")) do |menu|
menu.with_show_button(icon: "kebab-horizontal",
scheme: :invisible,
"aria-label": I18n.t("custom_fields.admin.items.actions"))
menu.with_show_button(
icon: "kebab-horizontal",
scheme: :invisible,
"aria-label": I18n.t("custom_fields.admin.items.actions")
)
menu_items(menu)
end
end
@@ -31,8 +31,10 @@ See COPYRIGHT and LICENSE files for more details.
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { t(:label_custom_style) }
header.with_breadcrumbs([{ href: admin_index_path, text: t(:label_administration) },
t(:label_custom_style)])
header.with_breadcrumbs(
[{ href: admin_index_path, text: t(:label_administration) },
t(:label_custom_style)]
)
header.with_description { t(:label_custom_style_description) }
if @tabs.present?
@@ -32,18 +32,20 @@ See COPYRIGHT and LICENSE files for more details.
header.with_breadcrumbs(breadcrumb_items)
if @color.persisted?
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: color_path(@color),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :delete
},
title: I18n.t(:button_delete)) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: color_path(@color),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :delete
},
title: I18n.t(:button_delete)
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -3,10 +3,12 @@
flex_layout do |content|
if has_no_items_or_projects?
content.with_row(mb: 3) do
render Primer::Alpha::Banner.new(scheme: :default,
icon: :info,
dismiss_scheme: :hide,
test_selector: "op-custom-fields--new-hierarchy-banner") do
render Primer::Alpha::Banner.new(
scheme: :default,
icon: :info,
dismiss_scheme: :hide,
test_selector: "op-custom-fields--new-hierarchy-banner"
) do
I18n.t("custom_fields.admin.notice.remember_items_and_projects")
end
end
@@ -2,9 +2,13 @@
grid_layout("op-ee-banner", **@system_arguments) do |grid|
grid.with_area(:'icon-container') do
content_tag :div, class: "op-ee-banner--shield" do
render(Primer::Beta::Octicon.new(icon: "op-enterprise-addons",
size: :medium,
classes: "op-ee-banner--icon"))
render(
Primer::Beta::Octicon.new(
icon: "op-enterprise-addons",
size: :medium,
classes: "op-ee-banner--icon"
)
)
end
end
grid.with_area(:'title-container') { render(Primer::Beta::Text.new) { title } }
@@ -1,9 +1,13 @@
<%= component_wrapper tag: "turbo-frame" do %>
<%= render(Primer::Beta::Button.new(scheme: :secondary,
disabled:,
data: { "filter--filters-form-target": "filterFormToggle",
action: "filter--filters-form#toggleDisplayFilters" },
test_selector: "filter-component-toggle")) do |button| %>
<%= render(
Primer::Beta::Button.new(
scheme: :secondary,
disabled:,
data: { "filter--filters-form-target": "filterFormToggle",
action: "filter--filters-form#toggleDisplayFilters" },
test_selector: "filter-component-toggle"
)
) do |button| %>
<% button.with_trailing_visual_counter(count: filters_count, test_selector: "filters-button-counter") %>
<%= t(:label_filter) %>
<% end %>
@@ -31,30 +31,34 @@ See COPYRIGHT and LICENSE files for more details.
header.with_title { @group.name }
header.with_breadcrumbs(breadcrumb_items)
header.with_action_button(tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: show_group_path(@group),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: show_group_path(@group),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)
) do |button|
button.with_leading_visual_icon(icon: :person)
t(:label_profile)
end
if @current_user.admin?
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -28,34 +28,38 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title(test_selector: "groups--title") { @group.name }
header.with_title(test_selector: "groups--title") { @group.name }
header.with_breadcrumbs(breadcrumb_items)
if @current_user.admin?
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_group_path(@group),
aria: { label: I18n.t(:button_edit) },
data: { "test-selector": "groups--edit-group-button" },
title: I18n.t(:button_edit)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_group_path(@group),
aria: { label: I18n.t(:button_edit) },
data: { "test-selector": "groups--edit-group-button" },
title: I18n.t(:button_edit)
) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: group_path(@group),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: t(:text_are_you_sure),
method: :delete,
},
title: I18n.t(:button_delete)
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -28,7 +28,7 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%= form_tag(filter_path, method: :get) do %>
<% collapsed_class = initially_visible? ? "" : "collapsed" %>
<% collapsed_class = initially_visible? ? "" : "collapsed" %>
<fieldset class="simple-filters--container <%= collapsed_class %>" data-members-form-target="filterContainer">
<legend><%= t(:label_filter_plural) %></legend>
<% if has_close_icon? %>
@@ -51,14 +51,14 @@ See COPYRIGHT and LICENSE files for more details.
<li class="simple-filters--filter">
<label class='simple-filters--filter-name' for='group_id'><%= Group.model_name.human %>:</label>
<%= collection_select :group,
:id,
groups,
:id,
:name,
{ include_blank: true,
selected: params[:group_id].to_i },
{ name: "group_id",
class: "simple-filters--filter-value" } %>
:id,
groups,
:id,
:name,
{ include_blank: true,
selected: params[:group_id].to_i },
{ name: "group_id",
class: "simple-filters--filter-value" } %>
</li>
<% end %>
<% if roles.present? %>
@@ -78,7 +78,8 @@ See COPYRIGHT and LICENSE files for more details.
{
name: "role_id",
class: "simple-filters--filter-value"
})
}
)
%>
</li>
<% end %>
@@ -96,7 +97,8 @@ See COPYRIGHT and LICENSE files for more details.
include_blank: true,
name: "shared_role_id",
class: "simple-filters--filter-value"
})
}
)
%>
</li>
<% end %>
@@ -1,22 +1,26 @@
<%= render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_filter_button(label: I18n.t(:description_filter),
id: "filter-member-button",
aria: { label: I18n.t(:description_filter) },
class: "toggle-member-filter-link",
data: filter_button_data_attributes) do
I18n.t(:description_filter)
end
subheader.with_filter_button(
label: I18n.t(:description_filter),
id: "filter-member-button",
aria: { label: I18n.t(:description_filter) },
class: "toggle-member-filter-link",
data: filter_button_data_attributes
) do
I18n.t(:description_filter)
end
subheader.with_action_button(scheme: :primary,
aria: { label: I18n.t(:button_add_member) },
title: I18n.t(:button_add_member),
id: "add-member-button",
data: add_button_data_attributes) do |button|
button.with_leading_visual_icon(icon: :plus)
t("activerecord.models.member")
end
subheader.with_action_button(
scheme: :primary,
aria: { label: I18n.t(:button_add_member) },
title: I18n.t(:button_add_member),
id: "add-member-button",
data: add_button_data_attributes
) do |button|
button.with_leading_visual_icon(icon: :plus)
t("activerecord.models.member")
end
subheader.with_bottom_pane_component do
render ::Members::UserFilterComponent.new(params, **@members_filter_options)
end
end %>
subheader.with_bottom_pane_component do
render ::Members::UserFilterComponent.new(params, **@members_filter_options)
end
end %>
@@ -6,48 +6,54 @@
watcher_action_button(header, @topic)
if !@topic.locked? && authorize_for("messages", "reply")
header.with_action_button(tag: :a,
scheme: :default,
mobile_icon: :quote,
mobile_label: t(:button_quote),
size: :medium,
href: url_for({ action: "quote", id: @topic }),
aria: { label: I18n.t(:button_delete) },
data: { 'action': "forum-messages#quote", test_selector: "message-quote-button" },
title: t(:button_quote)) do |button|
header.with_action_button(
tag: :a,
scheme: :default,
mobile_icon: :quote,
mobile_label: t(:button_quote),
size: :medium,
href: url_for({ action: "quote", id: @topic }),
aria: { label: I18n.t(:button_delete) },
data: { 'action': "forum-messages#quote", test_selector: "message-quote-button" },
title: t(:button_quote)
) do |button|
button.with_leading_visual_icon(icon: :quote)
t(:button_quote)
end
end
if @message.editable_by?(User.current)
header.with_action_button(tag: :a,
scheme: :default,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_topic_path(@topic),
aria: { label: t(:button_edit) },
data: { test_selector: "message-edit-button" },
title: t(:button_edit)) do |button|
header.with_action_button(
tag: :a,
scheme: :default,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_topic_path(@topic),
aria: { label: t(:button_edit) },
data: { test_selector: "message-edit-button" },
title: t(:button_edit)
) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
end
if @message.destroyable_by?(User.current)
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: topic_path(@topic),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :delete
},
title: I18n.t(:button_delete)) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: topic_path(@topic),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :delete
},
title: I18n.t(:button_delete)
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -28,11 +28,13 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%=
render(Primer::OpenProject::FeedbackDialog.new(
id:,
title: I18n.t("my.access_token.create_dialog.title"),
size: :large
)) do |dialog|
render(
Primer::OpenProject::FeedbackDialog.new(
id:,
title: I18n.t("my.access_token.create_dialog.title"),
size: :large
)
) do |dialog|
dialog.with_feedback_message do |message|
message.with_heading(tag: :h2) { I18n.t("my.access_token.create_dialog.header", type: "API") }
end
@@ -41,15 +43,18 @@ See COPYRIGHT and LICENSE files for more details.
flex_layout do |flex|
flex.with_row(mb: 2) do
render(Primer::OpenProject::InputGroup.new) do |input_group|
input_group.with_text_input(name: :openproject_api_access_token,
label: Token::API.model_name.human,
visually_hide_label: false,
value: @token_value)
input_group.with_text_input(
name: :openproject_api_access_token,
label: Token::API.model_name.human,
visually_hide_label: false,
value: @token_value
)
input_group.with_trailing_action_clipboard_copy_button(
value: @token_value,
aria: {
label: I18n.t("button_copy_to_clipboard")
})
}
)
end
end
flex.with_row do
@@ -36,9 +36,11 @@ See COPYRIGHT and LICENSE files for more details.
method: :post
) do |form|
component_collection do |collection|
collection.with_component(Primer::Alpha::Dialog::Body.new(
aria: { label: I18n.t("my.access_token.new_access_token_dialog_title") }
)) do
collection.with_component(
Primer::Alpha::Dialog::Body.new(
aria: { label: I18n.t("my.access_token.new_access_token_dialog_title") }
)
) do
flex_layout(mb: 3) do |body|
body.with_row do
render(Primer::Alpha::Banner.new(scheme: :warning)) do
@@ -1,15 +1,17 @@
<%= render(Primer::OpenProject::PageHeader.new) do |header|
header.with_title { page_title }
header.with_breadcrumbs(breadcrumb_items, selected_item_font_weight: current_breadcrumb_element == page_title ? :bold : :normal)
header.with_title { page_title }
header.with_breadcrumbs(breadcrumb_items, selected_item_font_weight: current_breadcrumb_element == page_title ? :bold : :normal)
header.with_action_button(tag: :a,
mobile_icon: :gear,
mobile_label: I18n.t(:label_setting_plural),
href: my_notifications_path,
size: :medium,
target: "_blank",
aria: { label: I18n.t("js.notifications.settings.title") }) do |button|
button.with_leading_visual_icon(icon: :gear)
I18n.t(:label_setting_plural)
end
end %>
header.with_action_button(
tag: :a,
mobile_icon: :gear,
mobile_label: I18n.t(:label_setting_plural),
href: my_notifications_path,
size: :medium,
target: "_blank",
aria: { label: I18n.t("js.notifications.settings.title") }
) do |button|
button.with_leading_visual_icon(icon: :gear)
I18n.t(:label_setting_plural)
end
end %>
@@ -1,25 +1,31 @@
<%= render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_filter_component do
render(Primer::Alpha::SegmentedControl.new("aria-label": I18n.t(:label_filter_plural))) do |control|
control.with_item(tag: :a,
href: notifications_path(facet: nil, **current_filters),
label: t("notifications.facets.unread"),
title: t("notifications.facets.unread_title"),
selected: @facet != "all")
control.with_item(tag: :a,
href: notifications_path(facet: "all", **current_filters),
label: t("notifications.facets.all"),
title: t("notifications.facets.all_title"),
selected: @facet == "all")
end
end
subheader.with_filter_component do
render(Primer::Alpha::SegmentedControl.new("aria-label": I18n.t(:label_filter_plural))) do |control|
control.with_item(
tag: :a,
href: notifications_path(facet: nil, **current_filters),
label: t("notifications.facets.unread"),
title: t("notifications.facets.unread_title"),
selected: @facet != "all"
)
control.with_item(
tag: :a,
href: notifications_path(facet: "all", **current_filters),
label: t("notifications.facets.all"),
title: t("notifications.facets.all_title"),
selected: @facet == "all"
)
end
end
subheader.with_action_button(tag: :a,
href: mark_all_read_notifications_path(**current_filters),
data: { method: :post },
size: :medium,
aria: { label: I18n.t("js.notifications.center.mark_all_read") }) do |button|
button.with_leading_visual_icon(icon: :'op-read-all')
I18n.t("js.notifications.center.mark_all_read")
end
end %>
subheader.with_action_button(
tag: :a,
href: mark_all_read_notifications_path(**current_filters),
data: { method: :post },
size: :medium,
aria: { label: I18n.t("js.notifications.center.mark_all_read") }
) do |button|
button.with_leading_visual_icon(icon: :'op-read-all')
I18n.t("js.notifications.center.mark_all_read")
end
end %>
@@ -29,14 +29,16 @@
# Actions
oauth_application_container.with_column do
render(Primer::Alpha::ToggleSwitch.new(
src: toggle_oauth_application_path(@application),
csrf_token: form_authenticity_token,
checked: @application.enabled?,
data: {
'test-selector': "op-admin-oauth--application-enabled-toggle-switch"
}
))
render(
Primer::Alpha::ToggleSwitch.new(
src: toggle_oauth_application_path(@application),
csrf_token: form_authenticity_token,
checked: @application.enabled?,
data: {
'test-selector': "op-admin-oauth--application-enabled-toggle-switch"
}
)
)
end
end
end
@@ -3,9 +3,13 @@
flex_layout do |index_container|
if OpenProject::FeatureDecisions.built_in_oauth_applications_active?
index_container.with_row do
render(border_box_container(mb: 4, data: {
'test-selector': "op-admin-oauth--built-in-applications"
})) do |component|
render(
border_box_container(
mb: 4, data: {
'test-selector': "op-admin-oauth--built-in-applications"
}
)
) do |component|
component.with_header(font_weight: :bold) do
render(Primer::Beta::Text.new) do
t("oauth.header.builtin_applications")
@@ -14,9 +18,13 @@
if @built_in_applications.empty?
component.with_row do
render(Primer::Beta::Text.new(data: {
'test-selector': "op-admin-oauth--built-in-applications-placeholder"
})) do
render(
Primer::Beta::Text.new(
data: {
'test-selector': "op-admin-oauth--built-in-applications-placeholder"
}
)
) do
t("oauth.empty_application_lists")
end
end
@@ -33,29 +33,33 @@ See COPYRIGHT and LICENSE files for more details.
header.with_breadcrumbs(breadcrumb_items)
unless @application.builtin?
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_oauth_application_path(@application),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_oauth_application_path(@application),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)
) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: oauth_application_path(@application),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :delete
},
title: I18n.t(:button_delete)) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: oauth_application_path(@application),
aria: { label: I18n.t(:button_delete) },
data: {
confirm: I18n.t(:text_are_you_sure),
method: :delete
},
title: I18n.t(:button_delete)
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -32,20 +32,33 @@ See COPYRIGHT and LICENSE files for more details.
border_box_container(
classes: container_class,
test_selector:,
)) do |component|
)
) do |component|
component.with_header(classes: grid_class, color: :muted) do
headers.each do |name, args|
concat render(Primer::Beta::Text.new(classes: header_classes(name),
font_weight: :semibold,
**header_args(name))) { args[:caption] }
concat render(
Primer::Beta::Text.new(
classes: header_classes(name),
font_weight: :semibold,
**header_args(name)
)
) { args[:caption] }
end
concat render(Primer::Beta::Text.new(classes: "op-border-box-grid--mobile-heading",
font_weight: :semibold)) { mobile_title }
concat render(
Primer::Beta::Text.new(
classes: "op-border-box-grid--mobile-heading",
font_weight: :semibold
)
) { mobile_title }
if has_actions?
concat render(Primer::BaseComponent.new(classes: heading_class,
tag: :div))
concat render(
Primer::BaseComponent.new(
classes: heading_class,
tag: :div
)
)
end
end
@@ -2,12 +2,14 @@
flex_layout(align_items: :center, **@system_arguments) do |flex|
if @scheme == :link
flex.with_column(classes: "ellipsis") do
render(Primer::Beta::Link.new(
id: @id,
href: value,
title: value,
target: :_blank
)) { value }
render(
Primer::Beta::Link.new(
id: @id,
href: value,
title: value,
target: :_blank
)
) { value }
end
else
flex.with_column(classes: "ellipsis") do
@@ -19,19 +19,23 @@
hidden_user_list.with_row(mt: 1) { item.to_s }
end
hidden_user_list.with_row(mt: 2) do
render(Primer::Beta::Button.new(
scheme: :link,
data: { action: "expandable-list#hideElements" }
)) { I18n.t("label_show_less") }
render(
Primer::Beta::Button.new(
scheme: :link,
data: { action: "expandable-list#hideElements" }
)
) { I18n.t("label_show_less") }
end
end
end
list.with_row(mt: 2) do
render(Primer::Beta::Button.new(
scheme: :link,
data: { "expandable-list-target": "showButton",
action: "expandable-list#showElements" }
)) { I18n.t("label_show_more") }
render(
Primer::Beta::Button.new(
scheme: :link,
data: { "expandable-list-target": "showButton",
action: "expandable-list#showElements" }
)
) { I18n.t("label_show_more") }
end
end
end
@@ -28,15 +28,17 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%=
render(Primer::BaseComponent.new(
tag: :div,
classes: "op-primer-flash--item",
data: {
"flash-target": "item",
"autohide": @autohide,
unique_key: @unique_key
}.compact
)) do
render(
Primer::BaseComponent.new(
tag: :div,
classes: "op-primer-flash--item",
data: {
"flash-target": "item",
"autohide": @autohide,
unique_key: @unique_key
}.compact
)
) do
render_parent
end
%>
@@ -5,40 +5,51 @@
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 } %>
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 } %>
<%= render(
Primer::Beta::Text.new(tag: :div,
display: display_expand_button_value,
classes: "op-long-text-attribute--text-hider",
data: { 'attribute-target': "textHider" })) %>
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"
)) %>
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_body { full_text }
component.with_header(variant: :large)
end %>
Primer::Alpha::Dialog.new(
id: id,
data: {
'test-selector': "attribute-dialog"
},
title: name,
size: :large
)
) do |component|
component.with_body { full_text }
component.with_header(variant: :large)
end %>
</div>
@@ -1,26 +1,30 @@
<div class="op-submenu" data-controller="filter--filter-list" data-application-target="dynamic" data-test-selector="op-submenu">
<% if @searchable %>
<div class="op-submenu--search">
<%= render Primer::Alpha::TextField.new(name: "search",
label: I18n.t("label_search"),
placeholder: I18n.t("label_search_by_name"),
leading_visual: { icon: :search },
visually_hide_label: true,
classes: "op-submenu--search-input",
data: {
action: "input->filter--filter-list#filterLists",
"filter--filter-list-target": "filter",
"test-selector": "op-submenu--search-input"
},) %>
<%= render Primer::Alpha::TextField.new(
name: "search",
label: I18n.t("label_search"),
placeholder: I18n.t("label_search_by_name"),
leading_visual: { icon: :search },
visually_hide_label: true,
classes: "op-submenu--search-input",
data: {
action: "input->filter--filter-list#filterLists",
"filter--filter-list-target": "filter",
"test-selector": "op-submenu--search-input"
},
) %>
<%= render Primer::Beta::Text.new(display: :none,
classes: "op-submenu--search-no-results-container",
data: {
"test-selector": "op-submenu--search-no-results",
"filter--filter-list-target": "noResultsText",
}) do
I18n.t("js.autocompleter.notFoundText")
end %>
<%= render Primer::Beta::Text.new(
display: :none,
classes: "op-submenu--search-no-results-container",
data: {
"test-selector": "op-submenu--search-no-results",
"filter--filter-list-target": "noResultsText",
}
) do
I18n.t("js.autocompleter.notFoundText")
end %>
</div>
<% end %>
@@ -99,18 +103,20 @@
<% if @create_btn_options.present? %>
<div class="op-submenu--footer">
<%= render Primer::Beta::Button.new(scheme: :primary,
tag: :a,
href: @create_btn_options[:href],
test_selector: "#{@create_btn_options[:module_key]}--create-button",
classes: "op-submenu--footer-action") do |button|
button.with_leading_visual_icon(icon: "plus")
if @create_btn_options[:btn_text].present?
@create_btn_options[:btn_text]
else
I18n.t("label_#{@create_btn_options[:module_key]}")
end
end %>
<%= render Primer::Beta::Button.new(
scheme: :primary,
tag: :a,
href: @create_btn_options[:href],
test_selector: "#{@create_btn_options[:module_key]}--create-button",
classes: "op-submenu--footer-action"
) do |button|
button.with_leading_visual_icon(icon: "plus")
if @create_btn_options[:btn_text].present?
@create_btn_options[:btn_text]
else
I18n.t("label_#{@create_btn_options[:module_key]}")
end
end %>
</div>
<% end %>
</div>
@@ -33,27 +33,31 @@ See COPYRIGHT and LICENSE files for more details.
header.with_breadcrumbs(breadcrumb_items)
unless new_record?
header.with_action_button(tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: placeholder_user_path(@placeholder_user),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: placeholder_user_path(@placeholder_user),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)
) do |button|
button.with_leading_visual_icon(icon: :person)
t(:label_profile)
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
disabled: !deletable?,
href: delete_button_href,
aria: { label: I18n.t(:button_delete) },
data: { "test-selector": "placeholder-user--delete-button" },
title: delete_button_title) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
disabled: !deletable?,
href: delete_button_href,
aria: { label: I18n.t(:button_delete) },
data: { "test-selector": "placeholder-user--delete-button" },
title: delete_button_title
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -32,29 +32,33 @@ See COPYRIGHT and LICENSE files for more details.
header.with_breadcrumbs(breadcrumb_items)
if @current_user.allowed_globally?(:manage_placeholder_user)
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
accesskey: accesskey(:edit),
href: edit_placeholder_user_path(@placeholder_user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
accesskey: accesskey(:edit),
href: edit_placeholder_user_path(@placeholder_user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)
) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
end
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
disabled: !deletable?,
href: delete_button_href,
aria: { label: I18n.t(:button_delete) },
data: { "test-selector": "placeholder-user--delete-button" },
title: delete_button_title) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
disabled: !deletable?,
href: delete_button_href,
aria: { label: I18n.t(:button_delete) },
data: { "test-selector": "placeholder-user--delete-button" },
title: delete_button_title
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -1,10 +1,14 @@
<%= render(Primer::Alpha::Dialog.new(title: t(:'queries.configure_view.heading'),
size: :large,
id: MODAL_ID,
# Hack to give the draggable autcompleter (ng-select) bound to the dialog
# enough height to display all options.
# This is necessary as long as ng-select does not support popovers.
style: "min-height: 480px")) do |d| %>
<%= render(
Primer::Alpha::Dialog.new(
title: t(:'queries.configure_view.heading'),
size: :large,
id: MODAL_ID,
# Hack to give the draggable autcompleter (ng-select) bound to the dialog
# enough height to display all options.
# This is necessary as long as ng-select does not support popovers.
style: "min-height: 480px"
)
) do |d| %>
<% d.with_header(variant: :large) %>
<%= render(Primer::Alpha::Dialog::Body.new) do %>
<%= primer_form_with(
@@ -14,26 +18,26 @@
method: :get
) do |form| %>
<% helpers.projects_query_params.except(:columns, :sortBy).each do |name, value| %>
<%= hidden_field_tag name, value, data: {"sort-by-config-target" => name} %>
<%= hidden_field_tag name, value, data: { "sort-by-config-target" => name } %>
<% end %>
<%= render(Primer::Alpha::TabPanels.new(label: "label")) do |tab_panel| %>
<% tab_panel.with_tab(selected: true, id: "tab-selects--columns") do |tab| %>
<% tab.with_text { I18n.t("label_columns") } %>
<% tab.with_panel do %>
<%= helpers.angular_component_tag "opce-draggable-autocompleter",
inputs: {
options: helpers.projects_columns_options,
selected: selected_columns,
protected: helpers.protected_projects_columns_options,
name: COLUMN_HTML_NAME,
id: COLUMN_HTML_ID,
dragAreaName: "#{COLUMN_HTML_ID}_dragarea",
formControlId: "#{COLUMN_HTML_ID}_autocompleter",
inputLabel: I18n.t(:'queries.configure_view.columns.input_label'),
inputPlaceholder: I18n.t(:'queries.configure_view.columns.input_placeholder'),
dragAreaLabel: I18n.t(:'queries.configure_view.columns.drag_area_label'),
appendToComponent: true
} %>
inputs: {
options: helpers.projects_columns_options,
selected: selected_columns,
protected: helpers.protected_projects_columns_options,
name: COLUMN_HTML_NAME,
id: COLUMN_HTML_ID,
dragAreaName: "#{COLUMN_HTML_ID}_dragarea",
formControlId: "#{COLUMN_HTML_ID}_autocompleter",
inputLabel: I18n.t(:'queries.configure_view.columns.input_label'),
inputPlaceholder: I18n.t(:'queries.configure_view.columns.input_placeholder'),
dragAreaLabel: I18n.t(:'queries.configure_view.columns.drag_area_label'),
appendToComponent: true
} %>
<% end %>
<% end %>
<% tab_panel.with_tab(id: "tab-selects--sorting") do |tab| %>
@@ -47,9 +51,13 @@
<% end %>
<%= render(Primer::Alpha::Dialog::Footer.new) do %>
<%= render(Primer::ButtonComponent.new(data: { "close-dialog-id": MODAL_ID })) { I18n.t(:button_cancel) } %>
<%= render(Primer::ButtonComponent.new(scheme: :primary,
type: :submit,
data: { "test-selector": "#{MODAL_ID}-submit"},
form: QUERY_FORM_ID)) { I18n.t(:button_apply) } %>
<%= render(
Primer::ButtonComponent.new(
scheme: :primary,
type: :submit,
data: { "test-selector": "#{MODAL_ID}-submit" },
form: QUERY_FORM_ID
)
) { I18n.t(:button_apply) } %>
<% end %>
<% end %>
@@ -1,15 +1,25 @@
<%= render(Primer::Alpha::Dialog.new(title: t(:'projects.lists.delete_modal.title'),
size: :large,
id: MODAL_ID,
data: { 'test-selector': MODAL_ID })) do |d| %>
<%= render(
Primer::Alpha::Dialog.new(
title: t(:'projects.lists.delete_modal.title'),
size: :large,
id: MODAL_ID,
data: { 'test-selector': MODAL_ID }
)
) do |d| %>
<% d.with_header(variant: :large) %>
<% d.with_body { t(:'projects.lists.delete_modal.text') } %>
<% d.with_footer do %>
<%= render(Primer::Beta::Button.new(data: { "close-dialog-id": MODAL_ID })) { I18n.t(:button_cancel) } %>
<%= form_with(url: project_query_path(query),
method: :delete) do %>
<%= render(Primer::Beta::Button.new(scheme: :danger,
type: :submit)) { I18n.t(:button_delete) } %>
<%= form_with(
url: project_query_path(query),
method: :delete
) do %>
<%= render(
Primer::Beta::Button.new(
scheme: :danger,
type: :submit
)
) { I18n.t(:button_delete) } %>
<% end %>
<% end %>
<% end %>
@@ -1,6 +1,8 @@
<p class="information-section">
<%= helpers.op_icon("icon-info1") %>
<%= t(:label_projects_disk_usage_information,
<%= t(
:label_projects_disk_usage_information,
count: Project.count,
used_disk_space: number_to_human_size(Project.total_projects_size, precision: 2)) %>
used_disk_space: number_to_human_size(Project.total_projects_size, precision: 2)
) %>
</p>
@@ -1,5 +1,9 @@
<%= render(Primer::Alpha::Dialog.new(title: t("js.label_export"),
id: MODAL_ID)) do |d| %>
<%= render(
Primer::Alpha::Dialog.new(
title: t("js.label_export"),
id: MODAL_ID
)
) do |d| %>
<% d.with_header(variant: :large) %>
<% d.with_body do %>
<ul class="op-export-options">
@@ -2,15 +2,17 @@
<%=
render(Primer::OpenProject::PageHeader.new(state: @state)) do |header|
header.with_title(data: { 'test-selector': "project-query-name" }) do |title|
title.with_editable_form(model: query,
update_path: @query.new_record? ? project_queries_path(projects_query_params) : project_query_path(@query, projects_query_params),
method: @query.new_record? ? :post : :put,
cancel_path: projects_path(**projects_query_params, **{ query_id: query.id }.compact),
input_name: "name",
label: ProjectQuery.human_attribute_name(:name),
placeholder: I18n.t(:"projects.lists.new.placeholder"),
scope: "query",
id: "project-save-form")
title.with_editable_form(
model: query,
update_path: @query.new_record? ? project_queries_path(projects_query_params) : project_query_path(@query, projects_query_params),
method: @query.new_record? ? :post : :put,
cancel_path: projects_path(**projects_query_params, **{ query_id: query.id }.compact),
input_name: "name",
label: ProjectQuery.human_attribute_name(:name),
placeholder: I18n.t(:"projects.lists.new.placeholder"),
scope: "query",
id: "project-save-form"
)
page_title
end
header.with_breadcrumbs(breadcrumb_items, selected_item_font_weight: current_breadcrumb_element == page_title ? :bold : :normal)
@@ -136,7 +138,7 @@
tag: :a,
label: t(:'queries.configure_view.heading'),
href: configure_view_modal_project_queries_path(projects_query_params),
content_arguments: { data: { controller: "async-dialog" }}
content_arguments: { data: { controller: "async-dialog" } }
) do |item|
item.with_leading_visual_icon(icon: :gear)
end
@@ -147,7 +149,7 @@
label: t(:button_delete),
scheme: :danger,
href: destroy_confirmation_modal_project_query_path(query.id),
content_arguments: { data: { controller: "async-dialog" }}
content_arguments: { data: { controller: "async-dialog" } }
) do |item|
item.with_leading_visual_icon(icon: "trash")
end
@@ -155,8 +157,7 @@
menu.with_item(
tag: :button,
label: t("label_zen_mode"),
content_arguments: { data: { controller: "projects-zen-mode", target: "projects-zen-mode.button", action: "click->projects-zen-mode#performAction" }
}
content_arguments: { data: { controller: "projects-zen-mode", target: "projects-zen-mode.button", action: "click->projects-zen-mode#performAction" } }
) do |item|
item.with_leading_visual_icon(icon: "screen-full")
end
@@ -1,33 +1,37 @@
<%= component_wrapper(tag: "turbo-frame") do %>
<%= render(Primer::OpenProject::SubHeader.new(data: sub_header_data_attributes)) do |subheader|
subheader.with_filter_input(name: "name_and_identifier",
label: t("projects.index.search.label"),
value: filter_input_value,
placeholder: t("projects.index.search.placeholder"),
leading_visual: {
icon: :search,
size: :small
},
clear_button_id: clear_button_id,
data: filter_input_data_attributes)
subheader.with_filter_input(
name: "name_and_identifier",
label: t("projects.index.search.label"),
value: filter_input_value,
placeholder: t("projects.index.search.placeholder"),
leading_visual: {
icon: :search,
size: :small
},
clear_button_id: clear_button_id,
data: filter_input_data_attributes
)
subheader.with_filter_component do
render(Projects::ProjectFilterButtonComponent.new(query: @query, disabled: @disable_buttons))
end
subheader.with_filter_component do
render(Projects::ProjectFilterButtonComponent.new(query: @query, disabled: @disable_buttons))
end
subheader.with_action_button(tag: :a,
href: new_project_path,
scheme: :primary,
disabled: @disable_buttons,
size: :medium,
aria: { label: I18n.t(:label_project_new) },
data: { 'test-selector': "project-new-button" }) do |button|
button.with_leading_visual_icon(icon: :plus)
Project.model_name.human
end if @current_user.allowed_globally?(:add_project)
subheader.with_action_button(
tag: :a,
href: new_project_path,
scheme: :primary,
disabled: @disable_buttons,
size: :medium,
aria: { label: I18n.t(:label_project_new) },
data: { 'test-selector': "project-new-button" }
) do |button|
button.with_leading_visual_icon(icon: :plus)
Project.model_name.human
end if @current_user.allowed_globally?(:add_project)
subheader.with_bottom_pane_component(mt: 0) do
render(Projects::ProjectsFiltersComponent.new(query: @query))
end
end %>
subheader.with_bottom_pane_component(mt: 0) do
render(Projects::ProjectsFiltersComponent.new(query: @query))
end
end %>
<% end %>
@@ -1,8 +1,8 @@
<%= flex_layout(align_items: :center) do |type_container|
type_container.with_column(mr: 1, classes: icon_color_class) do
render Primer::Beta::Octicon.new(icon: icon)
end
type_container.with_column do
render(Primer::Beta::Text.new(**text_options)) { text }
end
end %>
type_container.with_column(mr: 1, classes: icon_color_class) do
render Primer::Beta::Octicon.new(icon: icon)
end
type_container.with_column do
render(Primer::Beta::Text.new(**text_options)) { text }
end
end %>
@@ -1,32 +1,38 @@
<%=
render Primer::OpenProject::PageHeader.new do |header|
header.with_title { t(:label_information_plural) }
header.with_breadcrumbs( [
{ href: project_overview_path(@project.id), text: @project.name },
{ href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings") },
t(:label_information_plural)
])
header.with_breadcrumbs(
[
{ href: project_overview_path(@project.id), text: @project.name },
{ href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings") },
t(:label_information_plural)
]
)
if User.current.allowed_in_project?(:add_subprojects, @project)
header.with_action_button(scheme: :primary,
mobile_icon: :plus,
mobile_label: t(:label_subproject_new),
aria: { label: t(:label_subproject_new) },
title: t(:label_subproject_new),
tag: :a,
href: new_project_path(parent_id: @project.id)) do |button|
header.with_action_button(
scheme: :primary,
mobile_icon: :plus,
mobile_label: t(:label_subproject_new),
aria: { label: t(:label_subproject_new) },
title: t(:label_subproject_new),
tag: :a,
href: new_project_path(parent_id: @project.id)
) do |button|
button.with_leading_visual_icon(icon: :plus)
t(:label_subproject)
end
end
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t("projects.settings.change_identifier"),
size: :medium,
href: project_identifier_path(@project),
aria: { label: t("projects.settings.change_identifier") },
title: t("projects.settings.change_identifier")) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :pencil,
mobile_label: t("projects.settings.change_identifier"),
size: :medium,
href: project_identifier_path(@project),
aria: { label: t("projects.settings.change_identifier") },
title: t("projects.settings.change_identifier")
) do |button|
button.with_leading_visual_icon(icon: :pencil)
t("projects.settings.change_identifier")
end
@@ -43,14 +49,14 @@
) do |menu|
if @project.copy_allowed?
menu.with_item(
label:t(:button_copy),
label: t(:button_copy),
href: copy_project_path(@project),
content_arguments: {
data: { turbo: false },
test_selector: "project-settings--copy"
},
accesskey: helpers.accesskey(:copy),
) do |item|
) do |item|
item.with_leading_visual_icon(icon: :copy)
end
end
@@ -2,20 +2,22 @@
flex_layout(data: wrapper_data_attributes) do |flex|
flex.with_row do
render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_filter_input(name: "border-box-filter",
label: t("projects.settings.life_cycle.filter.label"),
visually_hide_label: true,
placeholder: t("projects.settings.life_cycle.filter.label"),
leading_visual: {
icon: :search,
size: :small
},
show_clear_button: true,
clear_button_id: clear_button_id,
data: {
action: "input->projects--settings--border-box-filter#filterLists",
"projects--settings--border-box-filter-target": "filter"
})
subheader.with_filter_input(
name: "border-box-filter",
label: t("projects.settings.life_cycle.filter.label"),
visually_hide_label: true,
placeholder: t("projects.settings.life_cycle.filter.label"),
leading_visual: {
icon: :search,
size: :small
},
show_clear_button: true,
clear_button_id: clear_button_id,
data: {
action: "input->projects--settings--border-box-filter#filterLists",
"projects--settings--border-box-filter-target": "filter"
}
)
end
end
@@ -32,29 +34,33 @@
end
header_container.with_column(flex_layout: true, justify_content: :flex_end) do |actions_container|
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': "hideWhenFiltering" }) do
render(Primer::Beta::Button.new(
tag: :a,
href: enable_all_project_settings_life_cycle_steps_path(project_id: project),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_enable_all"),
data: { 'turbo-method': :post, test_selector: "enable-all-life-cycle-steps" }
)) do |button|
render(
Primer::Beta::Button.new(
tag: :a,
href: enable_all_project_settings_life_cycle_steps_path(project_id: project),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_enable_all"),
data: { 'turbo-method': :post, test_selector: "enable-all-life-cycle-steps" }
)
) do |button|
button.with_leading_visual_icon(icon: "check-circle", color: :subtle)
t("projects.settings.actions.label_enable_all")
end
end
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': "hideWhenFiltering" }) do
render(Primer::Beta::Button.new(
tag: :a,
href: disable_all_project_settings_life_cycle_steps_path(project_id: project),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_disable_all"),
data: { 'turbo-method': :post, test_selector: "disable-all-life-cycle-steps" }
)) do |button|
render(
Primer::Beta::Button.new(
tag: :a,
href: disable_all_project_settings_life_cycle_steps_path(project_id: project),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_disable_all"),
data: { 'turbo-method': :post, test_selector: "disable-all-life-cycle-steps" }
)
) do |button|
button.with_leading_visual_icon(icon: "x-circle", color: :subtle)
t("projects.settings.actions.label_disable_all")
end
@@ -68,8 +74,10 @@
end
else
life_cycle_definitions_and_step_active.each do |definition, active|
component.with_row(data: { 'projects--settings--border-box-filter-target': "searchItem" },
test_selector: "project-life-cycle-step-#{definition.id}") do
component.with_row(
data: { 'projects--settings--border-box-filter-target': "searchItem" },
test_selector: "project-life-cycle-step-#{definition.id}"
) do
render(Projects::Settings::LifeCycleSteps::StepComponent.new(definition:, active?: active))
end
end
@@ -77,10 +85,12 @@
end
end
flex.with_row do
render Primer::Beta::Text.new(display: :none,
data: {
"projects--settings--border-box-filter-target": "noResultsText",
}) do
render Primer::Beta::Text.new(
display: :none,
data: {
"projects--settings--border-box-filter-target": "noResultsText",
}
) do
I18n.t("js.autocompleter.notFoundText")
end
end
@@ -2,9 +2,11 @@
render Primer::OpenProject::PageHeader.new do |header|
header.with_title { t("projects.settings.life_cycle.header.title") }
header.with_description do
t("projects.settings.life_cycle.header.description_html",
t(
"projects.settings.life_cycle.header.description_html",
overview_url: project_path(project),
admin_settings_url: admin_settings_project_life_cycle_step_definitions_path)
admin_settings_url: admin_settings_project_life_cycle_step_definitions_path
)
end
header.with_breadcrumbs(breadcrumb_items)
end
@@ -1,6 +1,8 @@
<%=
flex_layout(align_items: :center,
justify_content: :space_between) do |step_container|
flex_layout(
align_items: :center,
justify_content: :space_between
) do |step_container|
step_container.with_column(flex_layout: true, mr: 2, classes: "min-width-0") do |title_container|
title_container.with_column(pt: 1, mr: 3, classes: "ellipsis") do
render(Primer::Beta::Text.new(classes: "filter-target-visible-text")) { definition.name }
@@ -15,16 +17,18 @@
# small variant + status_label_position: :start leads to a small bounce while toggling
# behavior can be seen on primer's viewbook as well -> https://view-components-storybook.eastus.cloudapp.azure.com/view-components/lookbook/inspect/primer/alpha/toggle_switch/small
# quick fix: don't display loading indicator which is causing the bounce
render(Primer::Alpha::ToggleSwitch.new(
src: toggle_project_settings_life_cycle_step_path(id: definition.id),
csrf_token: form_authenticity_token,
data: { test_selector: "toggle-project-life-cycle-#{definition.id}" },
aria: { label: toggle_aria_label },
checked: active?,
size: :small,
status_label_position: :start,
classes: "op-primer-adjustments__toggle-switch--hidden-loading-indicator",
))
render(
Primer::Alpha::ToggleSwitch.new(
src: toggle_project_settings_life_cycle_step_path(id: definition.id),
csrf_token: form_authenticity_token,
data: { test_selector: "toggle-project-life-cycle-#{definition.id}" },
aria: { label: toggle_aria_label },
checked: active?,
size: :small,
status_label_position: :start,
classes: "op-primer-adjustments__toggle-switch--hidden-loading-indicator",
)
)
end
end
%>
@@ -1,15 +1,17 @@
<%=
component_wrapper do
flex_layout(align_items: :center, justify_content: :space_between, classes: "op-project-custom-field", data: {
test_selector: "project-custom-field-#{@project_custom_field.id}"
}) do |custom_field_container|
flex_layout(
align_items: :center, justify_content: :space_between, classes: "op-project-custom-field", data: {
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(classes: "filter-target-visible-text")) do
@project_custom_field.name
end
end
title_container.with_column(pt: 1, mr: 2, data: { test_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
@@ -28,22 +30,24 @@
# small variant + status_label_position: :start leads to a small bounce while toggling
# behavior can be seen on primer's viewbook as well -> https://view-components-storybook.eastus.cloudapp.azure.com/view-components/lookbook/inspect/primer/alpha/toggle_switch/small
# quick fix: don't display loading indicator which is causing the bounce
render(Primer::Alpha::ToggleSwitch.new(
src: toggle_project_settings_project_custom_fields_path(
project_custom_field_project_mapping: {
project_id: @project.id,
custom_field_id: @project_custom_field.id
}
),
csrf_token: form_authenticity_token,
data: { 'turbo-method': :put, 'turbo-stream': true,
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,
status_label_position: :start,
classes: "op-primer-adjustments__toggle-switch--hidden-loading-indicator",
))
render(
Primer::Alpha::ToggleSwitch.new(
src: toggle_project_settings_project_custom_fields_path(
project_custom_field_project_mapping: {
project_id: @project.id,
custom_field_id: @project_custom_field.id
}
),
csrf_token: form_authenticity_token,
data: { 'turbo-method': :put, 'turbo-stream': true,
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,
status_label_position: :start,
classes: "op-primer-adjustments__toggle-switch--hidden-loading-indicator",
)
)
end
end
end
@@ -3,29 +3,33 @@
flex_layout do |flex|
flex.with_row do
render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_filter_input(name: "border-box-filter",
label: t("projects.settings.project_custom_fields.filter.label"),
visually_hide_label: true,
placeholder: t("projects.settings.project_custom_fields.filter.label"),
leading_visual: {
icon: :search,
size: :small
},
show_clear_button: true,
clear_button_id: clear_button_id,
data: {
action: "input->projects--settings--border-box-filter#filterLists",
"projects--settings--border-box-filter-target": "filter"
})
subheader.with_filter_input(
name: "border-box-filter",
label: t("projects.settings.project_custom_fields.filter.label"),
visually_hide_label: true,
placeholder: t("projects.settings.project_custom_fields.filter.label"),
leading_visual: {
icon: :search,
size: :small
},
show_clear_button: true,
clear_button_id: clear_button_id,
data: {
action: "input->projects--settings--border-box-filter#filterLists",
"projects--settings--border-box-filter-target": "filter"
}
)
end
end
@project_custom_field_sections.each do |project_custom_field_section|
flex.with_row do
render(Projects::Settings::ProjectCustomFieldSections::ShowComponent.new(
project: @project,
project_custom_field_section:
))
render(
Projects::Settings::ProjectCustomFieldSections::ShowComponent.new(
project: @project,
project_custom_field_section:
)
)
end
end
end
@@ -1,7 +1,11 @@
<%= render Primer::OpenProject::PageHeader.new do |header| %>
<%= header.with_title { t("projects.settings.project_custom_fields.header.title") } %>
<%= header.with_description { t("projects.settings.project_custom_fields.header.description_html",
overview_url: project_path(project),
admin_settings_url: admin_settings_project_custom_fields_path) } %>
<%= header.with_description {
t(
"projects.settings.project_custom_fields.header.description_html",
overview_url: project_path(project),
admin_settings_url: admin_settings_project_custom_fields_path
)
} %>
<%= header.with_breadcrumbs(breadcrumb_items) %>
<% end %>
@@ -1,8 +1,12 @@
<%=
component_wrapper do
render(border_box_container(mb: 3, classes: "op-project-custom-field-section", data: {
test_selector: "project-custom-field-section-#{@project_custom_field_section.id}"
})) do |component|
render(
border_box_container(
mb: 3, classes: "op-project-custom-field-section", data: {
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|
section_header_container.with_column(py: 2) do |content_container|
@@ -14,39 +18,43 @@
end
section_header_container.with_column(flex_layout: true, justify_content: :flex_end) do |actions_container|
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': "hideWhenFiltering" }) do
render(Primer::Beta::Button.new(
tag: :a,
href: enable_all_of_section_project_settings_project_custom_fields_path(
project_custom_field_project_mapping: {
project_id: @project.id,
custom_field_section_id: @project_custom_field_section.id
}
),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_enable_all"),
data: { 'turbo-method': :put, 'turbo-stream': true, test_selector: "enable-all-project-custom-field-mappings-#{@project_custom_field_section.id}" }
)) do |button|
render(
Primer::Beta::Button.new(
tag: :a,
href: enable_all_of_section_project_settings_project_custom_fields_path(
project_custom_field_project_mapping: {
project_id: @project.id,
custom_field_section_id: @project_custom_field_section.id
}
),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_enable_all"),
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.actions.label_enable_all")
end
end
actions_container.with_column(data: { 'projects--settings--border-box-filter-target': "hideWhenFiltering" }) do
render(Primer::Beta::Button.new(
tag: :a,
href: disable_all_of_section_project_settings_project_custom_fields_path(
project_custom_field_project_mapping: {
project_id: @project.id,
custom_field_section_id: @project_custom_field_section.id
}
),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_disable_all"),
data: { 'turbo-method': :put, 'turbo-stream': true, test_selector: "disable-all-project-custom-field-mappings-#{@project_custom_field_section.id}" }
)) do |button|
render(
Primer::Beta::Button.new(
tag: :a,
href: disable_all_of_section_project_settings_project_custom_fields_path(
project_custom_field_project_mapping: {
project_id: @project.id,
custom_field_section_id: @project_custom_field_section.id
}
),
scheme: :invisible,
font_weight: :bold,
color: :subtle,
'aria-label': t("projects.settings.actions.label_disable_all"),
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.actions.label_disable_all")
end
@@ -61,10 +69,12 @@
else
@project_custom_fields.each do |project_custom_field|
component.with_row(data: { 'projects--settings--border-box-filter-target': "searchItem" }) do
render(Projects::Settings::ProjectCustomFieldSections::CustomFieldRowComponent.new(
project: @project,
project_custom_field:,
))
render(
Projects::Settings::ProjectCustomFieldSections::CustomFieldRowComponent.new(
project: @project,
project_custom_field:,
)
)
end
end
end
@@ -46,11 +46,11 @@ See COPYRIGHT and LICENSE files for more details.
<div class="generic-table--sort-header-outer generic-table--sort-header-outer_no-highlighting">
<div class="generic-table--sort-header">
<%= content_tag :a,
helpers.op_icon("icon-hierarchy"),
href: href_only_when_not_sort_lft,
class: "spot-link #{deactivate_class_on_lft_sort}",
data: { "turbo-stream": true },
title: t(:label_sort_by, value: %("#{t(:label_project_hierarchy)}")) %>
helpers.op_icon("icon-hierarchy"),
href: href_only_when_not_sort_lft,
class: "spot-link #{deactivate_class_on_lft_sort}",
data: { "turbo-stream": true },
title: t(:label_sort_by, value: %("#{t(:label_project_hierarchy)}")) %>
</div>
</div>
</th>
@@ -2,13 +2,13 @@
<% flex.with_column(flex: 1) do %>
<%#- We are just using the classes of the primer component here, because when using the primer component, we cannot detach the input element from the form %>
<%#- The form="none" adds the input to a nonexistant form (as we do not have one with the ID="none" and thus the fields to not get appended to the query string %>
<%= select_tag "sort_field", select_options, prompt: "-", form: "none", class: "FormControl-select FormControl-medium FormControl--fullWidth", data: { action: "change->sort-by-config#fieldChanged"} %>
<%= select_tag "sort_field", select_options, prompt: "-", form: "none", class: "FormControl-select FormControl-medium FormControl--fullWidth", data: { action: "change->sort-by-config#fieldChanged" } %>
<% end %>
<% flex.with_column do %>
<%= render(Primer::Alpha::SegmentedControl.new("aria-label": "Sort order", hide_labels: true, ml: 3)) do |sort_buttons| %>
<%#- The segmented control actions need to be included here as well as they do the visual styling of the currently selected option, just setting our action would remove their action %>
<% sort_buttons.with_item(icon: "sort-asc", label: "sort ascending", selected: order_asc?, data: { direction: "asc", action: "click:segmented-control#select click->sort-by-config#fieldChanged"}) %>
<% sort_buttons.with_item(icon: "sort-desc", label: "sort descending", selected: order_desc?, data: { direction: "desc", action: "click:segmented-control#select click->sort-by-config#fieldChanged"}) %>
<% sort_buttons.with_item(icon: "sort-asc", label: "sort ascending", selected: order_asc?, data: { direction: "asc", action: "click:segmented-control#select click->sort-by-config#fieldChanged" }) %>
<% sort_buttons.with_item(icon: "sort-desc", label: "sort descending", selected: order_desc?, data: { direction: "desc", action: "click:segmented-control#select click->sort-by-config#fieldChanged" }) %>
<% end %>
<% end %>
<% end %>
@@ -6,12 +6,14 @@
render(Primer::OpenProject::DragHandle.new(classes: "handle"))
end
content_container.with_column(mr: 2) do
render(Primer::Beta::Link.new(
href: edit_admin_settings_project_custom_field_path(@project_custom_field),
underline: false,
font_weight: :bold,
data: { turbo: "false" }
)) do
render(
Primer::Beta::Link.new(
href: edit_admin_settings_project_custom_field_path(@project_custom_field),
underline: false,
font_weight: :bold,
data: { turbo: "false" }
)
) do
@project_custom_field.name
end
end
@@ -22,8 +24,10 @@
end
content_container.with_column(mr: 2) do
render(Primer::Beta::Text.new(font_size: :small)) do
t("project.count",
count: @project_custom_field.project_custom_field_project_mappings.size)
t(
"project.count",
count: @project_custom_field.project_custom_field_project_mappings.size
)
end
end
if @project_custom_field.required?
@@ -1,7 +1,7 @@
<%=
component_wrapper(data: wrapper_data_attributes) do
if @project_custom_field_sections.any?
flex_layout(classes: "dragula-container", data: { 'allowed-drop-type': "section" }.merge(drop_target_config) ) do |flex|
flex_layout(classes: "dragula-container", data: { 'allowed-drop-type': "section" }.merge(drop_target_config)) do |flex|
@project_custom_field_sections.each do |section|
flex.with_row(
data: draggable_item_config(section)
@@ -27,10 +27,12 @@
end
end
actions_container.with_column do
render(Primer::Alpha::Dialog.new(
id: "project-custom-field-section-dialog#{@project_custom_field_section.id}", title: t("settings.project_attributes.label_new_section"),
size: :medium_portrait
)) do |dialog|
render(
Primer::Alpha::Dialog.new(
id: "project-custom-field-section-dialog#{@project_custom_field_section.id}", title: t("settings.project_attributes.label_new_section"),
size: :medium_portrait
)
) do |dialog|
render(Settings::ProjectCustomFieldSections::DialogBodyFormComponent.new(project_custom_field_section: @project_custom_field_section))
end
end
@@ -44,17 +46,19 @@
render(Primer::Beta::Text.new(color: :subtle)) { t("settings.project_attributes.label_no_project_custom_fields") }
end
empty_list_container.with_column do
render(Primer::Beta::Button.new(
render(
Primer::Beta::Button.new(
tag: :a,
href: new_admin_settings_project_custom_field_path(
type: "ProjectCustomField", custom_field_section_id: @project_custom_field_section.id
),
scheme: :secondary,
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")
end
)
) do |button|
button.with_leading_visual_icon(icon: :plus)
t("settings.project_attributes.label_new_attribute")
end
end
end
end
@@ -34,7 +34,7 @@ See COPYRIGHT and LICENSE files for more details.
header.with_tab_nav(label: nil, test_selector: :project_attribute_detail_header) do |tab_nav|
tab_nav.with_tab(
selected: project_custom_field_edit_selected?,
href: edit_admin_settings_project_custom_field_path(@custom_field)
href: edit_admin_settings_project_custom_field_path(@custom_field)
) do |tab|
tab.with_text { t(:label_details) }
end
@@ -21,16 +21,17 @@
end
end
subheader.with_action_button(tag: :a,
href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"),
scheme: :primary,
data: { turbo: "false", test_selector: "new-project-custom-field-button" },
mobile_icon: :plus,
mobile_label: t("settings.project_attributes.label_new_attribute")) do |button|
subheader.with_action_button(
tag: :a,
href: new_admin_settings_project_custom_field_path(type: "ProjectCustomField"),
scheme: :primary,
data: { turbo: "false", test_selector: "new-project-custom-field-button" },
mobile_icon: :plus,
mobile_label: t("settings.project_attributes.label_new_attribute")
) do |button|
button.with_leading_visual_icon(icon: :plus)
t("settings.project_attributes.label_new_attribute")
end
end
%>
<% end %>
@@ -28,7 +28,7 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%= render Primer::OpenProject::PageHeader.new do |header|
header.with_title { t("settings.project_life_cycle_step_definitions.#{heading_scope}.heading") }
header.with_description { t("settings.project_life_cycle_step_definitions.new.description") }
header.with_breadcrumbs(breadcrumbs_items)
end %>
header.with_title { t("settings.project_life_cycle_step_definitions.#{heading_scope}.heading") }
header.with_description { t("settings.project_life_cycle_step_definitions.new.description") }
header.with_breadcrumbs(breadcrumbs_items)
end %>
@@ -49,8 +49,10 @@ See COPYRIGHT and LICENSE files for more details.
}
)
subheader.with_action_component do
render(Primer::Alpha::ActionMenu.new(
anchor_align: :end)
render(
Primer::Alpha::ActionMenu.new(
anchor_align: :end
)
) do |menu|
menu.with_show_button(
scheme: :primary,
@@ -108,11 +110,13 @@ See COPYRIGHT and LICENSE files for more details.
**draggable_item_config(definition)
}
) do
render(Settings::ProjectLifeCycleStepDefinitions::RowComponent.new(
definition,
first?: definition == definitions.first,
last?: definition == definitions.last,
))
render(
Settings::ProjectLifeCycleStepDefinitions::RowComponent.new(
definition,
first?: definition == definitions.first,
last?: definition == definitions.last,
)
)
end
end
end
@@ -32,9 +32,11 @@ See COPYRIGHT and LICENSE files for more details.
row_container.with_column(flex_layout: true, classes: "gap-2 min-width-0") do |title_container|
if allowed_to_customize_life_cycle?
title_container.with_column do
render(Primer::OpenProject::DragHandle.new(
data: { "projects--settings--border-box-filter-target": "hideWhenFiltering" }
))
render(
Primer::OpenProject::DragHandle.new(
data: { "projects--settings--border-box-filter-target": "hideWhenFiltering" }
)
)
end
end
title_container.with_column(classes: "ellipsis", test_selector: "project-life-cycle-step-definition-name") do
@@ -1,27 +1,33 @@
<%=
render(Primer::Alpha::ActionMenu.new(select_variant: :single,
dynamic_label: true,
anchor_align: :end,
color: :subtle,
data: { test_selector: "op-share-dialog-bulk-update-role"})) do |menu|
render(
Primer::Alpha::ActionMenu.new(
select_variant: :single,
dynamic_label: true,
anchor_align: :end,
color: :subtle,
data: { test_selector: "op-share-dialog-bulk-update-role" }
)
) do |menu|
menu.with_show_button(scheme: :invisible, color: :subtle, data: { 'shares--bulk-selection-target': "bulkUpdateRoleLabel" }) do |button|
button.with_trailing_action_icon(icon: "triangle-down")
"Placeholder"
end
@available_roles.each do |role_hash|
menu.with_item(label: role_hash[:label],
href: update_path,
method: :patch,
active: false,
form_arguments: {
method: :patch,
name: "role_ids[]",
value: role_hash[:value],
data: { 'shares--bulk-selection-target': "bulkForm bulkUpdateRoleForm",
'role-name': role_hash[:label],
'test-selector': "op-share-dialog-bulk-update-role-permission-#{role_hash[:label]}" }
}) do |item|
menu.with_item(
label: role_hash[:label],
href: update_path,
method: :patch,
active: false,
form_arguments: {
method: :patch,
name: "role_ids[]",
value: role_hash[:value],
data: { 'shares--bulk-selection-target': "bulkForm bulkUpdateRoleForm",
'role-name': role_hash[:label],
'test-selector': "op-share-dialog-bulk-update-role-permission-#{role_hash[:label]}" }
}
) do |item|
item.with_description.with_content(role_hash[:description])
end
end
@@ -1,11 +1,15 @@
<%
concat(
render(Primer::Alpha::CheckBox.new(name: "toggle_all",
value: nil,
label: I18n.t("sharing.label_toggle_all"),
visually_hide_label: true,
data: { 'shares--bulk-selection-target': "toggleAll",
action: "shares--bulk-selection#toggle" }))
render(
Primer::Alpha::CheckBox.new(
name: "toggle_all",
value: nil,
label: I18n.t("sharing.label_toggle_all"),
visually_hide_label: true,
data: { 'shares--bulk-selection-target': "toggleAll",
action: "shares--bulk-selection#toggle" }
)
)
)
concat(
@@ -1,5 +1,5 @@
<%=
component_wrapper(data: { test_selector: "op-share-dialog-active-count"}) do
component_wrapper(data: { test_selector: "op-share-dialog-active-count" }) do
render(Primer::Box.new(display: :flex, aligns_items: :center)) do
# There's no point in rendering the BulkSelectionCounterComponent even if
# I'm able to manage shares if the only user that the work package is
@@ -1,15 +1,15 @@
<%= render(Primer::Beta::Blankslate.new) do |component|
component.with_visual_icon(icon: blankslate_config[:icon], size: :medium)
component.with_heading(tag: :h2).with_content(
blankslate_config[:heading_text],
)
component.with_description do
flex_layout do |flex|
flex.with_row(mb: 2) do
render(Primer::Beta::Text.new(color: :subtle)) do
blankslate_config[:description_text]
component.with_visual_icon(icon: blankslate_config[:icon], size: :medium)
component.with_heading(tag: :h2).with_content(
blankslate_config[:heading_text],
)
component.with_description do
flex_layout do |flex|
flex.with_row(mb: 2) do
render(Primer::Beta::Text.new(color: :subtle)) do
blankslate_config[:description_text]
end
end
end
end
end
end
end %>
end %>
@@ -1,28 +1,36 @@
<%=
component_wrapper do
content_tag(:div, class: tooltip_wrapper_classes, data: { tooltip: tooltip_message }) do
render(Primer::Alpha::ActionMenu.new(**{ select_variant: :single,
size: :small,
dynamic_label: true,
anchor_align: :end,
color: :subtle }.deep_merge(@system_arguments))) do |menu|
menu.with_show_button(disabled: !editable?, data: { 'shares--bulk-selection-target': "userRowRole",
'share-id': share.id,
'active-role-name': permission_name(active_role.id)}) do |button|
render(
Primer::Alpha::ActionMenu.new(
**{ select_variant: :single,
size: :small,
dynamic_label: true,
anchor_align: :end,
color: :subtle }.deep_merge(@system_arguments)
)
) do |menu|
menu.with_show_button(
disabled: !editable?, data: { 'shares--bulk-selection-target': "userRowRole",
'share-id': share.id,
'active-role-name': permission_name(active_role.id) }
) do |button|
button.with_trailing_action_icon(icon: :"triangle-down")
permission_name(active_role.id)
end
strategy.available_roles.each do |role_hash|
menu.with_item(label: role_hash[:label],
href: update_path,
method: :patch,
active: role_active?(role_hash),
data: { value: role_hash[:value] },
form_arguments: {
method: :patch,
inputs: form_inputs(role_hash[:value])
}) do |item|
menu.with_item(
label: role_hash[:label],
href: update_path,
method: :patch,
active: role_active?(role_hash),
data: { value: role_hash[:value] },
form_arguments: {
method: :patch,
inputs: form_inputs(role_hash[:value])
}
) do |item|
item.with_description.with_content(role_hash[:description])
end
end
@@ -1,15 +1,15 @@
<%= render(Primer::Beta::Blankslate.new) do |component|
component.with_visual_icon(icon: blankslate_config[:icon], size: :medium)
component.with_heading(tag: :h2).with_content(
blankslate_config[:heading_text],
)
component.with_description do
flex_layout do |flex|
flex.with_row(mb: 2) do
render(Primer::Beta::Text.new(color: :subtle)) do
blankslate_config[:description_text]
component.with_visual_icon(icon: blankslate_config[:icon], size: :medium)
component.with_heading(tag: :h2).with_content(
blankslate_config[:heading_text],
)
component.with_description do
flex_layout do |flex|
flex.with_row(mb: 2) do
render(Primer::Beta::Text.new(color: :subtle)) do
blankslate_config[:description_text]
end
end
end
end
end
end
end %>
end %>
@@ -1,20 +1,26 @@
<%=
container.with_row do
render(Primer::Box.new(border: true,
border_radius: BOX_BORDER_RADIUS,
p: BOX_PADDING)) do
render(
Primer::Box.new(
border: true,
border_radius: BOX_BORDER_RADIUS,
p: BOX_PADDING
)
) do
content_tag(:div, class: tooltip_wrapper_classes, data: { tooltip: tooltip_message }) do
render(Primer::Forms::ToggleSwitchForm.new(
name: "publish_project_query",
label: t("sharing.project_queries.public_flag.label", instance_name: Setting.app_title),
caption: t("sharing.project_queries.public_flag.caption"),
src: toggle_public_flag_link,
csrf_token: form_authenticity_token,
status_label_position: :start,
checked: published?,
enabled: can_publish?,
turbo: true
))
render(
Primer::Forms::ToggleSwitchForm.new(
name: "publish_project_query",
label: t("sharing.project_queries.public_flag.label", instance_name: Setting.app_title),
caption: t("sharing.project_queries.public_flag.caption"),
src: toggle_public_flag_link,
csrf_token: form_authenticity_token,
status_label_position: :start,
checked: published?,
enabled: can_publish?,
turbo: true
)
)
end
end
end
@@ -31,26 +31,30 @@ See COPYRIGHT and LICENSE files for more details.
header.with_title { @user.name }
header.with_breadcrumbs(breadcrumb_items)
header.with_action_button(tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: user_path(@user),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :person,
mobile_label: t(:label_profile),
size: :medium,
href: user_path(@user),
aria: { label: I18n.t(:label_profile) },
title: I18n.t(:label_profile)
) do |button|
button.with_leading_visual_icon(icon: :person)
t(:label_profile)
end
if @current_user.allowed_globally?(:create_user) && @current_user.id != @user.id
header.with_action_button(tag: :a,
mobile_icon: :mail,
mobile_label: t(:label_send_invitation),
size: :medium,
href: resend_invitation_user_path(@user),
data: { method: :post },
aria: { label: I18n.t(:label_send_invitation) },
title: I18n.t(:tooltip_resend_invitation)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :mail,
mobile_label: t(:label_send_invitation),
size: :medium,
href: resend_invitation_user_path(@user),
data: { method: :post },
aria: { label: I18n.t(:label_send_invitation) },
title: I18n.t(:tooltip_resend_invitation)
) do |button|
button.with_leading_visual_icon(icon: :mail)
t(:label_send_invitation)
end
@@ -59,15 +63,17 @@ See COPYRIGHT and LICENSE files for more details.
if @current_user.admin?
unless @current_user.id == @user.id
iterate_user_statusses(@user) do |title, name|
header.with_action_button(tag: :a,
mobile_icon: change_user_status_icons[name],
mobile_label: title,
size: :medium,
name: name,
href: change_status_user_path(@user, { name => "" }),
data: { method: :post },
aria: { label: title },
title: title) do |button|
header.with_action_button(
tag: :a,
mobile_icon: change_user_status_icons[name],
mobile_label: title,
size: :medium,
name: name,
href: change_status_user_path(@user, { name => "" }),
data: { method: :post },
aria: { label: title },
title: title
) do |button|
button.with_leading_visual_icon(icon: change_user_status_icons[name])
title
end
@@ -75,14 +81,16 @@ See COPYRIGHT and LICENSE files for more details.
end
if Setting.users_deletable_by_admins?
header.with_action_button(tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: deletion_info_user_path(@user),
aria: { label: I18n.t(:button_delete) },
title: I18n.t(:button_delete)) do |button|
header.with_action_button(
tag: :a,
scheme: :danger,
mobile_icon: :trash,
mobile_label: t(:button_delete),
size: :medium,
href: deletion_info_user_path(@user),
aria: { label: I18n.t(:button_delete) },
title: I18n.t(:button_delete)
) do |button|
button.with_leading_visual_icon(icon: :trash)
t(:button_delete)
end
@@ -44,9 +44,13 @@ See COPYRIGHT and LICENSE files for more details.
if show_email?
f.with_column(classes: "op-user-hover-card--email") do
render(Primer::Beta::Text.new(font_size: :small,
color: :muted,
data: { test_selector: "user-hover-card-email" })) do
render(
Primer::Beta::Text.new(
font_size: :small,
color: :muted,
data: { test_selector: "user-hover-card-email" }
)
) do
@user.mail
end
end
@@ -69,9 +73,13 @@ See COPYRIGHT and LICENSE files for more details.
end
flex.with_row do
render(Primer::Beta::Button.new(tag: :a,
href: helpers.allowed_management_user_profile_path(@user),
data: { test_selector: "user-hover-card-profile-btn" })) do
render(
Primer::Beta::Button.new(
tag: :a,
href: helpers.allowed_management_user_profile_path(@user),
data: { test_selector: "user-hover-card-profile-btn" }
)
) do
I18n.t("users.open_profile")
end
end
@@ -6,10 +6,14 @@
%>
<%= t(:label_enterprise_active_users, current: OpenProject::Enterprise.active_user_count, limit: user_limit) %>
&nbsp;
<%= render(Primer::Beta::Button.new(scheme: :primary,
size: :small,
tag: :a,
href: OpenProject::Enterprise.upgrade_path,
title: t(:title_enterprise_upgrade))) { t(:button_upgrade) } %>
<%= render(
Primer::Beta::Button.new(
scheme: :primary,
size: :small,
tag: :a,
href: OpenProject::Enterprise.upgrade_path,
title: t(:title_enterprise_upgrade)
)
) { t(:button_upgrade) } %>
<% end if user_limit %>
<% end %>
@@ -1,10 +1,12 @@
<%=
render(Primer::OpenProject::SubHeader.new) do |subheader|
subheader.with_action_button(scheme: :primary,
aria: { label: I18n.t(:label_user_new) },
title: I18n.t(:label_user_new),
tag: :a,
href: new_user_path) do |button|
subheader.with_action_button(
scheme: :primary,
aria: { label: I18n.t(:label_user_new) },
title: I18n.t(:label_user_new),
tag: :a,
href: new_user_path
) do |button|
button.with_leading_visual_icon(icon: :plus)
t("activerecord.models.user")
end
@@ -1,6 +1,6 @@
<%=
render(Primer::OpenProject::SidePanel::Section.new) do |section|
section.with_title { t(:label_information) }
section.with_title { t(:label_information) }
component_wrapper do
flex_layout do |details_container|
@@ -34,27 +34,31 @@ See COPYRIGHT and LICENSE files for more details.
header.with_breadcrumbs(breadcrumb_items)
if @current_user.allowed_globally?(:manage_user)
header.with_action_button(tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_user_path(@user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :pencil,
mobile_label: t(:button_edit),
size: :medium,
href: edit_user_path(@user),
aria: { label: I18n.t(:button_edit) },
title: I18n.t(:button_edit)
) do |button|
button.with_leading_visual_icon(icon: :pencil)
t(:button_edit)
end
end
if @current_user.allowed_globally?(:create_user) && @current_user != @user
header.with_action_button(tag: :a,
mobile_icon: :mail,
mobile_label: t(:label_send_invitation),
size: :medium,
href: resend_invitation_user_path(@user),
data: { method: :post },
aria: { label: I18n.t(:label_send_invitation) },
title: I18n.t(:tooltip_resend_invitation)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :mail,
mobile_label: t(:label_send_invitation),
size: :medium,
href: resend_invitation_user_path(@user),
data: { method: :post },
aria: { label: I18n.t(:label_send_invitation) },
title: I18n.t(:tooltip_resend_invitation)
) do |button|
button.with_leading_visual_icon(icon: :mail)
t(:label_send_invitation)
end
@@ -1,27 +1,38 @@
<%=
render(Primer::Alpha::Dialog.new(title: dialog_title,
size: :large,
id: DIALOG_ID)) do |d|
render(
Primer::Alpha::Dialog.new(
title: dialog_title,
size: :large,
id: DIALOG_ID
)
) do |d|
d.with_header(variant: :large)
d.with_body(classes: body_classes) do
render(WorkPackageRelationsTab::AddWorkPackageChildFormComponent.new(
work_package: @work_package
))
render(
WorkPackageRelationsTab::AddWorkPackageChildFormComponent.new(
work_package: @work_package
)
)
end
d.with_footer do
component_collection do |buttons|
buttons.with_component(Primer::ButtonComponent.new(
data: {
'close-dialog-id': DIALOG_ID
}
)) do
buttons.with_component(
Primer::ButtonComponent.new(
data: {
'close-dialog-id': DIALOG_ID
}
)
) do
t("button_cancel")
end
buttons.with_component(Primer::ButtonComponent.new(
scheme: :primary,
form: FORM_ID,
data: { turbo: true },
type: :submit)) do
buttons.with_component(
Primer::ButtonComponent.new(
scheme: :primary,
form: FORM_ID,
data: { turbo: true },
type: :submit
)
) do
t("button_save")
end
end
@@ -10,8 +10,12 @@
# Prevent the menu from overflowing on Safari
action_bar.with_column(flex_shrink: 0, ml: 2) do
render(Primer::Alpha::ActionMenu.new(test_selector: NEW_RELATION_ACTION_MENU,
menu_id: NEW_RELATION_ACTION_MENU)) do |menu|
render(
Primer::Alpha::ActionMenu.new(
test_selector: NEW_RELATION_ACTION_MENU,
menu_id: NEW_RELATION_ACTION_MENU
)
) do |menu|
menu.with_show_button do |button|
button.with_leading_visual_icon(icon: :"plus")
button.with_trailing_action_icon(icon: :"triangle-down")
@@ -61,11 +65,13 @@
items: all_relations
) do |relation, visibility|
# Render each relation with its visibility
render(WorkPackageRelationsTab::RelationComponent.new(
work_package: work_package,
relation: relation,
visibility: visibility
))
render(
WorkPackageRelationsTab::RelationComponent.new(
work_package: work_package,
relation: relation,
visibility: visibility
)
)
end
end
end
@@ -84,10 +90,14 @@
relation_type: :children,
items: all_children
) do |child, visibility|
render(WorkPackageRelationsTab::RelationComponent.new(work_package:,
relation: nil,
child:,
visibility: visibility))
render(
WorkPackageRelationsTab::RelationComponent.new(
work_package:,
relation: nil,
child:,
visibility: visibility
)
)
end
end
end
@@ -1,26 +1,37 @@
<%=
render(Primer::Alpha::Dialog.new(title: dialog_title,
size: :large,
id: DIALOG_ID)) do |d|
render(
Primer::Alpha::Dialog.new(
title: dialog_title,
size: :large,
id: DIALOG_ID
)
) do |d|
d.with_header(variant: :large)
d.with_body(classes: body_classes) do
render(WorkPackageRelationsTab::WorkPackageRelationFormComponent.new(
work_package: @work_package,
relation: @relation
))
render(
WorkPackageRelationsTab::WorkPackageRelationFormComponent.new(
work_package: @work_package,
relation: @relation
)
)
end
d.with_footer do
component_collection do |buttons|
buttons.with_component(Primer::ButtonComponent.new(
data: { 'close-dialog-id': DIALOG_ID }
)) do
buttons.with_component(
Primer::ButtonComponent.new(
data: { 'close-dialog-id': DIALOG_ID }
)
) do
t(:button_cancel)
end
buttons.with_component(Primer::ButtonComponent.new(
scheme: :primary,
form: FORM_ID,
data: { turbo: true },
type: :submit)) do
buttons.with_component(
Primer::ButtonComponent.new(
scheme: :primary,
form: FORM_ID,
data: { turbo: true },
type: :submit
)
) do
if @relation.id.present?
t(:button_save)
else
@@ -1,8 +1,11 @@
<%=
component_wrapper do
render(Primer::Beta::Blankslate.new(
border: true,
data: { test_selector: "op-wp-journals-container-empty"})) do |component|
render(
Primer::Beta::Blankslate.new(
border: true,
data: { test_selector: "op-wp-journals-container-empty" }
)
) do |component|
component.with_visual_icon(icon: :pulse)
component.with_heading(tag: :h2).with_content(t("activities.work_packages.activity_tab.no_results_title_text"))
component.with_description { t("activities.work_packages.activity_tab.no_results_description_text") }
@@ -1,12 +1,13 @@
<%=
component_wrapper do
flex_layout(justify_content: :space_between) do |container|
container.with_column do
render(Primer::Alpha::ActionMenu.new(
select_variant: :single, dynamic_label: true,
data: { "test_selector": "op-wp-journals-filter-menu" }
)) do |menu|
render(
Primer::Alpha::ActionMenu.new(
select_variant: :single, dynamic_label: true,
data: { "test_selector": "op-wp-journals-filter-menu" }
)
) do |menu|
menu.with_show_button do |button|
button.with_trailing_action_icon(icon: :"triangle-down")
end
@@ -6,8 +6,10 @@
classes: "work-packages-activities-tab-journals-index-component--journals-inner-container",
mb: inner_container_margin_bottom
) do
flex_layout(id: insert_target_modifier_id,
data: { test_selector: "op-wp-journals-container" }) do |journals_index_container|
flex_layout(
id: insert_target_modifier_id,
data: { test_selector: "op-wp-journals-container" }
) do |journals_index_container|
if empty_state?
journals_index_container.with_row(mt: 2, mb: 3) do
render(
@@ -27,10 +29,12 @@
if record.is_a?(Changeset)
render(WorkPackages::ActivitiesTab::Journals::RevisionComponent.new(changeset: record, filter:))
else
render(WorkPackages::ActivitiesTab::Journals::ItemComponent.new(
journal: record, filter:,
grouped_emoji_reactions: wp_journals_grouped_emoji_reactions[record.id]
))
render(
WorkPackages::ActivitiesTab::Journals::ItemComponent.new(
journal: record, filter:,
grouped_emoji_reactions: wp_journals_grouped_emoji_reactions[record.id]
)
)
end
end
end
@@ -57,10 +61,12 @@
if record.is_a?(Changeset)
render(WorkPackages::ActivitiesTab::Journals::RevisionComponent.new(changeset: record, filter:))
else
render(WorkPackages::ActivitiesTab::Journals::ItemComponent.new(
journal: record, filter:,
grouped_emoji_reactions: wp_journals_grouped_emoji_reactions[record.id]
))
render(
WorkPackages::ActivitiesTab::Journals::ItemComponent.new(
journal: record, filter:,
grouped_emoji_reactions: wp_journals_grouped_emoji_reactions[record.id]
)
)
end
end
end
@@ -1,27 +1,35 @@
<%=
component_wrapper(data: wrapper_data_attributes, class: "work-packages-activities-tab-journals-item-component") do
flex_layout(data: {
test_selector: "op-wp-journal-entry-#{journal.id}"
}) do |journal_container|
flex_layout(
data: {
test_selector: "op-wp-journal-entry-#{journal.id}"
}
) do |journal_container|
if show_comment_container?
journal_container.with_row do
render(border_box_container(
padding: :condensed,
"aria-label": I18n.t("activities.work_packages.activity_tab.commented"),
data: {
"anchor-activity-id": journal.sequence_version,
"anchor-comment-id": journal.id,
}
)) do |border_box_component|
render(
border_box_container(
padding: :condensed,
"aria-label": I18n.t("activities.work_packages.activity_tab.commented"),
data: {
"anchor-activity-id": journal.sequence_version,
"anchor-comment-id": journal.id,
}
)
) do |border_box_component|
border_box_component.with_header(px: 2, py: 1, data: { test_selector: "op-journal-notes-header" }) do
flex_layout(align_items: :center, justify_content: :space_between) do |header_container|
header_container.with_column(flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--header-start-container ellipsis") do |header_start_container|
header_container.with_column(
flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--header-start-container ellipsis"
) do |header_start_container|
header_start_container.with_column(mr: 2) do
render Users::AvatarComponent.new(user: journal.user, show_name: false, size: :mini)
end
header_start_container.with_column(mr: 1, flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--user-name-container hidden-for-desktop") do |user_name_container|
header_start_container.with_column(
mr: 1, flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--user-name-container hidden-for-desktop"
) do |user_name_container|
user_name_container.with_row(classes: "work-packages-activities-tab-journals-item-component--user-name ellipsis") do
truncated_user_name(journal.user)
end
@@ -29,20 +37,22 @@
render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mt: 1)) { format_time(journal.created_at) }
end
end
header_start_container.with_column(mr: 1,
classes: "work-packages-activities-tab-journals-item-component--user-name ellipsis hidden-for-mobile") do
header_start_container.with_column(
mr: 1,
classes: "work-packages-activities-tab-journals-item-component--user-name ellipsis hidden-for-mobile"
) do
truncated_user_name(journal.user, hover_card: true)
end
if journal.initial?
header_start_container.with_column(
mr: 1,
classes: "work-packages-activities-tab-journals-item-component-details--journal-type hidden-for-mobile"
) do
render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mt: 1)) do
I18n.t("activities.work_packages.activity_tab.created_on")
end
header_start_container.with_column(
mr: 1,
classes: "work-packages-activities-tab-journals-item-component-details--journal-type hidden-for-mobile"
) do
render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mt: 1)) do
I18n.t("activities.work_packages.activity_tab.created_on")
end
end
end
header_start_container.with_column(mr: 1, classes: "hidden-for-mobile") do
if OpenProject::FeatureDecisions.work_package_comment_id_url_active?
activity_anchor_link(journal) { journal_updated_at_formatted_time(journal) }
@@ -54,12 +64,14 @@
header_container.with_column(flex_layout: true, align_items: :center) do |header_end_container|
if has_unread_notifications?
header_end_container.with_column(mr: 2, pt: 1) do
render(Primer::Beta::Octicon.new(
:"dot-fill", # color is set via CSS as requested by UI/UX Team
classes: "work-packages-activities-tab-journals-item-component--notification-dot-icon",
size: :medium,
data: { test_selector: "op-journal-unread-notification", "op-ian-center-update-immediate": true }
))
render(
Primer::Beta::Octicon.new(
:"dot-fill", # color is set via CSS as requested by UI/UX Team
classes: "work-packages-activities-tab-journals-item-component--notification-dot-icon",
size: :medium,
data: { test_selector: "op-journal-unread-notification", "op-ian-center-update-immediate": true }
)
)
end
end
@@ -69,12 +81,16 @@
end
end
header_end_container.with_column(ml: 1,
classes: "work-packages-activities-tab-journals-item-component--action-menu") do
header_end_container.with_column(
ml: 1,
classes: "work-packages-activities-tab-journals-item-component--action-menu"
) do
render(Primer::Alpha::ActionMenu.new(data: { test_selector: "op-wp-journal-#{journal.id}-action-menu" })) do |menu|
menu.with_show_button(icon: "kebab-horizontal",
"aria-label": I18n.t(:button_actions),
scheme: :invisible)
menu.with_show_button(
icon: "kebab-horizontal",
"aria-label": I18n.t(:button_actions),
scheme: :invisible
)
copy_url_action_item(menu)
edit_action_item(menu) if allowed_to_edit?
quote_action_item(menu) if journal.notes.present? && allowed_to_quote?
@@ -94,8 +110,12 @@
else
case state
when :show
render(WorkPackages::ActivitiesTab::Journals::ItemComponent::Show.new(journal:, filter:,
grouped_emoji_reactions:))
render(
WorkPackages::ActivitiesTab::Journals::ItemComponent::Show.new(
journal:, filter:,
grouped_emoji_reactions:
)
)
when :edit
render(WorkPackages::ActivitiesTab::Journals::ItemComponent::Edit.new(journal:, filter:))
end
@@ -105,8 +125,12 @@
end
end
journal_container.with_row do
render(WorkPackages::ActivitiesTab::Journals::ItemComponent::Details.new(journal:,
has_unread_notifications: notification_on_details?, filter:))
render(
WorkPackages::ActivitiesTab::Journals::ItemComponent::Details.new(
journal:,
has_unread_notifications: notification_on_details?, filter:
)
)
end
end
end
@@ -1,11 +1,13 @@
<%=
component_wrapper do
render(Primer::Alpha::Overlay.new(
title: I18n.t("reactions.action_title"),
padding: :condensed,
anchor_side: :outside_top,
visually_hide_title: true
)) do |overlay|
render(
Primer::Alpha::Overlay.new(
title: I18n.t("reactions.action_title"),
padding: :condensed,
anchor_side: :outside_top,
visually_hide_title: true
)
) do |overlay|
overlay.with_show_button(
icon: "smiley",
"aria-label": I18n.t("reactions.add_reaction"),
@@ -18,21 +20,23 @@
flex_layout(flex_wrap: :wrap, classes: "op-add-reactions-overlay") do |add_reactions_container|
EmojiReaction.available_emoji_reactions.each do |emoji, reaction|
add_reactions_container.with_column(mr: 2) do
render(Primer::Beta::Button.new(
scheme: button_scheme(reaction),
color: :default,
bg: counter_color(reaction),
id: "overlay-#{journal.id}-#{reaction}",
test_selector: "overlay-reaction-#{reaction}",
tag: :a,
href: href(reaction:),
data: {
turbo_stream: true,
turbo_method: :put,
"work-packages--activities-tab--index-target": "reactionButton",
},
aria: { label: I18n.t("reactions.react_with", reaction: reaction.to_s.humanize(capitalize: false)) }
)) do
render(
Primer::Beta::Button.new(
scheme: button_scheme(reaction),
color: :default,
bg: counter_color(reaction),
id: "overlay-#{journal.id}-#{reaction}",
test_selector: "overlay-reaction-#{reaction}",
tag: :a,
href: href(reaction:),
data: {
turbo_stream: true,
turbo_method: :put,
"work-packages--activities-tab--index-target": "reactionButton",
},
aria: { label: I18n.t("reactions.react_with", reaction: reaction.to_s.humanize(capitalize: false)) }
)
) do
emoji
end
end
@@ -14,15 +14,17 @@
end
form_container.with_row(flex_layout: true, mt: 3, justify_content: :flex_end) do |submit_container|
submit_container.with_column(mr: 2) do
render(Primer::Beta::Button.new(
scheme: :secondary,
size: :medium,
tag: :a,
href: cancel_edit_work_package_activity_path(work_package.id, id: journal.id, filter:),
data: { turbo_stream: true }
)) do
t("button_cancel")
end
render(
Primer::Beta::Button.new(
scheme: :secondary,
size: :medium,
tag: :a,
href: cancel_edit_work_package_activity_path(work_package.id, id: journal.id, filter:),
data: { turbo_stream: true }
)
) do
t("button_cancel")
end
end
submit_container.with_column do
render(WorkPackages::ActivitiesTab::Journals::Submit.new(f))
@@ -5,10 +5,12 @@
display: button_row_display_value,
data: {
"work-packages--activities-tab--index-target": "buttonRow"
}) do
}
) do
flex_layout(justify_content: :space_between) do |button_row|
button_row.with_column(classes: "work-packages-activities-tab-journals-new-component--input-trigger-column", mr: 2) do
render(Primer::Beta::Button.new(
render(
Primer::Beta::Button.new(
text_align: :left,
scheme: :default,
size: :medium,
@@ -17,17 +19,20 @@
"action": "click->work-packages--activities-tab--index#showForm dragover->work-packages--activities-tab--index#showForm",
"test_selector": "op-open-work-package-journal-form-trigger"
}
)) do
)
) do
render(Primer::Beta::Text.new(color: :muted, font_weight: :normal)) { t("activities.work_packages.activity_tab.label_type_to_comment") }
end
end
button_row.with_column do
render(Primer::Beta::IconButton.new(
render(
Primer::Beta::IconButton.new(
scheme: :default,
icon: :"paper-airplane",
"aria-label": t("activities.work_packages.activity_tab.label_submit_comment"),
disabled: true
))
)
)
end
end
end
@@ -56,16 +61,18 @@
render(WorkPackages::ActivitiesTab::Journals::NotesForm.new(f))
end
form_container.with_column do
render(Primer::Beta::IconButton.new(
scheme: :default,
icon: :"paper-airplane",
"aria-label": t("activities.work_packages.activity_tab.label_submit_comment"),
type: :submit,
data: {
"test_selector": "op-submit-work-package-journal-form",
"work-packages--activities-tab--index-target": "formSubmitButton"
}
))
render(
Primer::Beta::IconButton.new(
scheme: :default,
icon: :"paper-airplane",
"aria-label": t("activities.work_packages.activity_tab.label_submit_comment"),
type: :submit,
data: {
"test_selector": "op-submit-work-package-journal-form",
"work-packages--activities-tab--index-target": "formSubmitButton"
}
)
)
end
end
end
@@ -1,63 +1,81 @@
<%=
component_wrapper(class: "work-packages-activities-tab-journals-item-component") do
flex_layout(data: {
test_selector: "op-wp-revision-entry-#{changeset.id}"
}) do |revision_container|
flex_layout(
data: {
test_selector: "op-wp-revision-entry-#{changeset.id}"
}
) do |revision_container|
revision_container.with_row do
render(border_box_container(
id: "activity-anchor-r#{changeset.revision}",
padding: :condensed,
"aria-label": I18n.t("activities.work_packages.activity_tab.commented")
)) do |border_box_component|
render(
border_box_container(
id: "activity-anchor-r#{changeset.revision}",
padding: :condensed,
"aria-label": I18n.t("activities.work_packages.activity_tab.commented")
)
) do |border_box_component|
border_box_component.with_header(px: 2, py: 1, data: { test_selector: "op-revision-header" }) do
flex_layout(align_items: :center, justify_content: :space_between, classes: "work-packages-activities-tab-revision-component--header") do |header_container|
header_container.with_column(flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--header-start-container ellipsis") do |header_start_container|
header_container.with_column(
flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--header-start-container ellipsis"
) do |header_start_container|
header_start_container.with_column(mr: 2) do
if changeset.user
render(Users::AvatarComponent.new(user: changeset.user, show_name: false, size: :mini))
end
end
header_start_container.with_column(mr: 1, flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--user-name-container hidden-for-desktop") do |user_name_container|
header_start_container.with_column(
mr: 1, flex_layout: true,
classes: "work-packages-activities-tab-journals-item-component--user-name-container hidden-for-desktop"
) do |user_name_container|
user_name_container.with_row(classes: "work-packages-activities-tab-journals-item-component--user-name ellipsis") do
render_user_name
end
user_name_container.with_row do
render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mr: 1)) do
committed_text = render(Primer::Beta::Link.new(
committed_text = render(
Primer::Beta::Link.new(
href: revision_url,
scheme: :secondary,
underline: false,
font_size: :small,
target: "_blank"
)
) do
I18n.t("js.label_committed_link", revision_identifier: short_revision)
end
I18n.t(
"js.label_committed_at",
committed_revision_link: committed_text.html_safe,
date: format_time(changeset.committed_on)
).html_safe
end
end
end
header_start_container.with_column(
mr: 1,
classes: "work-packages-activities-tab-journals-item-component--user-name ellipsis hidden-for-mobile"
) do
render_user_name
end
header_start_container.with_column(mr: 1, classes: "hidden-for-mobile") do
render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mr: 1)) do
committed_text = render(
Primer::Beta::Link.new(
href: revision_url,
scheme: :secondary,
underline: false,
font_size: :small,
target: "_blank"
)) do
I18n.t("js.label_committed_link", revision_identifier: short_revision)
end
I18n.t("js.label_committed_at",
committed_revision_link: committed_text.html_safe,
date: format_time(changeset.committed_on)).html_safe
end
end
end
header_start_container.with_column(mr: 1,
classes: "work-packages-activities-tab-journals-item-component--user-name ellipsis hidden-for-mobile") do
render_user_name
end
header_start_container.with_column(mr: 1, classes: "hidden-for-mobile") do
render(Primer::Beta::Text.new(font_size: :small, color: :subtle, mr: 1)) do
committed_text = render(Primer::Beta::Link.new(
href: revision_url,
scheme: :secondary,
underline: false,
font_size: :small,
target: "_blank"
)) do
)
) do
I18n.t("js.label_committed_link", revision_identifier: short_revision)
end
I18n.t("js.label_committed_at",
committed_revision_link: committed_text.html_safe,
date: format_time(changeset.committed_on)).html_safe
I18n.t(
"js.label_committed_at",
committed_revision_link: committed_text.html_safe,
date: format_time(changeset.committed_on)
).html_safe
end
end
end
@@ -1,35 +1,46 @@
<%=
flex_layout(classes: "op-work-package-details-tab-component", data: {
"application-target": "dynamic",
controller: "work-packages--details--tabs"
}) do |flex|
flex_layout(
classes: "op-work-package-details-tab-component", data: {
"application-target": "dynamic",
controller: "work-packages--details--tabs"
}
) do |flex|
flex.with_column(classes: "op-work-package-details-tab-component--action") do
render(Primer::Beta::IconButton.new(icon: :"chevron-left",
tag: :a,
classes: "hidden-for-tablet",
scheme: :invisible,
data: {
action: "click->work-packages--details--tabs#scrollLeft"
},
aria: { label: I18n.t(:label_scroll_left) }))
render(
Primer::Beta::IconButton.new(
icon: :"chevron-left",
tag: :a,
classes: "hidden-for-tablet",
scheme: :invisible,
data: {
action: "click->work-packages--details--tabs#scrollLeft"
},
aria: { label: I18n.t(:label_scroll_left) }
)
)
end
flex.with_column(flex: 1, classes: "op-work-package-details-tab-component--tabs", test_selector: "wp-details-tab-component--tabs") do
render(Primer::Alpha::UnderlineNav.new(align: :left,
label: "Tabs",
data: {
"work-packages--details--tabs-target": "underlineNav",
})) do |component|
render(
Primer::Alpha::UnderlineNav.new(
align: :left,
label: "Tabs",
data: {
"work-packages--details--tabs-target": "underlineNav",
}
)
) do |component|
menu_items.each do |node|
component.with_tab(selected: @tab == node.name,
href: helpers.url_for_with_params(**node.url),
test_selector: "wp-details-tab-component--tab-#{node.name}",
data: {
turbo: true,
turbo_stream: true,
turbo_action: "replace",
"work-packages--details--tabs-target": @tab == node.name ? "activeElement" : ""
}
component.with_tab(
selected: @tab == node.name,
href: helpers.url_for_with_params(**node.url),
test_selector: "wp-details-tab-component--tab-#{node.name}",
data: {
turbo: true,
turbo_stream: true,
turbo_action: "replace",
"work-packages--details--tabs-target": @tab == node.name ? "activeElement" : ""
}
) do |c|
c.with_text { t("js.work_packages.tabs.#{node.name}") }
count = node.badge(work_package:).to_i
@@ -40,35 +51,47 @@
end
flex.with_column(classes: "op-work-package-details-tab-component--action") do
render(Primer::Beta::IconButton.new(icon: :"chevron-right",
tag: :a,
classes: "hidden-for-tablet",
scheme: :invisible,
data: {
action: "click->work-packages--details--tabs#scrollRight"
},
aria: { label: I18n.t(:label_scroll_right) }))
render(
Primer::Beta::IconButton.new(
icon: :"chevron-right",
tag: :a,
classes: "hidden-for-tablet",
scheme: :invisible,
data: {
action: "click->work-packages--details--tabs#scrollRight"
},
aria: { label: I18n.t(:label_scroll_right) }
)
)
end
flex.with_column(classes: "op-work-package-details-tab-component--action") do
render(Primer::Beta::IconButton.new(icon: :"screen-full",
tag: :a,
classes: "hidden-for-small-laptops",
href: work_package_path(work_package.id, full_screen_tab),
target: "_top",
scheme: :invisible,
test_selector: "wp-details-tab-component--full-screen",
aria: { label: I18n.t("js.button_show_fullscreen") }))
render(
Primer::Beta::IconButton.new(
icon: :"screen-full",
tag: :a,
classes: "hidden-for-small-laptops",
href: work_package_path(work_package.id, full_screen_tab),
target: "_top",
scheme: :invisible,
test_selector: "wp-details-tab-component--full-screen",
aria: { label: I18n.t("js.button_show_fullscreen") }
)
)
end
flex.with_column(classes: "op-work-package-details-tab-component--action") do
render(Primer::Beta::IconButton.new(icon: :x,
tag: :a,
href: base_route,
data: { turbo: true, target: "_top", turbo_action: "advance" },
scheme: :invisible,
test_selector: "wp-details-tab-component--close",
aria: { label: I18n.t(:button_close) }))
render(
Primer::Beta::IconButton.new(
icon: :x,
tag: :a,
href: base_route,
data: { turbo: true, target: "_top", turbo_action: "advance" },
scheme: :invisible,
test_selector: "wp-details-tab-component--close",
aria: { label: I18n.t(:button_close) }
)
)
end
end
%>
@@ -1,20 +1,23 @@
<%= flex_layout do |container| %>
<%= container.with_row do |_columns| %>
<%= render WorkPackages::Exports::ColumnSelectionComponent.new(
query,
"columns-select-export-csv",
I18n.t("export.dialog.columns.input_caption_table")
) %>
query,
"columns-select-export-csv",
I18n.t("export.dialog.columns.input_caption_table")
) %>
<% end %>
<%= container.with_row do |_csv_include_description| %>
<%= render OpenProject::Common::DividerComponent.new %>
<%= render(Primer::Alpha::CheckBox.new(
id: "show_descriptions_csv",
name: "show_descriptions",
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.xls.include_descriptions.label"),
caption: I18n.t("export.dialog.xls.include_descriptions.caption"),
visually_hide_label: false)) %>
<%= render(
Primer::Alpha::CheckBox.new(
id: "show_descriptions_csv",
name: "show_descriptions",
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.xls.include_descriptions.label"),
caption: I18n.t("export.dialog.xls.include_descriptions.caption"),
visually_hide_label: false
)
) %>
<% end %>
<% end %>
@@ -1,34 +1,37 @@
<%= render(Primer::Alpha::Dialog.new(
title: I18n.t("export.dialog.title"),
size: :xlarge,
id: MODAL_ID,
data: {
"application-target": "dynamic",
controller: "work-packages--export--dialog"
}
)) do |dialog| %>
<%= render(
Primer::Alpha::Dialog.new(
title: I18n.t("export.dialog.title"),
size: :xlarge,
id: MODAL_ID,
data: {
"application-target": "dynamic",
controller: "work-packages--export--dialog"
}
)
) do |dialog| %>
<% dialog.with_header(variant: :large) %>
<% dialog.with_body do %>
<% flex_layout do |modal_body| %>
<% modal_body.with_row do |_format| %>
<%= render(Primer::Beta::Text.new(tag: "legend", font_size: :normal, mb: 2, font_weight: :bold)) { I18n.t("export.dialog.format.label") } %>
<%= render(Primer::Alpha::SegmentedControl.new(ml: 0, "aria-label": I18n.t("export.dialog.format.label"), size: :medium)) do |component|
export_formats_settings.each do |format|
component.with_item(
label: format[:label], icon: format[:icon], selected: format[:selected],
data: {
"work-packages--export--dialog-format-param": format[:id],
action: "click:segmented-control#select click->work-packages--export--dialog#formatChanged"
})
end
end %>
export_formats_settings.each do |format|
component.with_item(
label: format[:label], icon: format[:icon], selected: format[:selected],
data: {
"work-packages--export--dialog-format-param": format[:id],
action: "click:segmented-control#select click->work-packages--export--dialog#formatChanged"
}
)
end
end %>
<%= render OpenProject::Common::DividerComponent.new %>
<% end %>
<% export_formats_settings.each do |format| %>
<% modal_body.with_row(
classes: format[:selected] ? nil : "d-none",
data: { format: format[:id], "work-packages--export--dialog-target": "formatTab" }
) do |_format_tabs| %>
classes: format[:selected] ? nil : "d-none",
data: { format: format[:id], "work-packages--export--dialog-target": "formatTab" }
) do |_format_tabs| %>
<%= primer_form_with(
url: export_format_url(format[:id]),
id: "#{EXPORT_FORM_ID}-#{format[:id]}",
@@ -48,12 +51,15 @@
<% end %>
<% dialog.with_footer do %>
<%= render(Primer::ButtonComponent.new(data: { "close-dialog-id": MODAL_ID })) { I18n.t(:button_cancel) } %>
<%= render(Primer::ButtonComponent.new(
data: {
"close-dialog-id": MODAL_ID,
"work-packages--export--dialog-target": "submit"
},
scheme: :primary, type: :submit,
form: "#{EXPORT_FORM_ID}-#{export_formats_settings.find { |e| e[:selected] }[:id]}")) { I18n.t("export.dialog.submit") } %>
<%= render(
Primer::ButtonComponent.new(
data: {
"close-dialog-id": MODAL_ID,
"work-packages--export--dialog-target": "submit"
},
scheme: :primary, type: :submit,
form: "#{EXPORT_FORM_ID}-#{export_formats_settings.find { |e| e[:selected] }[:id]}"
)
) { I18n.t("export.dialog.submit") } %>
<% end %>
<% end %>
@@ -1,35 +1,43 @@
<%=
flex_layout(data: {
"application-target": "dynamic",
controller: "work-packages--export--pdf--settings"
}) do |container|
flex_layout(
data: {
"application-target": "dynamic",
controller: "work-packages--export--pdf--settings"
}
) do |container|
%>
<%= container.with_row do %>
<%= render(Primer::Alpha::RadioButtonGroup.new(
full_width: true,
name: "pdf_export_type",
label: I18n.t("export.dialog.pdf.export_type.label"))) do |component|
pdf_export_types.each do |entry|
component.radio_button(label: entry[:label],
value: entry[:value],
checked: current_pdf_export_type == entry[:value],
disabled: entry[:disabled] ? true : nil,
data: {
"work-packages--export--pdf--settings-name-param": entry[:value],
action: "work-packages--export--pdf--settings#typeChanged"
},
caption: entry[:caption])
end
end %>
<%= render(
Primer::Alpha::RadioButtonGroup.new(
full_width: true,
name: "pdf_export_type",
label: I18n.t("export.dialog.pdf.export_type.label")
)
) do |component|
pdf_export_types.each do |entry|
component.radio_button(
label: entry[:label],
value: entry[:value],
checked: current_pdf_export_type == entry[:value],
disabled: entry[:disabled] ? true : nil,
data: {
"work-packages--export--pdf--settings-name-param": entry[:value],
action: "work-packages--export--pdf--settings#typeChanged"
},
caption: entry[:caption]
)
end
end %>
<%= render OpenProject::Common::DividerComponent.new %>
<% end %>
<% pdf_export_types.reject { |entry| entry[:disabled] }.each do |entry| %>
<%= container.with_row(
classes: current_pdf_export_type == entry[:value] ? nil : "d-none",
data: {
"pdf-export-type": entry[:value],
"work-packages--export--pdf--settings-target": "fields"
}) do |_pdf_export_type| %>
classes: current_pdf_export_type == entry[:value] ? nil : "d-none",
data: {
"pdf-export-type": entry[:value],
"work-packages--export--pdf--settings-target": "fields"
}
) do |_pdf_export_type| %>
<%= render(entry[:component].new(query)) %>
<% end %>
<% end %>
@@ -1,11 +1,11 @@
<%= flex_layout do |container| %>
<% container.with_row do |_columns| %>
<%= render WorkPackages::Exports::ColumnSelectionComponent.new(
query,
"columns-select-export-pdf-report",
I18n.t("export.dialog.columns.input_caption_report"),
I18n.t("export.dialog.columns.input_label_report")
) %>
query,
"columns-select-export-pdf-report",
I18n.t("export.dialog.columns.input_caption_report"),
I18n.t("export.dialog.columns.input_label_report")
) %>
<% end %>
<% container.with_row do |_columns| %>
<%= render OpenProject::Common::DividerComponent.new %>
@@ -27,12 +27,16 @@
<% end %>
<%= container.with_row do |_pdf_report_images| %>
<%= render OpenProject::Common::DividerComponent.new %>
<%= render(Primer::Alpha::CheckBox.new(name: "show_images",
checked: true,
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.pdf.include_images.label"),
caption: I18n.t("export.dialog.pdf.include_images.caption"),
visually_hide_label: false)) %>
<%= render(
Primer::Alpha::CheckBox.new(
name: "show_images",
checked: true,
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.pdf.include_images.label"),
caption: I18n.t("export.dialog.pdf.include_images.caption"),
visually_hide_label: false
)
) %>
<% end %>
<% end %>
@@ -1,5 +1,5 @@
<%= render WorkPackages::Exports::ColumnSelectionComponent.new(
query,
"columns-select-export-pdf-table",
I18n.t("export.dialog.columns.input_caption_table")
) %>
query,
"columns-select-export-pdf-table",
I18n.t("export.dialog.columns.input_caption_table")
) %>
@@ -1,31 +1,37 @@
<%= flex_layout do |container| %>
<%= container.with_row do |_columns| %>
<%= render WorkPackages::Exports::ColumnSelectionComponent.new(
query,
"columns-select-export-xls",
I18n.t("export.dialog.columns.input_caption_table")
) %>
query,
"columns-select-export-xls",
I18n.t("export.dialog.columns.input_caption_table")
) %>
<% end %>
<%= container.with_row do |_xls_include_relations| %>
<%= render OpenProject::Common::DividerComponent.new %>
<%= render(Primer::Alpha::CheckBox.new(
id: "show_relations_xls",
name: "show_relations",
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.xls.include_relations.label"),
caption: I18n.t("export.dialog.xls.include_relations.caption"),
visually_hide_label: false)) %>
<%= render(
Primer::Alpha::CheckBox.new(
id: "show_relations_xls",
name: "show_relations",
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.xls.include_relations.label"),
caption: I18n.t("export.dialog.xls.include_relations.caption"),
visually_hide_label: false
)
) %>
<% end %>
<%= container.with_row do |_xls_include_description| %>
<%= render OpenProject::Common::DividerComponent.new %>
<%= render(Primer::Alpha::CheckBox.new(
id: "show_descriptions_xls",
name: "show_descriptions",
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.xls.include_descriptions.label"),
caption: I18n.t("export.dialog.xls.include_descriptions.caption"),
visually_hide_label: false)) %>
<%= render(
Primer::Alpha::CheckBox.new(
id: "show_descriptions_xls",
name: "show_descriptions",
value: "true",
unchecked_value: "false",
label: I18n.t("export.dialog.xls.include_descriptions.label"),
caption: I18n.t("export.dialog.xls.include_descriptions.caption"),
visually_hide_label: false
)
) %>
<% end %>
<% end %>
@@ -16,12 +16,16 @@
grid.with_area(:assignee, tag: :div, font_size: :small, color: :muted) do
if @assignee.present?
# Render the avatar without a hover card => opening another hover card within a hover card is not supported
render(Users::AvatarComponent.new(user: @assignee,
show_name: true,
link: false,
size: :mini,
classes: "op-wp-hover-card--principal",
hover_card: { active: false }))
render(
Users::AvatarComponent.new(
user: @assignee,
show_name: true,
link: false,
size: :mini,
classes: "op-wp-hover-card--principal",
hover_card: { active: false }
)
)
else
concat(render(Primer::Beta::Octicon.new(icon: :person, mr: 1)))
concat(render(Primer::Beta::Text.new) { "-" })
@@ -3,14 +3,16 @@
flex.with_column(mr: 2) do
render(WorkPackages::HighlightedTypeComponent.new(work_package: @work_package, font_size: :small))
end
flex.with_column(mr: 2) do
render(Primer::Beta::Link.new(
href: url_for(controller: "/work_packages", action: "show", id: @work_package),
title: @work_package.subject,
target: :_blank,
font_size: @font_size,
color: :muted
)) { "##{@work_package.id}" }
flex.with_column(mr: 2) do
render(
Primer::Beta::Link.new(
href: url_for(controller: "/work_packages", action: "show", id: @work_package),
title: @work_package.subject,
target: :_blank,
font_size: @font_size,
color: :muted
)
) { "##{@work_package.id}" }
end
flex.with_column do
render WorkPackages::StatusBadgeComponent.new(status: @work_package.status)
@@ -11,11 +11,15 @@
) do |f| %>
<%= flex_layout do |modal_body| %>
<% modal_body.with_row(classes: "FormControl-horizontalGroup--sm-vertical") do |_fields| %>
<%= render(WorkPackages::ProgressForm.new(f,
work_package:,
mode:,
focused_field:,
touched_field_map:)) %>
<%= render(
WorkPackages::ProgressForm.new(
f,
work_package:,
mode:,
focused_field:,
touched_field_map:
)
) %>
<% end %>
<% modal_body.with_row(mt: 3) do |_tooltip| %>
@@ -27,8 +31,12 @@
<% modal_body.with_row(mt: 3) do |_actions_row| %>
<%= flex_layout(justify_content: :flex_end) do |action_buttons| %>
<%= action_buttons.with_column do %>
<%= render(Primer::Beta::Button.new(scheme: :primary,
type: :submit)) { t(:button_save) } %>
<%= render(
Primer::Beta::Button.new(
scheme: :primary,
type: :submit
)
) { t(:button_save) } %>
<% end %>
<% end %>
<% end %>
@@ -11,18 +11,26 @@
) do |f| %>
<%= flex_layout do |modal_body| %>
<% modal_body.with_row(classes: "FormControl-horizontalGroup--sm-vertical") do |_fields| %>
<%= render(WorkPackages::ProgressForm.new(f,
work_package:,
mode:,
focused_field:,
touched_field_map:)) %>
<%= render(
WorkPackages::ProgressForm.new(
f,
work_package:,
mode:,
focused_field:,
touched_field_map:
)
) %>
<% end %>
<% modal_body.with_row(mt: 3) do |_actions_row| %>
<%= flex_layout(justify_content: :flex_end) do |action_buttons| %>
<%= action_buttons.with_column do %>
<%= render(Primer::Beta::Button.new(scheme: :primary,
type: :submit)) { t(:button_save) } %>
<%= render(
Primer::Beta::Button.new(
scheme: :primary,
type: :submit
)
) { t(:button_save) } %>
<% end %>
<% end %>
<% end %>
@@ -15,35 +15,49 @@
<%= render(WorkPackages::Reminder::Note.new(f)) %>
<% end %>
<% if reminder.persisted? %>
<%= form_flex_container.with_row(flex_layout: true,
justify_content: :space_between) do |actions_row| %>
<%= form_flex_container.with_row(
flex_layout: true,
justify_content: :space_between
) do |actions_row| %>
<%= actions_row.with_column do %>
<%= render(Primer::Beta::Button.new(
scheme: :danger,
type: :submit,
formaction: work_package_reminder_path(remindable, reminder),
formmethod: :delete
)) { I18n.t(:button_remove_reminder) } %>
<%= render(
Primer::Beta::Button.new(
scheme: :danger,
type: :submit,
formaction: work_package_reminder_path(remindable, reminder),
formmethod: :delete
)
) { I18n.t(:button_remove_reminder) } %>
<% end %>
<%= actions_row.with_column(flex_layout: true) do |actions_sub_row| %>
<%= actions_sub_row.with_column(mr: 2) do %>
<%= render(Primer::Beta::Button.new(**cancel_button_props)) { I18n.t(:button_cancel) } %>
<% end %>
<%= actions_sub_row.with_column do %>
<%= render(Primer::Beta::Button.new(scheme: :primary,
type: :submit)) { I18n.t(:button_save) } %>
<%= render(
Primer::Beta::Button.new(
scheme: :primary,
type: :submit
)
) { I18n.t(:button_save) } %>
<% end %>
<% end %>
<% end %>
<% else %>
<%= form_flex_container.with_row(flex_layout: true,
justify_content: :flex_end) do |actions_row| %>
<%= form_flex_container.with_row(
flex_layout: true,
justify_content: :flex_end
) do |actions_row| %>
<%= actions_row.with_column(mr: 2) do %>
<%= render(Primer::Beta::Button.new(**cancel_button_props)) { I18n.t(:button_cancel) } %>
<% end %>
<%= actions_row.with_column do %>
<%= render(Primer::Beta::Button.new(scheme: :primary,
type: :submit)) { I18n.t(:button_set_reminder) } %>
<%= render(
Primer::Beta::Button.new(
scheme: :primary,
type: :submit
)
) { I18n.t(:button_set_reminder) } %>
<% end %>
<% end %>
<% end %>
@@ -13,9 +13,11 @@
end
@items.each do |item|
menu.with_item(label: item.name,
content_arguments: { classes: "__hl_inline_status_#{item.id}",
align_items: :center }) do |menu_item|
menu.with_item(
label: item.name,
content_arguments: { classes: "__hl_inline_status_#{item.id}",
align_items: :center }
) do |menu_item|
menu_item.with_trailing_visual_icon(icon: :lock) if item.is_readonly?
end
end
@@ -32,24 +32,28 @@ See COPYRIGHT and LICENSE files for more details.
header.with_title { title }
header.with_breadcrumbs(breadcrumb_items)
header.with_action_button(tag: :a,
mobile_icon: :copy,
mobile_label: t(:button_copy),
size: :medium,
href: copy_workflows_path,
aria: { label: I18n.t(:button_copy) },
title: I18n.t(:button_copy)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :copy,
mobile_label: t(:button_copy),
size: :medium,
href: copy_workflows_path,
aria: { label: I18n.t(:button_copy) },
title: I18n.t(:button_copy)
) do |button|
button.with_leading_visual_icon(icon: :copy)
t(:button_copy)
end
header.with_action_button(tag: :a,
mobile_icon: :info,
mobile_label: t(:label_workflow_summary),
size: :medium,
href: workflows_path,
aria: { label: I18n.t(:label_workflow_summary) },
title: I18n.t(:label_workflow_summary)) do |button|
header.with_action_button(
tag: :a,
mobile_icon: :info,
mobile_label: t(:label_workflow_summary),
size: :medium,
href: workflows_path,
aria: { label: I18n.t(:label_workflow_summary) },
title: I18n.t(:label_workflow_summary)
) do |button|
button.with_leading_visual_icon(icon: :info)
t(:label_workflow_summary)
end
+9 -7
View File
@@ -28,8 +28,10 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<div id="nav-login-content">
<%= styled_form_tag({controller: "/account", action: "login"},
autocomplete: "off", class: "-vertical") do %>
<%= styled_form_tag(
{ controller: "/account", action: "login" },
autocomplete: "off", class: "-vertical"
) do %>
<%= back_url_to_current_page_hidden_field_tag %>
<div class="grid-block">
@@ -47,8 +49,8 @@ See COPYRIGHT and LICENSE files for more details.
<% elsif Setting::SelfRegistration.enabled? %>
<%# show here if autologin is disabled, otherwise below lost_password link %>
<%= link_to t(:label_register),
account_register_path,
title: t(:label_register) %>
account_register_path,
title: t(:label_register) %>
<% end %>
</div>
</div>
@@ -60,14 +62,14 @@ See COPYRIGHT and LICENSE files for more details.
</div>
<div class="form--field-extra-actions">
<% if Setting.lost_password? %>
<%= link_to t(:label_password_lost), {controller: "/account", action: "lost_password"} %>
<%= link_to t(:label_password_lost), { controller: "/account", action: "lost_password" } %>
<% end %>
<% if Setting::Autologin.enabled? && Setting::SelfRegistration.enabled? %>
<%# show here if autologin is enabled, otherwise below login field %>
<%= "<br>".html_safe if Setting.lost_password? %>
<%= link_to t(:label_register),
account_register_path,
title: t(:label_register) %>
account_register_path,
title: t(:label_register) %>
<% end %>
</div>
</div>
@@ -28,11 +28,11 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
<%= styled_form_tag(
{action: "login"},
{ action: "login" },
autocomplete: "off",
class: "-wide-labels user-login--form",
data: { turbo: false } # allow redirects without turbo
) do %>
) do %>
<%= back_url_hidden_field_tag %>
<div class="form--field -required">
+2 -1
View File
@@ -31,7 +31,8 @@ See COPYRIGHT and LICENSE files for more details.
@user,
url: account_register_path,
data: { turbo: false },
html: { class: "form -wide-labels spot-modal" }) do |f| %>
html: { class: "form -wide-labels spot-modal" }
) do |f| %>
<%= back_url_hidden_field_tag use_referer: false %>
<%= error_messages_for :user %>
<div id="spotModalTitle" class="spot-modal--header">

Some files were not shown because too many files have changed in this diff Show More