Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/release/15.0' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
ulferts committed Nov 12, 2024
2 parents 4bc2b9f + 41024a1 commit 478aa89
Show file tree
Hide file tree
Showing 169 changed files with 1,135 additions and 762 deletions.
1 change: 1 addition & 0 deletions app/components/_index.sass
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@import "work_packages/activities_tab/journals/index_component"
@import "work_packages/activities_tab/journals/item_component"
@import "work_packages/activities_tab/journals/item_component/details"
@import "work_packages/activities_tab/journals/item_component/add_reactions"
@import "work_packages/activities_tab/journals/item_component/reactions"
@import "shares/modal_body_component"
@import "shares/invite_user_form_component"
Expand Down
18 changes: 14 additions & 4 deletions app/components/projects/table_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,20 @@ def columns
end

def projects(query)
query
.results
.with_required_storage
.with_latest_activity
scope = query.results

# The two columns associated with the
# * disk storage
# * latest activity
# information are only available to admins.
# For non admins, the performance penalty of fetching the information therefore needs never be paid.
if User.current.admin?
scope = scope
.with_required_storage
.with_latest_activity
end

scope
.includes(:custom_values, :enabled_modules)
.paginate(page: helpers.page_param(params), per_page: helpers.per_page_param(params))
end
Expand Down
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 @@ -15,7 +15,7 @@
)

overlay.with_body(pt: 2, test_selector: "emoji-reactions-overlay") do
flex_layout do |add_reactions_container|
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(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.op-add-reactions-overlay
row-gap: var(--base-size-4, 4px)
@media screen and (max-width: $breakpoint-sm)
max-width: 200px
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 @@ -187,7 +187,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 +265,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
2 changes: 1 addition & 1 deletion 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
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
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/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2976,6 +2976,9 @@ en:
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
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,7 @@
as: :work_package_progress
end
get "/export_dialog" => "work_packages#export_dialog", on: :collection, as: "export_dialog"
get :show_conflict_flash_message, on: :collection # we don't need a specific work package for this

get "/split_view/update_counter" => "work_packages/split_view#update_counter",
on: :member
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ OpenProject provides means to fully erase both all identifiable information of a

- Data controllers can perform the deletion [through the administration](../../../system-admin-guide/users-permissions/users/).

- Depending on the configuration of your OpenProject instance, individual data subjects may perform the deletion of their own account through the [Delete Account](../../../user-guide/my-account/) page. If this is disabled, the request may be stated to the data controller.
- Depending on the configuration of your OpenProject instance, individual data subjects may perform the deletion of their own account through the [Delete Account](../../../user-guide/account-settings/) page. If this is disabled, the request may be stated to the data controller.

### Data Portability

Expand Down
Loading

0 comments on commit 478aa89

Please sign in to comment.