Skip to content

Commit

Permalink
Merge branch 'release/15.0' into documentation/fix-spelling
Browse files Browse the repository at this point in the history
# Conflicts:
#	docs/release-notes/15-0-0/README.md
  • Loading branch information
as-op committed Nov 13, 2024
2 parents 93100d4 + c6b2e94 commit 56a54d0
Show file tree
Hide file tree
Showing 227 changed files with 2,447 additions and 1,634 deletions.
28 changes: 13 additions & 15 deletions app/components/work_packages/activities_tab/index_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class IndexComponent < ApplicationComponent
include ApplicationHelper
include OpPrimer::ComponentHelpers
include OpTurbo::Streamable
include WorkPackages::ActivitiesTab::SharedHelpers

def initialize(work_package:, last_server_timestamp:, filter: :all)
super
Expand All @@ -48,27 +49,24 @@ def initialize(work_package:, last_server_timestamp:, filter: :all)
attr_reader :work_package, :filter, :last_server_timestamp

def wrapper_data_attributes
stimulus_controller = "work-packages--activities-tab--index"

{
test_selector: "op-wp-activity-tab",
controller: "work-packages--activities-tab--index",
controller: stimulus_controller,
"application-target": "dynamic",
"work-packages--activities-tab--index-update-streams-url-value": update_streams_work_package_activities_url(
work_package
),
"work-packages--activities-tab--index-sorting-value": journal_sorting,
"work-packages--activities-tab--index-filter-value": filter,
"work-packages--activities-tab--index-user-id-value": User.current.id,
"work-packages--activities-tab--index-work-package-id-value": work_package.id,
"work-packages--activities-tab--index-polling-interval-in-ms-value": polling_interval,
"work-packages--activities-tab--index-notification-center-path-name-value": notifications_path,
"work-packages--activities-tab--index-last-server-timestamp-value": last_server_timestamp
"#{stimulus_controller}-update-streams-url-value": update_streams_work_package_activities_url(work_package),
"#{stimulus_controller}-sorting-value": journal_sorting,
"#{stimulus_controller}-filter-value": filter,
"#{stimulus_controller}-user-id-value": User.current.id,
"#{stimulus_controller}-work-package-id-value": work_package.id,
"#{stimulus_controller}-polling-interval-in-ms-value": polling_interval,
"#{stimulus_controller}-notification-center-path-name-value": notifications_path,
"#{stimulus_controller}-show-conflict-flash-message-url-value": show_conflict_flash_message_work_packages_path,
"#{stimulus_controller}-last-server-timestamp-value": last_server_timestamp
}
end

def journal_sorting
User.current.preference&.comments_sorting || "desc"
end

def polling_interval
# Polling interval should only be adjustable in test environment
if Rails.env.test?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class FilterAndSortingComponent < ApplicationComponent
include ApplicationHelper
include OpPrimer::ComponentHelpers
include OpTurbo::Streamable
include WorkPackages::ActivitiesTab::SharedHelpers

def initialize(work_package:, filter: :all)
super
Expand All @@ -59,10 +60,6 @@ def show_only_changes?
filter == :only_changes
end

def journal_sorting
User.current.preference&.comments_sorting || "desc"
end

def desc_sorting?
journal_sorting == "desc"
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ class IndexComponent < ApplicationComponent
include ApplicationHelper
include OpPrimer::ComponentHelpers
include OpTurbo::Streamable
include WorkPackages::ActivitiesTab::SharedHelpers

def initialize(work_package:, filter: :all)
super
Expand All @@ -55,10 +56,6 @@ def insert_target_modifier_id
"work-package-journal-days"
end

def journal_sorting
User.current.preference&.comments_sorting || "desc"
end

def journal_sorting_desc?
journal_sorting == "desc"
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<%=
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(
Expand Down Expand Up @@ -45,7 +47,7 @@
end
header_end_container.with_column do
render(Primer::Beta::Link.new(
href: "#",
href: activity_url(journal),
scheme: :secondary,
underline: false,
font_size: :small,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def wrapper_data_attributes
{
controller: "work-packages--activities-tab--item",
"application-target": "dynamic",
"work-packages--activities-tab--item-activity-url-value": activity_url
"work-packages--activities-tab--item-activity-url-value": activity_url(journal)
}
end

Expand All @@ -68,14 +68,6 @@ def noop?
journal.noop?
end

def activity_url
"#{project_work_package_url(journal.journable.project, journal.journable)}/activity#{activity_anchor}"
end

def activity_anchor
"#activity-#{journal.sequence_version}"
end

def updated?
return false if journal.initial?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
my: 0,
border: :left,
classes: "work-packages-activities-tab-journals-item-component-details--journal-details-container",
data: { initial: journal.initial? }
data: {
"journal-with-changeset-updated-at": journal.updated_at.to_i, # used by the stimulus controller to maintain state
"journal-with-changeset-user-id": journal.user_id, # used by the stimulus controller to maintain state
initial: journal.initial? # used by the stimulus controller to render correctly
}
) do |details_container|
case filter
when :only_comments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ def render_header_start(header_container)

def render_timeline_icon(container)
container.with_column(mr: 2, classes: "work-packages-activities-tab-journals-item-component-details--timeline-icon") do
icon_name = journal.initial? ? "diff-added" : "diff-modified"
render Primer::Beta::Octicon.new(icon: icon_name, size: :small, "aria-label": icon_aria_label, color: :subtle)
render Primer::Beta::Octicon.new(icon: "diff-modified", size: :small, "aria-label": icon_aria_label, color: :subtle)
end
end

Expand Down Expand Up @@ -187,7 +186,7 @@ def render_activity_link(container)
classes: "work-packages-activities-tab-journals-item-component-details--activity-link-container"
) do
render(Primer::Beta::Link.new(
href: "#",
href: activity_url(journal),
scheme: :secondary,
underline: false,
font_size: :small,
Expand Down Expand Up @@ -265,10 +264,6 @@ def render_detail_description(container, rendered_detail)
def render_empty_line(details_container)
details_container.with_row(my: 1, font_size: :small, classes: "empty-line")
end

def journal_sorting
User.current.preference&.comments_sorting || "desc"
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
format_text(journal, :notes)
end
end
journal_container.with_row(mt: 3, flex_layout: true) do |reactions_container|
journal_container.with_row(flex_layout: true) do |reactions_container|
reactions_container.with_column do
render(WorkPackages::ActivitiesTab::Journals::ItemComponent::AddReactions.new(journal:, grouped_emoji_reactions:))
end
Expand Down
12 changes: 12 additions & 0 deletions app/components/work_packages/activities_tab/shared_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@ def truncated_user_name(user)
user.name
end
end

def journal_sorting
User.current.preference&.comments_sorting || OpenProject::Configuration.default_comment_sort_order
end

def activity_url(journal)
"#{project_work_package_url(journal.journable.project, journal.journable)}/activity#{activity_anchor(journal)}"
end

def activity_anchor(journal)
"#activity-#{journal.sequence_version}"
end
end
end
end
72 changes: 72 additions & 0 deletions app/components/work_packages/update_conflict_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2024 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++

module WorkPackages
class UpdateConflictComponent < ApplicationComponent
include OpPrimer::ComponentHelpers
include OpTurbo::Streamable

def initialize(scheme: :warning, button_text: I18n.t("label_meeting_reload"))
super

@scheme = scheme
@button_text = button_text

if %i[warning danger].exclude?(@scheme)
raise ArgumentError, "Invalid scheme: #{@scheme}. Must be :warning or :danger."
end
end

def call
render(
::OpPrimer::FlashComponent.new(
scheme: @scheme,
icon: @scheme == :danger ? :stop : :"alert-fill",
dismiss_scheme: :hide,
unique_key: "work-package-update-conflict",
data: {
"banner-scheme": @scheme.to_s # used for testing
}
)
) do |banner|
banner.with_action_button(
tag: :a,
href: "#",
data: {
turbo: false,
action: "click->flash#reloadPage",
test_selector: "op-work-package-update-conflict-reload-button"
},
size: :medium
) { @button_text }

content
end
end
end
end
33 changes: 28 additions & 5 deletions app/controllers/work_packages/activities_tab_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def set_filter
end

def journal_sorting
User.current.preference&.comments_sorting || "desc"
User.current.preference&.comments_sorting || OpenProject::Configuration.default_comment_sort_order
end

def journal_params
Expand Down Expand Up @@ -349,11 +349,34 @@ def rerender_updated_journals(journals, last_update_timestamp, grouped_emoji_rea

def rerender_journals_with_updated_notification(journals, last_update_timestamp, grouped_emoji_reactions)
# Case: the user marked the journal as read somewhere else and expects the bubble to disappear
journals
.joins(:notifications)
#
# below code stopped working with the introduction of the sequence_version query
# I believe it is due to the fact that the notification join does not work well with the sequence_version query
# see below comments from my debugging session
# journals
# .joins(:notifications)
# .where("notifications.updated_at > ?", last_update_timestamp)
# .find_each do |journal|
# # DEBUGGING:
# # the journal id is actually 85 but below data is logged:
# # # journal id 14 (?!)
# # # journal sequence_version 22 (correct!)
# # the update stream has a wrong target then!
# # target="work-packages-activities-tab-journals-item-component-14"
# # instead of
# # target="work-packages-activities-tab-journals-item-component-85"
# update_item_show_component(journal:, grouped_emoji_reactions: grouped_emoji_reactions.fetch(journal.id, {}))
# end
#
# alternative approach in order to bypass the notification join issue in relation with the sequence_version query
Notification
.where(journal_id: journals.pluck(:id))
.where("notifications.updated_at > ?", last_update_timestamp)
.find_each do |journal|
update_item_show_component(journal:, grouped_emoji_reactions: grouped_emoji_reactions.fetch(journal.id, {}))
.find_each do |notification|
update_item_show_component(
journal: journals.find(notification.journal_id), # take the journal from the journals querried with sequence_version!
grouped_emoji_reactions: grouped_emoji_reactions.fetch(notification.journal_id, {})
)
end
end

Expand Down
16 changes: 16 additions & 0 deletions app/controllers/work_packages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class WorkPackagesController < ApplicationController
include Layout
include WorkPackagesControllerHelper
include OpTurbo::DialogStreamHelper
include OpTurbo::ComponentStream

accept_key_auth :index, :show

Expand All @@ -40,6 +41,8 @@ class WorkPackagesController < ApplicationController
before_action :load_and_authorize_in_optional_project,
:check_allowed_export,
:protect_from_unauthorized_export, only: %i[index export_dialog]

before_action :authorize, only: :show_conflict_flash_message
authorization_checked! :index, :show, :export_dialog

before_action :load_and_validate_query, only: :index, unless: -> { request.format.html? }
Expand Down Expand Up @@ -90,6 +93,19 @@ def export_dialog
respond_with_dialog WorkPackages::Exports::ModalDialogComponent.new(query: @query, project: @project, title: params[:title])
end

def show_conflict_flash_message
scheme = params[:scheme]&.to_sym || :danger

update_flash_message_via_turbo_stream(
component: WorkPackages::UpdateConflictComponent,
scheme:,
message: I18n.t("notice_locking_conflict_#{scheme}"),
button_text: I18n.t("notice_locking_conflict_action_button")
)

respond_with_turbo_streams
end

protected

def load_and_validate_query_for_export
Expand Down
3 changes: 1 addition & 2 deletions app/seeders/common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -402,5 +402,4 @@ global_roles:
t_name: Standard global role
position: 7
builtin: :standard_global
permissions:
- :view_user_email
permissions: []
7 changes: 7 additions & 0 deletions config/initializers/feature_decisions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,10 @@

OpenProject::FeatureDecisions.add :custom_field_of_type_hierarchy,
description: "Allows the use of the custom field type 'Hierarchy'."

# TODO: Remove once the feature flag primerized_work_package_activities is removed altogether
OpenProject::FeatureDecisions.define_singleton_method(:primerized_work_package_activities_active?) do
Rails.env.production? ||
(Setting.exists?("feature_primerized_work_package_activities_active") &&
Setting.send(:feature_primerized_work_package_activities_active?))
end
2 changes: 1 addition & 1 deletion config/initializers/permissions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@
{
versions: %i[index show status_by],
journals: %i[index],
work_packages: %i[show index],
work_packages: %i[show index show_conflict_flash_message],
work_packages_api: [:get],
"work_packages/reports": %i[report report_details],
"work_packages/activities_tab": %i[index update_streams update_sorting update_filter],
Expand Down
3 changes: 3 additions & 0 deletions config/locales/crowdin/af.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2822,6 +2822,9 @@ af:
notice_locking_conflict: "Information has been updated by at least one other user in the meantime."
notice_locking_conflict_additional_information: "The update(s) came from %{users}."
notice_locking_conflict_reload_page: "Please reload the page, review the changes and reapply your updates."
notice_locking_conflict_warning: "This page has been updated by someone else. To not lose your edits, copy them locally and reload to view the updated version."
notice_locking_conflict_danger: "Could not save your changes because of conflicting modifications. To not lose your edits, copy them locally and reload to view the updated version."
notice_locking_conflict_action_button: "Discard changes and reload"
notice_member_added: Added %{name} to the project.
notice_members_added: Added %{number} users to the project.
notice_member_removed: "Removed %{user} from project."
Expand Down
Loading

0 comments on commit 56a54d0

Please sign in to comment.