Skip to content

Commit

Permalink
Merge branch 'release/14.2' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
akabiru committed Jun 12, 2024
2 parents 091775e + 622c27e commit 31ceb4e
Show file tree
Hide file tree
Showing 139 changed files with 1,867 additions and 1,170 deletions.
2 changes: 0 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,6 @@ gem "turbo-rails", "~> 2.0.0"

gem "httpx"

gem "gitlab_chronic_duration"

group :test do
gem "launchy", "~> 3.0.0"
gem "rack-test", "~> 2.1.0"
Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,6 @@ GEM
fuubar (2.5.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
gitlab_chronic_duration (0.12.0)
numerizer (~> 0.2)
glob (0.4.0)
globalid (1.2.1)
activesupport (>= 6.1)
Expand Down Expand Up @@ -1208,7 +1206,6 @@ DEPENDENCIES
fog-aws
friendly_id (~> 5.5.0)
fuubar (~> 2.5.0)
gitlab_chronic_duration
gon (~> 6.4.0)
good_job (= 3.26.2)
google-apis-gmail_v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
) do |form|
concat(render(Primer::Alpha::Dialog::Body.new(
id: dialog_body_id, test_selector: dialog_body_id, aria: { label: title },
classes: "FormControl-horizontalGroup--sm-vertical FormControl-horizontalGroup--center-aligned",
style: "min-height: 300px"
)) do
render(Projects::CustomFields::CustomFieldMappingForm.new(form, project_custom_field: @project_custom_field))
Expand Down
43 changes: 3 additions & 40 deletions app/contracts/settings/working_days_and_hours_params_contract.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ class WorkingDaysAndHoursParamsContract < ::ParamsContract

validate :working_days_are_present
validate :hours_per_day_are_present
validate :days_per_week_are_present
validate :days_per_month_are_present
validate :durations_are_positive_values
validate :durations_are_within_bounds
validate :days_per_week_and_days_per_month_are_consistent
validate :unique_job

protected
Expand All @@ -53,45 +50,19 @@ def hours_per_day_are_present
end
end

def days_per_week_are_present
if days_per_week.blank?
errors.add :base, :days_per_week_are_missing
end
end

def days_per_month_are_present
if days_per_month.blank?
errors.add :base, :days_per_month_are_missing
end
end

def durations_are_positive_values
if hours_per_day &&
days_per_week &&
days_per_month &&
any_duration_is_negative_or_zero?
hours_per_day_is_negative_or_zero?
errors.add :base, :durations_are_not_positive_numbers
end
end

def durations_are_within_bounds
errors.add :base, :hours_per_day_is_out_of_bounds if hours_per_day.to_i > 24
errors.add :base, :days_per_week_is_out_of_bounds if days_per_week.to_i > 7
errors.add :base, :days_per_month_is_out_of_bounds if days_per_month.to_i > 31
end

def any_duration_is_negative_or_zero?
!hours_per_day.to_i.positive? ||
!days_per_week.to_i.positive? ||
!days_per_month.to_i.positive?
end

def days_per_week_and_days_per_month_are_consistent
if days_per_week &&
days_per_month &&
days_per_week.to_i != days_per_month.to_i / ChronicDuration::FULL_WEEKS_PER_MONTH
errors.add :base, :days_per_week_and_days_per_month_are_inconsistent
end
def hours_per_day_is_negative_or_zero?
!hours_per_day.to_i.positive?
end

def unique_job
Expand All @@ -107,13 +78,5 @@ def working_days
def hours_per_day
params[:hours_per_day]
end

def days_per_week
params[:days_per_week]
end

def days_per_month
params[:days_per_month]
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ProjectCustomFieldsController < ::Admin::SettingsController
before_action :prepare_custom_option_position, only: %i(update create)
before_action :find_custom_option, only: :delete_option
before_action :project_custom_field_mappings_query, only: %i[project_mappings unlink]
before_action :find_link_project_custom_field_mapping, only: :link
before_action :find_custom_field_projects_to_link, only: :link
before_action :find_unlink_project_custom_field_mapping, only: :unlink
# rubocop:enable Rails/LexicallyScopedActionFilter

Expand Down Expand Up @@ -75,15 +75,15 @@ def project_mappings

def link
create_service = ProjectCustomFieldProjectMappings::BulkCreateService
.new(user: current_user, project: @project, project_custom_field: @custom_field,
.new(user: current_user, projects: @projects, project_custom_field: @custom_field,
include_sub_projects: include_sub_projects?)
.call

create_service.on_success { render_project_list }

create_service.on_failure do
update_flash_message_via_turbo_stream(
message: join_flash_messages(create_service.errors.full_messages),
message: join_flash_messages(create_service.errors),
full: true, dismiss_scheme: :hide, scheme: :danger
)
end
Expand Down Expand Up @@ -195,8 +195,8 @@ def find_unlink_project_custom_field_mapping
respond_with_turbo_streams
end

def find_link_project_custom_field_mapping
@project = Project.find(permitted_params.project_custom_field_project_mapping[:project_id])
def find_custom_field_projects_to_link
@projects = Project.find(params.to_unsafe_h[:project_custom_field_project_mapping][:project_ids])
rescue ActiveRecord::RecordNotFound
update_flash_message_via_turbo_stream(
message: t(:notice_file_not_found), full: true, dismiss_scheme: :hide, scheme: :danger
Expand All @@ -220,7 +220,7 @@ def drop_success_streams(call)
end

def include_sub_projects?
ActiveRecord::Type::Boolean.new.cast(permitted_params.project_custom_field_project_mapping[:include_sub_projects])
ActiveRecord::Type::Boolean.new.cast(params.to_unsafe_h[:project_custom_field_project_mapping][:include_sub_projects])
end
end
end
18 changes: 12 additions & 6 deletions app/controllers/my_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ def account; end

def update_account
write_settings

# If mail changed, expire all other sessions
if @user.previous_changes['mail'] && ::Sessions::DropOtherSessionsService.call(@user, session)
flash[:info] = "#{flash[:notice]} #{t(:notice_account_other_session_expired)}"
flash.delete :notice
end
end

def settings; end
Expand Down Expand Up @@ -219,6 +213,7 @@ def write_settings

if result&.success
flash[:notice] = notice_account_updated
handle_email_changes
else
flash[:error] = error_account_update_failed(result)
end
Expand All @@ -228,6 +223,17 @@ def write_settings

helper_method :has_tokens?

def handle_email_changes
# If mail changed, expire all other sessions
if @user.previous_changes['mail']
Users::DropTokensService.new(current_user: @user).call!
Sessions::DropOtherSessionsService.call!(@user, session)

flash[:info] = "#{flash[:notice]} #{t(:notice_account_other_session_expired)}"
flash.delete :notice
end
end

def has_tokens?
Setting.feeds_enabled? || Setting.rest_api_enabled? || current_user.ical_tokens.any?
end
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ def show
.where.not(project_id: nil)
.where(id: Member.visible(current_user))

@groups = @user.groups.visible

if can_show_user?
@events = events
render layout: (can_manage_or_create_users? ? "admin" : "no_menu")
Expand Down
11 changes: 6 additions & 5 deletions app/forms/projects/custom_fields/custom_field_mapping_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,23 @@

module Projects::CustomFields
class CustomFieldMappingForm < ApplicationForm
form do |f|
f.group(layout: :horizontal) do |f_group|
f_group.project_autocompleter(
form do |form|
form.group(layout: :horizontal) do |group|
group.project_autocompleter(
name: :id,
label: Project.model_name.human,
visually_hide_label: true,
autocomplete_options: {
openDirectly: false,
focusDirectly: false,
multiple: true,
dropdownPosition: "bottom",
disabledProjects: projects_with_custom_field_mapping,
inputName: "project_custom_field_project_mapping[project_id]"
inputName: "project_custom_field_project_mapping[project_ids]"
}
)

f_group.check_box(
group.check_box(
name: :include_sub_projects,
label: I18n.t("projects.settings.project_custom_fields.new_project_mapping_form.include_sub_projects"),
checked: false,
Expand Down
2 changes: 1 addition & 1 deletion app/helpers/omniauth_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ def omniauth_direct_login?
# If this option is active /login will lead directly to the configured omniauth provider
# and so will a click on 'Sign in' (as opposed to opening the drop down menu).
def direct_login_provider
Setting.omniauth_direct_login_provider
Setting.omniauth_direct_login_provider.presence
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,30 @@
#++
module WorkPackage::Exports
module Formatters
class DerivedRemainingHours < ::Exports::Formatters::Default
class CompoundHours < ::Exports::Formatters::Default
def self.apply?(name, _export_format)
%i[derived_remaining_time derived_remaining_hours].include?(name.to_sym)
name.to_sym == key
end

def format(work_package, **)
formatted_derived_hours(work_package)
hours = format_value(work_package.public_send(attribute))
derived_hours = total_prefix(format_value(work_package.public_send(:"derived_#{attribute}")))

[hours, derived_hours].compact.join(" ").presence
end

def format_value(value, _options = nil)
DurationConverter.output(value)
end

private

def formatted_hours(value)
value.nil? ? nil : "#{value} #{I18n.t('export.units.hours')}"
def attribute
self.class.key
end

def formatted_derived_hours(work_package)
if (derived_estimated_value = work_package.derived_estimated_hours)
formatted_hours(derived_estimated_value)
end
def total_prefix(value)
value && "· Σ #{value}"
end
end
end
Expand Down
32 changes: 1 addition & 31 deletions app/models/work_package/exports/formatters/estimated_hours.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,7 @@
#++
module WorkPackage::Exports
module Formatters
class EstimatedHours < ::Exports::Formatters::Default
def self.apply?(name, _export_format)
name.to_sym == :estimated_hours
end

def format(work_package, **)
estimated_hours = formatted_hours(work_package.estimated_hours)
derived_hours = formatted_derived_hours(work_package)

if estimated_hours.nil? || derived_hours.nil?
return estimated_hours || derived_hours
end

"#{estimated_hours} #{derived_hours}"
end

def format_value(value, _options)
formatted_hours(value)
end

private

def formatted_hours(value)
value.nil? ? nil : "#{value} #{I18n.t('export.units.hours')}"
end

def formatted_derived_hours(work_package)
if (derived_estimated_value = work_package.derived_estimated_hours)
"· Σ #{formatted_hours(derived_estimated_value)}"
end
end
class EstimatedHours < ::WorkPackage::Exports::Formatters::CompoundHours
end
end
end
10 changes: 2 additions & 8 deletions app/models/work_package/exports/formatters/hours.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,11 @@ module WorkPackage::Exports
module Formatters
class Hours < ::Exports::Formatters::Default
def self.apply?(name, export_format)
%i[remaining_hours spent_hours].include?(name.to_sym) && export_format == :pdf
name.to_sym == :spent_hours && export_format == :pdf
end

def format_value(value, _options)
formatted_hours(value)
end

private

def formatted_hours(value)
value.nil? ? "" : "#{value} #{I18n.t('export.units.hours')}"
DurationConverter.output(value)
end
end
end
Expand Down
33 changes: 33 additions & 0 deletions app/models/work_package/exports/formatters/remaining_hours.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#-- 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 WorkPackage::Exports
module Formatters
class RemainingHours < ::WorkPackage::Exports::Formatters::CompoundHours
end
end
end
Loading

0 comments on commit 31ceb4e

Please sign in to comment.