From 07caac7d916a7a158ef73d9c44922b11ee00450a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Thu, 22 Sep 2022 21:54:02 +0200 Subject: [PATCH 001/148] Fix backup job not looking for user config property https://community.openproject.org/work_packages/44251 --- app/workers/backup_job.rb | 15 +++++++++++---- spec/workers/backup_job_spec.rb | 29 +++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/app/workers/backup_job.rb b/app/workers/backup_job.rb index c5040584a8..be73860970 100644 --- a/app/workers/backup_job.rb +++ b/app/workers/backup_job.rb @@ -249,23 +249,30 @@ class BackupJob < ::ApplicationJob end def pg_env - config = ActiveRecord::Base.connection_db_config.configuration_hash entries = pg_env_to_connection_config.map do |key, config_key| - value = config[config_key].to_s + possible_keys = Array(config_key) + value = possible_keys + .lazy + .filter_map { |key| database_config[key] } + .first - [key.to_s, value] if value.present? + [key.to_s, value.to_s] if value.present? end entries.compact.to_h end + def database_config + @database_config ||= ActiveRecord::Base.connection_db_config.configuration_hash + end + ## # Maps the PG env variable name to the key in the AR connection config. def pg_env_to_connection_config { PGHOST: :host, PGPORT: :port, - PGUSER: :username, + PGUSER: %i[username user], PGPASSWORD: :password, PGDATABASE: :database } diff --git a/spec/workers/backup_job_spec.rb b/spec/workers/backup_job_spec.rb index ab8f1a1bd9..e2c3b6c1ed 100644 --- a/spec/workers/backup_job_spec.rb +++ b/spec/workers/backup_job_spec.rb @@ -69,7 +69,7 @@ describe BackupJob, type: :model do allow(job).to receive(:arguments).and_return arguments allow(job).to receive(:job_id).and_return job_id - expect(Open3).to receive(:capture3).and_return [nil, "Dump failed", db_dump_process_status] + allow(Open3).to receive(:capture3).and_return [nil, "Dump failed", db_dump_process_status] allow_any_instance_of(BackupJob) .to receive(:tmp_file_name).with("openproject", ".sql").and_return("/tmp/openproject.sql") @@ -85,6 +85,31 @@ describe BackupJob, type: :model do job.perform **arguments.first end + describe '#pg_env' do + subject { job.pg_env } + + context 'when config has user reference, not username (regression #44251)' do + let(:config_double) do + { + adapter: :postgresql, + password: "blabla", + database: "test", + user: "foobar" + } + end + + before do + allow(job).to receive(:database_config).and_return(config_double) + end + + it 'still sets a PGUSER' do + expect(subject['PGUSER']).to eq 'foobar' + expect(subject['PGPASSWORD']).to eq 'blabla' + expect(subject['PGDATABASE']).to eq 'test' + end + end + end + context "with a failed database dump" do let(:db_dump_success) { false } @@ -175,7 +200,7 @@ describe BackupJob, type: :model do allow_any_instance_of(LocalFileUploader).to receive(:cached?).and_return(true) allow_any_instance_of(LocalFileUploader) .to receive(:local_file) - .and_return(File.new(dummy_path)) + .and_return(File.new(dummy_path)) end after do From 9e8d301f6b4fccbc01ecaf6dca2c20ce87e2acf6 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 27 Sep 2022 15:14:44 +0200 Subject: [PATCH 002/148] set working days only toggle off only if start or end date is set on a non-working day --- .../team-planner/planner/team-planner.component.ts | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts index 8d9ceeac07..59dbf63aa4 100644 --- a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts +++ b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts @@ -752,17 +752,14 @@ export class TeamPlannerComponent extends UntilDestroyedMixin implements OnInit, } private handleDateClicked(info:DateSelectArg) { - const startDay = new Date(info.start).getDate(); - const endDay = new Date(info.end).getDate(); - const duration = endDay - startDay; - const ignoreNonWorkingDays = duration !== 1 ? false : this.weekdayService.isNonWorkingDay(info.start); + const nonWorkingDays = this.weekdayService.isNonWorkingDay(info.start) || this.weekdayService.isNonWorkingDay(info.end); this.openNewSplitCreate( info.startStr, // end date is exclusive this.workPackagesCalendar.getEndDateFromTimestamp(info.endStr), info.resource?.id || '', - ignoreNonWorkingDays, + nonWorkingDays, ); } From 650eb8d267c86596173765348b6beace521db2f4 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 27 Sep 2022 15:19:45 +0200 Subject: [PATCH 003/148] if work packkage has a duration, its duration should be reflected while dragging from add existing --- .../team-planner/team-planner/calendar-drag-drop.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/features/team-planner/team-planner/calendar-drag-drop.service.ts b/frontend/src/app/features/team-planner/team-planner/calendar-drag-drop.service.ts index 3af7af173c..c526ee74f3 100644 --- a/frontend/src/app/features/team-planner/team-planner/calendar-drag-drop.service.ts +++ b/frontend/src/app/features/team-planner/team-planner/calendar-drag-drop.service.ts @@ -10,7 +10,6 @@ import { BehaviorSubject } from 'rxjs'; import { SchemaCacheService } from 'core-app/core/schemas/schema-cache.service'; import { AuthorisationService } from 'core-app/core/model-auth/model-auth.service'; import { I18nService } from 'core-app/core/i18n/i18n.service'; -import { OpCalendarService } from 'core-app/features/calendar/op-calendar.service'; import { OpWorkPackagesCalendarService } from 'core-app/features/calendar/op-work-packages-calendar.service'; @Injectable() @@ -119,7 +118,8 @@ export class CalendarDragDropService { const startDate = moment(workPackage.startDate); const dueDate = moment(workPackage.dueDate); - const diff = dueDate.diff(startDate, 'days') + 1; + const duration = Number(moment.duration(workPackage.duration).asDays().toFixed(0)); + const diff = duration > 0 ? duration : dueDate.diff(startDate, 'days') + 1; return { id: `${workPackage.href as string}-external`, From 68d073c2cc34715e7cc3fa0101e87d0638cded47 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Thu, 22 Sep 2022 22:12:54 +0200 Subject: [PATCH 004/148] [#43675] Migration splitting involved notification setting and date defaults --- app/models/notification_setting.rb | 6 ++-- .../create_from_model_service.rb | 4 +-- .../user_preferences/update_service.rb | 3 +- config/locales/js-en.yml | 2 ++ db/migrate/20220922200908_add_assignee.rb | 20 +++++++++++++ ...notifications-settings-page.component.html | 28 +++++++++++++------ .../notifications-settings-page.component.ts | 24 +++++++++------- .../state/notification-setting.model.ts | 6 ++-- .../factories/notification_setting_factory.rb | 3 +- 9 files changed, 69 insertions(+), 27 deletions(-) create mode 100644 db/migrate/20220922200908_add_assignee.rb diff --git a/app/models/notification_setting.rb b/app/models/notification_setting.rb index a1e8b515d2..c22de82448 100644 --- a/app/models/notification_setting.rb +++ b/app/models/notification_setting.rb @@ -1,6 +1,7 @@ class NotificationSetting < ApplicationRecord WATCHED = :watched - INVOLVED = :involved + ASSIGNEE = :assignee + RESPONSIBLE = :responsible MENTIONED = :mentioned WORK_PACKAGE_CREATED = :work_package_created WORK_PACKAGE_COMMENTED = :work_package_commented @@ -19,7 +20,8 @@ class NotificationSetting < ApplicationRecord def self.all_settings [ WATCHED, - INVOLVED, + ASSIGNEE, + RESPONSIBLE, MENTIONED, WORK_PACKAGE_CREATED, WORK_PACKAGE_COMMENTED, diff --git a/app/services/notifications/create_from_model_service.rb b/app/services/notifications/create_from_model_service.rb index b471f7ecc7..12398b7f96 100644 --- a/app/services/notifications/create_from_model_service.rb +++ b/app/services/notifications/create_from_model_service.rb @@ -141,13 +141,13 @@ class Notifications::CreateFromModelService def settings_of_assigned project_applicable_settings(User.where(id: group_or_user_ids(journal.data.assigned_to)), project, - NotificationSetting::INVOLVED) + NotificationSetting::ASSIGNEE) end def settings_of_responsible project_applicable_settings(User.where(id: group_or_user_ids(journal.data.responsible)), project, - NotificationSetting::INVOLVED) + NotificationSetting::RESPONSIBLE) end def settings_of_subscribed diff --git a/app/services/user_preferences/update_service.rb b/app/services/user_preferences/update_service.rb index 23f5701bde..65f4e3040c 100644 --- a/app/services/user_preferences/update_service.rb +++ b/app/services/user_preferences/update_service.rb @@ -90,7 +90,8 @@ module UserPreferences conflict_target:, index_predicate:, columns: %i[watched - involved + assignee + responsible mentioned work_package_commented work_package_created diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index e9c22773ce..024912adc4 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -632,6 +632,8 @@ en: involved: title: 'Assigned to me or accountable' description: 'Receive notifications for all activities on work packages for which I am assignee or accountable' + assignee: 'Assignee' + responsible: 'Accountable' watched: 'Updates on watched items' work_package_commented: 'All new comments' work_package_created: 'New work packages' diff --git a/db/migrate/20220922200908_add_assignee.rb b/db/migrate/20220922200908_add_assignee.rb new file mode 100644 index 0000000000..8e15229d08 --- /dev/null +++ b/db/migrate/20220922200908_add_assignee.rb @@ -0,0 +1,20 @@ +class AddAssignee < ActiveRecord::Migration[7.0] + def change + change_table :notification_settings, bulk: true do |t| + t.column :assignee, :boolean, default: false, null: false + t.column :responsible, :boolean, default: false, null: false + end + + reversible do |change| + change.up do + NotificationSetting.where(involved: true).update_all(assignee: true, responsible: true) + remove_column :notification_settings, :involved, :boolean + end + + change.down do + add_column :notification_settings, :involved, :boolean + NotificationSetting.where(assignee: true).or(NotificationSetting.where(responsible: true)).update_all(involved: true) + end + end + end +end diff --git a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html index cfd46505b6..e35be13487 100644 --- a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html +++ b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html @@ -17,21 +17,31 @@ slot="input" />

{{ text.mentioned.description }}

- + + + + + - -

{{ text.involved.description }}

-
+
{{ text.alsoNotifyFor.title }}

{{ text.alsoNotifyFor.description }}

diff --git a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.ts b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.ts index 7e27710178..480e581ae4 100644 --- a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.ts +++ b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.ts @@ -21,7 +21,8 @@ import { INotificationSetting } from 'core-app/features/user-preferences/state/n export const myNotificationsPageComponentSelector = 'op-notifications-page'; interface IToastSettingsValue { - involved:boolean; + assignee:boolean; + responsible:boolean; workPackageCreated:boolean; workPackageProcessed:boolean; workPackageScheduled:boolean; @@ -49,7 +50,8 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl @Input() userId:string; public form = new FormGroup({ - involved: new FormControl(false), + assignee: new FormControl(false), + responsible: new FormControl(false), workPackageCreated: new FormControl(false), workPackageProcessed: new FormControl(false), workPackageScheduled: new FormControl(false), @@ -71,10 +73,6 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl title: this.I18n.t('js.notifications.settings.reasons.mentioned.title'), description: this.I18n.t('js.notifications.settings.reasons.mentioned.description'), }, - involved: { - title: this.I18n.t('js.notifications.settings.reasons.involved.title'), - description: this.I18n.t('js.notifications.settings.reasons.involved.description'), - }, watched: this.I18n.t('js.notifications.settings.reasons.watched'), work_package_commented: this.I18n.t('js.notifications.settings.reasons.work_package_commented'), work_package_created: this.I18n.t('js.notifications.settings.reasons.work_package_created'), @@ -86,6 +84,8 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl title: this.I18n.t('js.notifications.settings.project_specific.title'), description: this.I18n.t('js.notifications.settings.project_specific.description'), }, + assignee: this.I18n.t('js.notifications.settings.reasons.assignee'), + responsible: this.I18n.t('js.notifications.settings.reasons.responsible'), }; constructor( @@ -116,7 +116,8 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl return; } - this.form.get('involved')?.setValue(settings.involved); + this.form.get('assignee')?.setValue(settings.assignee); + this.form.get('responsible')?.setValue(settings.responsible); this.form.get('workPackageCreated')?.setValue(settings.workPackageCreated); this.form.get('workPackageProcessed')?.setValue(settings.workPackageProcessed); this.form.get('workPackageScheduled')?.setValue(settings.workPackageScheduled); @@ -139,7 +140,8 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl ) .forEach((setting) => projectSettings.push(new FormGroup({ project: new FormControl(setting._links.project), - involved: new FormControl(setting.involved), + assignee: new FormControl(setting.assignee), + responsible: new FormControl(setting.responsible), workPackageCreated: new FormControl(setting.workPackageCreated), workPackageProcessed: new FormControl(setting.workPackageProcessed), workPackageScheduled: new FormControl(setting.workPackageScheduled), @@ -161,7 +163,8 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl _links: { project: { href: null } }, watched: true, mentioned: true, - involved: notificationSettings.involved, + assignee: notificationSettings.assignee, + responsible: notificationSettings.responsible, workPackageCreated: notificationSettings.workPackageCreated, workPackageProcessed: notificationSettings.workPackageProcessed, workPackageScheduled: notificationSettings.workPackageScheduled, @@ -173,7 +176,8 @@ export class NotificationsSettingsPageComponent extends UntilDestroyedMixin impl _links: { project: { href: settings.project.href } }, watched: true, mentioned: true, - involved: settings.involved, + assignee: settings.assignee, + responsible: settings.responsible, workPackageCreated: settings.workPackageCreated, workPackageProcessed: settings.workPackageProcessed, workPackageScheduled: settings.workPackageScheduled, diff --git a/frontend/src/app/features/user-preferences/state/notification-setting.model.ts b/frontend/src/app/features/user-preferences/state/notification-setting.model.ts index d150484250..05f521205a 100644 --- a/frontend/src/app/features/user-preferences/state/notification-setting.model.ts +++ b/frontend/src/app/features/user-preferences/state/notification-setting.model.ts @@ -3,7 +3,8 @@ import { HalSourceLink } from 'core-app/features/hal/resources/hal-resource'; export interface INotificationSetting { _links:{ project:HalSourceLink }; watched:boolean; - involved:boolean; + assignee:boolean; + responsible:boolean; mentioned:boolean; workPackageCommented:boolean; workPackageCreated:boolean; @@ -28,7 +29,8 @@ export function buildNotificationSetting(project:null|HalSourceLink, params:Part title: project?.title, }, }, - involved: true, + assignee: true, + responsible: true, mentioned: true, watched: true, workPackageCommented: true, diff --git a/spec/factories/notification_setting_factory.rb b/spec/factories/notification_setting_factory.rb index f94a0c237e..bbd022b49d 100644 --- a/spec/factories/notification_setting_factory.rb +++ b/spec/factories/notification_setting_factory.rb @@ -1,6 +1,7 @@ FactoryBot.define do factory :notification_setting do - involved { true } + assignee { true } + responsible { true } mentioned { true } watched { true } work_package_commented { false } From 0c85cc4287428b840e89993100bd81f1c788eff5 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Mon, 26 Sep 2022 10:53:05 +0200 Subject: [PATCH 005/148] [#43675] fix specs --- app/seeders/admin_user_seeder.rb | 2 +- app/seeders/development_data/users_seeder.rb | 2 +- app/services/users/set_attributes_service.rb | 2 +- ...notification-settings-table.component.html | 22 +++++++++++++++---- .../notification-settings-table.component.ts | 10 ++++----- ...create_from_model_service_document_spec.rb | 8 +++---- .../notifications/reminder_mail_spec.rb | 3 ++- .../users/notifications/shared_examples.rb | 9 +++++--- ...ser_preference_representer_parsing_spec.rb | 12 ++++++---- spec/models/mail_handler_spec.rb | 2 +- .../create_from_model_service_comment_spec.rb | 4 ++-- .../create_from_model_service_message_spec.rb | 8 +++---- .../create_from_model_service_news_spec.rb | 4 ++-- .../create_from_model_service_wiki_spec.rb | 8 +++---- ...te_from_model_service_work_package_spec.rb | 8 +++---- ...mail_service_mentioned_integration_spec.rb | 13 ++++++++--- .../mentioned_journals_shared.rb | 3 ++- .../update_service_integration_spec.rb | 9 +++++--- spec/support/pages/notifications/settings.rb | 3 ++- spec/workers/mails/shared/watcher_job.rb | 8 +++---- 20 files changed, 86 insertions(+), 54 deletions(-) diff --git a/app/seeders/admin_user_seeder.rb b/app/seeders/admin_user_seeder.rb index 29470a0049..c531b4f8bf 100644 --- a/app/seeders/admin_user_seeder.rb +++ b/app/seeders/admin_user_seeder.rb @@ -55,7 +55,7 @@ class AdminUserSeeder < Seeder user.language = I18n.locale.to_s user.status = User.statuses[:active] user.force_password_change = force_password_change? - user.notification_settings.build(involved: true, mentioned: true, watched: true) + user.notification_settings.build(assignee: true, responsible: true, mentioned: true, watched: true) end end diff --git a/app/seeders/development_data/users_seeder.rb b/app/seeders/development_data/users_seeder.rb index 8cac0c2d16..d40985a6fa 100644 --- a/app/seeders/development_data/users_seeder.rb +++ b/app/seeders/development_data/users_seeder.rb @@ -103,7 +103,7 @@ module DevelopmentData user.status = User.statuses[:active] user.language = I18n.locale user.force_password_change = false - user.notification_settings.build(involved: true, mentioned: true, watched: true) + user.notification_settings.build(assignee: true, responsible: true, mentioned: true, watched: true) end end diff --git a/app/services/users/set_attributes_service.rb b/app/services/users/set_attributes_service.rb index 75ff215f43..9c2dc80bba 100644 --- a/app/services/users/set_attributes_service.rb +++ b/app/services/users/set_attributes_service.rb @@ -62,7 +62,7 @@ module Users end def initialize_notification_settings - model.notification_settings.build(involved: true, mentioned: true, watched: true) + model.notification_settings.build(assignee: true, responsible: true, mentioned: true, watched: true) end # rubocop:disable Metrics/AbcSize diff --git a/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.html b/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.html index 3aa7ed212d..9bbd16fb3d 100644 --- a/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.html +++ b/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.html @@ -30,15 +30,29 @@ -
{{ text.involved_header.title }}
-

{{ text.involved_header.description }}

+
{{ text.assignee }}
+ + + + + +
{{ text.responsible }}
+ + + + diff --git a/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.ts b/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.ts index 38cd81fc1c..28dfd1faf0 100644 --- a/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.ts +++ b/frontend/src/app/features/user-preferences/notifications-settings/table/notification-settings-table.component.ts @@ -9,7 +9,6 @@ import { FormArray, FormGroup, FormControl } from '@angular/forms'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { I18nService } from 'core-app/core/i18n/i18n.service'; import idFromLink from 'core-app/features/hal/helpers/id-from-link'; -import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service'; import { HalSourceLink } from 'core-app/features/hal/resources/hal-resource'; @Component({ @@ -30,10 +29,8 @@ export class NotificationSettingsTableComponent { title: this.I18n.t('js.notifications.settings.reasons.mentioned.title'), description: this.I18n.t('js.notifications.settings.reasons.mentioned.description'), }, - involved_header: { - title: this.I18n.t('js.notifications.settings.reasons.involved.title'), - description: this.I18n.t('js.notifications.settings.reasons.involved.description'), - }, + assignee: this.I18n.t('js.notifications.settings.reasons.assignee'), + responsible: this.I18n.t('js.notifications.settings.reasons.responsible'), watched_header: this.I18n.t('js.notifications.settings.reasons.watched'), work_package_commented_header: this.I18n.t('js.notifications.settings.reasons.work_package_commented'), work_package_created_header: this.I18n.t('js.notifications.settings.reasons.work_package_created'), @@ -55,7 +52,8 @@ export class NotificationSettingsTableComponent { addProjectSettings(project:HalSourceLink):void { this.settings.push(new FormGroup({ project: new FormControl(project), - involved: new FormControl(false), + assignee: new FormControl(false), + responsible: new FormControl(false), workPackageCreated: new FormControl(false), workPackageProcessed: new FormControl(false), workPackageScheduled: new FormControl(false), diff --git a/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb b/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb index cf8eb98141..e5829200fa 100644 --- a/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb +++ b/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb @@ -68,10 +68,10 @@ describe Notifications::CreateFromModelService, 'document', with_settings: { jou end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end @@ -116,10 +116,10 @@ describe Notifications::CreateFromModelService, 'document', with_settings: { jou end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end diff --git a/spec/features/notifications/reminder_mail_spec.rb b/spec/features/notifications/reminder_mail_spec.rb index cd1cd2dfec..b58757d0a8 100644 --- a/spec/features/notifications/reminder_mail_spec.rb +++ b/spec/features/notifications/reminder_mail_spec.rb @@ -36,7 +36,8 @@ describe "Reminder email sending", type: :feature, js: true do }, notification_settings: [ build(:notification_setting, - involved: true, + assignee: true, + responsible: true, watched: true, mentioned: true, work_package_commented: true, diff --git a/spec/features/users/notifications/shared_examples.rb b/spec/features/users/notifications/shared_examples.rb index 17ea5bde9d..7eeb576b23 100644 --- a/spec/features/users/notifications/shared_examples.rb +++ b/spec/features/users/notifications/shared_examples.rb @@ -15,7 +15,8 @@ shared_examples 'notification settings workflow' do settings_page.add_project project_alt # Set settings for project email - settings_page.configure_global involved: true, + settings_page.configure_global assignee: true, + responsible: true, work_package_commented: true, work_package_created: true, work_package_processed: true, @@ -24,7 +25,8 @@ shared_examples 'notification settings workflow' do # Set settings for project email settings_page.configure_project project: project, - involved: true, + assignee: true, + responsible: true, work_package_commented: false, work_package_created: false, work_package_processed: false, @@ -39,7 +41,8 @@ shared_examples 'notification settings workflow' do expect(notification_settings.where(project:).count).to eq 1 project_settings = notification_settings.find_by(project:) - expect(project_settings.involved).to be_truthy + expect(project_settings.assignee).to be_truthy + expect(project_settings.responsible).to be_truthy expect(project_settings.mentioned).to be_truthy expect(project_settings.watched).to be_truthy expect(project_settings.work_package_commented).to be_falsey diff --git a/spec/lib/api/v3/user_preferences/user_preference_representer_parsing_spec.rb b/spec/lib/api/v3/user_preferences/user_preference_representer_parsing_spec.rb index 892a954781..d6745ee8f9 100644 --- a/spec/lib/api/v3/user_preferences/user_preference_representer_parsing_spec.rb +++ b/spec/lib/api/v3/user_preferences/user_preference_representer_parsing_spec.rb @@ -43,7 +43,8 @@ describe ::API::V3::UserPreferences::UserPreferenceRepresenter, { 'notifications' => [ { - 'involved' => true, + 'assignee' => true, + 'responsible' => true, '_links' => { 'project' => { 'href' => '/api/v3/projects/1' @@ -51,7 +52,8 @@ describe ::API::V3::UserPreferences::UserPreferenceRepresenter, } }, { - 'involved' => false, + 'assignee' => false, + 'responsible' => false, 'mentioned' => true, '_links' => { 'project' => { @@ -69,11 +71,13 @@ describe ::API::V3::UserPreferences::UserPreferenceRepresenter, in_project, global = subject.notification_settings expect(in_project[:project_id]).to eq "1" - expect(in_project[:involved]).to be_truthy + expect(in_project[:assignee]).to be_truthy + expect(in_project[:responsible]).to be_truthy expect(in_project[:mentioned]).to be_nil expect(global[:project_id]).to be_nil - expect(global[:involved]).to be false + expect(global[:assignee]).to be_falsey + expect(global[:responsible]).to be_falsey expect(global[:mentioned]).to be true end end diff --git a/spec/models/mail_handler_spec.rb b/spec/models/mail_handler_spec.rb index 5ccc370811..314a02df2f 100644 --- a/spec/models/mail_handler_spec.rb +++ b/spec/models/mail_handler_spec.rb @@ -1071,7 +1071,7 @@ describe MailHandler, type: :model do assignee = create(:user, member_in_project: project, member_with_permissions: %i(view_work_packages), - notification_settings: [build(:notification_setting, involved: true)]) + notification_settings: [build(:notification_setting, assignee: true, responsible: true)]) work_package.update_column(:assigned_to_id, assignee.id) diff --git a/spec/services/notifications/create_from_model_service_comment_spec.rb b/spec/services/notifications/create_from_model_service_comment_spec.rb index a65cc25532..e651be0b59 100644 --- a/spec/services/notifications/create_from_model_service_comment_spec.rb +++ b/spec/services/notifications/create_from_model_service_comment_spec.rb @@ -73,10 +73,10 @@ describe Notifications::CreateFromModelService, 'comment', with_settings: { jour end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_message_spec.rb b/spec/services/notifications/create_from_model_service_message_spec.rb index 8be43a0c01..1ffec2fd7c 100644 --- a/spec/services/notifications/create_from_model_service_message_spec.rb +++ b/spec/services/notifications/create_from_model_service_message_spec.rb @@ -74,10 +74,10 @@ describe Notifications::CreateFromModelService, 'message', with_settings: { jour end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end @@ -206,10 +206,10 @@ describe Notifications::CreateFromModelService, 'message', with_settings: { jour end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_news_spec.rb b/spec/services/notifications/create_from_model_service_news_spec.rb index b8d3fa9c90..574632496e 100644 --- a/spec/services/notifications/create_from_model_service_news_spec.rb +++ b/spec/services/notifications/create_from_model_service_news_spec.rb @@ -66,10 +66,10 @@ describe Notifications::CreateFromModelService, 'news', with_settings: { journal end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_wiki_spec.rb b/spec/services/notifications/create_from_model_service_wiki_spec.rb index 7471a0bf2f..639425c410 100644 --- a/spec/services/notifications/create_from_model_service_wiki_spec.rb +++ b/spec/services/notifications/create_from_model_service_wiki_spec.rb @@ -72,10 +72,10 @@ describe Notifications::CreateFromModelService, 'wiki', with_settings: { journal end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end @@ -165,10 +165,10 @@ describe Notifications::CreateFromModelService, 'wiki', with_settings: { journal end end - context 'with the user having registered for involved notifications' do + context 'with the user having registered for assignee and responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_work_package_spec.rb b/spec/services/notifications/create_from_model_service_work_package_spec.rb index 57d8d81510..212ba90dd0 100644 --- a/spec/services/notifications/create_from_model_service_work_package_spec.rb +++ b/spec/services/notifications/create_from_model_service_work_package_spec.rb @@ -103,7 +103,7 @@ describe Notifications::CreateFromModelService, let(:user_property) { :assigned_to } let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end @@ -147,10 +147,10 @@ describe Notifications::CreateFromModelService, it_behaves_like 'creates no notification' end - context 'when assignee has all in app notifications enabled but only involved for mail' do + context 'when assignee has all in app notifications enabled but only assignee for mail' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end @@ -194,7 +194,7 @@ describe Notifications::CreateFromModelService, let(:user_property) { :responsible } let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(involved: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) ] end diff --git a/spec/services/notifications/mail_service_mentioned_integration_spec.rb b/spec/services/notifications/mail_service_mentioned_integration_spec.rb index 0cba2953ca..cbb9b1be65 100644 --- a/spec/services/notifications/mail_service_mentioned_integration_spec.rb +++ b/spec/services/notifications/mail_service_mentioned_integration_spec.rb @@ -42,7 +42,8 @@ describe Notifications::MailService, 'Mentioned integration', type: :model do notification_settings: [ build(:notification_setting, mentioned: true, - involved: true) + assignee: true, + responsible: true) ], member_in_project: project, member_through_role: role @@ -62,7 +63,12 @@ describe Notifications::MailService, 'Mentioned integration', type: :model do end def expect_no_assigned_notification - expect(Notification.where(recipient:, resource: work_package, reason: :involved)) + expect(Notification.where(recipient:, resource: work_package, reason: :assignee)) + .to be_empty + end + + def expect_no_responsible_notification + expect(Notification.where(recipient:, resource: work_package, reason: :responsible)) .to be_empty end @@ -94,9 +100,10 @@ describe Notifications::MailService, 'Mentioned integration', type: :model do .to have_received(:mentioned) .once - # No involved notification since the assignee is also mentioned which trumps + # No assignee and responsible notification since the assignee is also mentioned which trumps # being assignee and a user will only get one notification for a journal. expect_no_assigned_notification + expect_no_responsible_notification expect_mentioned_notification update_assignee!(assignee) diff --git a/spec/services/notifications/mentioned_journals_shared.rb b/spec/services/notifications/mentioned_journals_shared.rb index 86f19c18a7..9d83de4cfe 100644 --- a/spec/services/notifications/mentioned_journals_shared.rb +++ b/spec/services/notifications/mentioned_journals_shared.rb @@ -52,7 +52,8 @@ shared_context 'with a mentioned work package being updated again' do notification_settings: [ build(:notification_setting, mentioned: true, - involved: true) + assignee: true, + responsible: true) ], member_in_project: project, member_through_role: role diff --git a/spec/services/user_preferences/update_service_integration_spec.rb b/spec/services/user_preferences/update_service_integration_spec.rb index de5c56847e..4519acbd4f 100644 --- a/spec/services/user_preferences/update_service_integration_spec.rb +++ b/spec/services/user_preferences/update_service_integration_spec.rb @@ -60,7 +60,8 @@ describe UserPreferences::UpdateService, 'integration', type: :model do { project_id: nil, watched: false, - involved: true, + assignee: true, + responsible: true, work_package_commented: false, work_package_created: true, work_package_processed: true, @@ -76,7 +77,8 @@ describe UserPreferences::UpdateService, 'integration', type: :model do expect(default_ian.watched).to be true expect(default_ian.mentioned).to be true - expect(default_ian.involved).to be true + expect(default_ian.assignee).to be true + expect(default_ian.responsible).to be true expect(default_ian.work_package_commented).to be true expect(default_ian.work_package_created).to be true expect(default_ian.work_package_processed).to be true @@ -87,7 +89,8 @@ describe UserPreferences::UpdateService, 'integration', type: :model do expect(subject.first.project_id).to be_nil expect(subject.first.mentioned).to be false expect(subject.first.watched).to be false - expect(subject.first.involved).to be true + expect(default_ian.assignee).to be true + expect(default_ian.responsible).to be true expect(subject.first.work_package_commented).to be false expect(subject.first.work_package_created).to be true expect(subject.first.work_package_processed).to be true diff --git a/spec/support/pages/notifications/settings.rb b/spec/support/pages/notifications/settings.rb index cb2d988e2d..42ed49164d 100644 --- a/spec/support/pages/notifications/settings.rb +++ b/spec/support/pages/notifications/settings.rb @@ -53,7 +53,8 @@ module Pages def expect_global_represented(setting) %i[ - involved + assignee + responsible work_package_commented work_package_created work_package_processed diff --git a/spec/workers/mails/shared/watcher_job.rb b/spec/workers/mails/shared/watcher_job.rb index 3e025cdcd8..d75809fa5c 100644 --- a/spec/workers/mails/shared/watcher_job.rb +++ b/spec/workers/mails/shared/watcher_job.rb @@ -126,25 +126,25 @@ shared_examples "watcher job" do |action| it_behaves_like 'notifies the watcher' do let(:notification_settings) do - [build_stubbed(:notification_setting, mentioned: false, involved: false, watched: true)] + [build_stubbed(:notification_setting, mentioned: false, assignee: false, responsible: false, watched: true)] end end it_behaves_like 'notifies the watcher' do let(:notification_settings) do - [build_stubbed(:notification_setting, mentioned: false, involved: false, watched: true)] + [build_stubbed(:notification_setting, mentioned: false, assignee: false, responsible: false, watched: true)] end end it_behaves_like 'does not notify the watcher' do let(:notification_settings) do - [build_stubbed(:notification_setting, mentioned: false, involved: true, watched: false)] + [build_stubbed(:notification_setting, mentioned: false, assignee: true, responsible: true, watched: false)] end end it_behaves_like 'does not notify the watcher' do let(:notification_settings) do - [build_stubbed(:notification_setting, mentioned: true, involved: false, watched: false)] + [build_stubbed(:notification_setting, mentioned: true, assignee: false, responsible: false, watched: false)] end end From 4534007a3be4b7998721fc6c1948b41553c19c79 Mon Sep 17 00:00:00 2001 From: Dmitrii Date: Tue, 27 Sep 2022 22:20:24 +0200 Subject: [PATCH 006/148] [#43675] fig regarding comments --- config/locales/js-en.yml | 3 -- ...08_split_involved_notification_setting.rb} | 6 ++-- ...notifications-settings-page.component.html | 10 +++---- ...create_from_model_service_document_spec.rb | 28 ++++++++++++++++--- .../create_from_model_service_comment_spec.rb | 14 ++++++++-- .../create_from_model_service_message_spec.rb | 28 ++++++++++++++++--- .../create_from_model_service_news_spec.rb | 14 ++++++++-- .../create_from_model_service_wiki_spec.rb | 28 ++++++++++++++++--- ...te_from_model_service_work_package_spec.rb | 6 ++-- 9 files changed, 107 insertions(+), 30 deletions(-) rename db/migrate/{20220922200908_add_assignee.rb => 20220922200908_split_involved_notification_setting.rb} (75%) diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index 024912adc4..19b8b9333e 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -629,9 +629,6 @@ en: mentioned: title: 'I am @mentioned' description: 'Receive a notification every time someone mentions me anywhere' - involved: - title: 'Assigned to me or accountable' - description: 'Receive notifications for all activities on work packages for which I am assignee or accountable' assignee: 'Assignee' responsible: 'Accountable' watched: 'Updates on watched items' diff --git a/db/migrate/20220922200908_add_assignee.rb b/db/migrate/20220922200908_split_involved_notification_setting.rb similarity index 75% rename from db/migrate/20220922200908_add_assignee.rb rename to db/migrate/20220922200908_split_involved_notification_setting.rb index 8e15229d08..dc4dce2953 100644 --- a/db/migrate/20220922200908_add_assignee.rb +++ b/db/migrate/20220922200908_split_involved_notification_setting.rb @@ -1,4 +1,4 @@ -class AddAssignee < ActiveRecord::Migration[7.0] +class SplitInvolvedNotificationSetting < ActiveRecord::Migration[7.0] def change change_table :notification_settings, bulk: true do |t| t.column :assignee, :boolean, default: false, null: false @@ -8,13 +8,13 @@ class AddAssignee < ActiveRecord::Migration[7.0] reversible do |change| change.up do NotificationSetting.where(involved: true).update_all(assignee: true, responsible: true) - remove_column :notification_settings, :involved, :boolean end change.down do - add_column :notification_settings, :involved, :boolean NotificationSetting.where(assignee: true).or(NotificationSetting.where(responsible: true)).update_all(involved: true) end end + + remove_column :notification_settings, :involved, :boolean end end diff --git a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html index e35be13487..fb9b04cde8 100644 --- a/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html +++ b/frontend/src/app/features/user-preferences/notifications-settings/page/notifications-settings-page.component.html @@ -17,9 +17,9 @@ slot="input" />

{{ text.mentioned.description }}

- + - @@ -29,9 +29,9 @@ formControlName="assignee" data-qa-global-notification-type="assignee" /> - + - @@ -41,7 +41,7 @@ formControlName="responsible" data-qa-global-notification-type="responsible" /> - +
{{ text.alsoNotifyFor.title }}

{{ text.alsoNotifyFor.description }}

diff --git a/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb b/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb index e5829200fa..898cc64bc4 100644 --- a/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb +++ b/modules/documents/spec/services/notifications/create_from_model_service_document_spec.rb @@ -68,10 +68,20 @@ describe Notifications::CreateFromModelService, 'document', with_settings: { jou end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end @@ -116,10 +126,20 @@ describe Notifications::CreateFromModelService, 'document', with_settings: { jou end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_comment_spec.rb b/spec/services/notifications/create_from_model_service_comment_spec.rb index e651be0b59..2cc0263053 100644 --- a/spec/services/notifications/create_from_model_service_comment_spec.rb +++ b/spec/services/notifications/create_from_model_service_comment_spec.rb @@ -73,10 +73,20 @@ describe Notifications::CreateFromModelService, 'comment', with_settings: { jour end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_message_spec.rb b/spec/services/notifications/create_from_model_service_message_spec.rb index 1ffec2fd7c..576509d0b7 100644 --- a/spec/services/notifications/create_from_model_service_message_spec.rb +++ b/spec/services/notifications/create_from_model_service_message_spec.rb @@ -74,10 +74,20 @@ describe Notifications::CreateFromModelService, 'message', with_settings: { jour end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end @@ -206,10 +216,20 @@ describe Notifications::CreateFromModelService, 'message', with_settings: { jour end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_news_spec.rb b/spec/services/notifications/create_from_model_service_news_spec.rb index 574632496e..20a6e735a3 100644 --- a/spec/services/notifications/create_from_model_service_news_spec.rb +++ b/spec/services/notifications/create_from_model_service_news_spec.rb @@ -66,10 +66,20 @@ describe Notifications::CreateFromModelService, 'news', with_settings: { journal end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_wiki_spec.rb b/spec/services/notifications/create_from_model_service_wiki_spec.rb index 639425c410..49be368284 100644 --- a/spec/services/notifications/create_from_model_service_wiki_spec.rb +++ b/spec/services/notifications/create_from_model_service_wiki_spec.rb @@ -72,10 +72,20 @@ describe Notifications::CreateFromModelService, 'wiki', with_settings: { journal end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end @@ -165,10 +175,20 @@ describe Notifications::CreateFromModelService, 'wiki', with_settings: { journal end end - context 'with the user having registered for assignee and responsible notifications' do + context 'with the user having registered for assignee notifications' do + let(:recipient_notification_settings) do + [ + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) + ] + end + + it_behaves_like 'creates no notification' + end + + context 'with the user having registered for responsible notifications' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end diff --git a/spec/services/notifications/create_from_model_service_work_package_spec.rb b/spec/services/notifications/create_from_model_service_work_package_spec.rb index 212ba90dd0..7c35fb6697 100644 --- a/spec/services/notifications/create_from_model_service_work_package_spec.rb +++ b/spec/services/notifications/create_from_model_service_work_package_spec.rb @@ -103,7 +103,7 @@ describe Notifications::CreateFromModelService, let(:user_property) { :assigned_to } let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) ] end @@ -150,7 +150,7 @@ describe Notifications::CreateFromModelService, context 'when assignee has all in app notifications enabled but only assignee for mail' do let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(assignee: true)) ] end @@ -194,7 +194,7 @@ describe Notifications::CreateFromModelService, let(:user_property) { :responsible } let(:recipient_notification_settings) do [ - build(:notification_setting, **notification_settings_all_false.merge(assignee: true, responsible: true)) + build(:notification_setting, **notification_settings_all_false.merge(responsible: true)) ] end From 67f38a59fbd495e3d7ae7bb499a200ac5d054b1b Mon Sep 17 00:00:00 2001 From: JanKeppler Date: Wed, 28 Sep 2022 14:53:23 +0200 Subject: [PATCH 007/148] [#44319] User guide: Edit time tracking (typo) https://community.openproject.org/work_packages/44319 [ci skip] --- .../time-and-costs/time-tracking/README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/user-guide/time-and-costs/time-tracking/README.md b/docs/user-guide/time-and-costs/time-tracking/README.md index ca48e5fe9e..a4adbf9e3a 100644 --- a/docs/user-guide/time-and-costs/time-tracking/README.md +++ b/docs/user-guide/time-and-costs/time-tracking/README.md @@ -13,15 +13,15 @@ Users can book their time or units spent on an activity within a project directl > **Note**: To use the time tracking functionality, the **Time and costs module** needs to be activated in the [project settings](../../projects/project-settings/modules/). -| Topic | Content | -|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------------| -| [Logging time](#logging-time-in-the-work-package-view) | How to log time to work packages. | -| [Logging time via commit message](#logging-time-via-commit-message) | How to log time via a commit message to a work package. | -| [Edit logged time](#edit-logged-time) | How to edit logged time on a work package. | -| [Delete time entries](#delete-time-entries) | How to delete time entries logged to a work package. | -| [Logging and editing time for other users](#logging-and-editing-time-for-other-users) | How to log time to work packages. | -| [Spent time widget on the My Page](#spent-time-widget-on-the-my-page) | How to easily track and display spent time in the spent time widget on the MyPage. | -| [Track time with Toggl](./toggl-integration) | How to track spent time with Toggl integration. | +| Topic | Content | +| ------------------------------------------------------------ | ------------------------------------------------------------ | +| [Logging time](#logging-time-in-the-work-package-view) | How to log time to work package. | +| [Logging time via commit message](#logging-time-via-commit-message) | How to log time via a commit message to a work package. | +| [Edit logged time](#edit-logged-time) | How to edit logged time on a work package. | +| [Delete time entries](#delete-time-entries) | How to delete time entries logged to a work package. | +| [Logging and editing time for other users](#logging-and-editing-time-for-other-users) | How to log time to work packages. | +| [Spent time widget on the My Page](#spent-time-widget-on-the-my-page) | How to easily track and display spent time in the spent time widget on the MyPage. | +| [Track time with Toggl](./toggl-integration) | How to track spent time with Toggl integration. | ## Logging time in the work package view From 328b84864bbf4acaafc5a9d207ec69fc755a45bf Mon Sep 17 00:00:00 2001 From: JanKeppler Date: Wed, 28 Sep 2022 14:56:19 +0200 Subject: [PATCH 008/148] [#44319] User guide: Edit time tracking (typo) https://community.openproject.org/work_packages/44319 [ci skip] OP#44319 --- docs/user-guide/time-and-costs/time-tracking/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user-guide/time-and-costs/time-tracking/README.md b/docs/user-guide/time-and-costs/time-tracking/README.md index a4adbf9e3a..9080ef9f24 100644 --- a/docs/user-guide/time-and-costs/time-tracking/README.md +++ b/docs/user-guide/time-and-costs/time-tracking/README.md @@ -15,7 +15,7 @@ Users can book their time or units spent on an activity within a project directl | Topic | Content | | ------------------------------------------------------------ | ------------------------------------------------------------ | -| [Logging time](#logging-time-in-the-work-package-view) | How to log time to work package. | +| [Logging time](#logging-time-in-the-work-package-view) | How to log time to a work package. | | [Logging time via commit message](#logging-time-via-commit-message) | How to log time via a commit message to a work package. | | [Edit logged time](#edit-logged-time) | How to edit logged time on a work package. | | [Delete time entries](#delete-time-entries) | How to delete time entries logged to a work package. | From 4ea3765168bcf1a4e3567fd328cf889c60f438db Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Thu, 29 Sep 2022 10:48:47 +0200 Subject: [PATCH 009/148] end date is one day after the selected end date so we should reduce one day --- .../features/calendar/wp-calendar/wp-calendar.component.ts | 6 ++---- .../team-planner/planner/team-planner.component.ts | 3 ++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/features/calendar/wp-calendar/wp-calendar.component.ts b/frontend/src/app/features/calendar/wp-calendar/wp-calendar.component.ts index 89338dca44..0d8089359f 100644 --- a/frontend/src/app/features/calendar/wp-calendar/wp-calendar.component.ts +++ b/frontend/src/app/features/calendar/wp-calendar/wp-calendar.component.ts @@ -314,10 +314,8 @@ export class WorkPackagesCalendarComponent extends UntilDestroyedMixin implement } private handleDateClicked(info:DateSelectArg) { - const startDay = new Date(info.start).getDate(); - const endDay = new Date(info.end).getDate(); - const duration = endDay - startDay; - const nonWorkingDays = duration !== 1 ? false : this.weekdayService.isNonWorkingDay(info.start); + const due = moment(info.endStr).subtract(1, 'day').toDate(); + const nonWorkingDays = this.weekdayService.isNonWorkingDay(info.start) || this.weekdayService.isNonWorkingDay(due); const defaults = { startDate: info.startStr, diff --git a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts index 59dbf63aa4..3206cfed41 100644 --- a/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts +++ b/frontend/src/app/features/team-planner/team-planner/planner/team-planner.component.ts @@ -752,7 +752,8 @@ export class TeamPlannerComponent extends UntilDestroyedMixin implements OnInit, } private handleDateClicked(info:DateSelectArg) { - const nonWorkingDays = this.weekdayService.isNonWorkingDay(info.start) || this.weekdayService.isNonWorkingDay(info.end); + const due = moment(info.endStr).subtract(1, 'day').toDate(); + const nonWorkingDays = this.weekdayService.isNonWorkingDay(info.start) || this.weekdayService.isNonWorkingDay(due); this.openNewSplitCreate( info.startStr, From 0f933b8f08d2618d329dad95da68bbab6f445ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Thu, 29 Sep 2022 09:48:47 +0200 Subject: [PATCH 010/148] Fix only work package custom_options being avaialable in API https://community.openproject.org/wp/44281 --- .../v3/custom_options/custom_options_api.rb | 26 ++- .../time_entry_schema_representer_spec.rb | 2 +- .../time_entry_representer_rendering_spec.rb | 2 +- .../time_entries/create_form_resource_spec.rb | 2 +- .../time_entries/update_form_resource_spec.rb | 2 +- .../requests/api/time_entry_resource_spec.rb | 2 +- spec/factories/custom_field_factory.rb | 81 +++++++- .../custom_options_resource_spec.rb | 188 ++++++++++++++---- 8 files changed, 254 insertions(+), 51 deletions(-) diff --git a/lib/api/v3/custom_options/custom_options_api.rb b/lib/api/v3/custom_options/custom_options_api.rb index c95395f738..43540d0ae5 100644 --- a/lib/api/v3/custom_options/custom_options_api.rb +++ b/lib/api/v3/custom_options/custom_options_api.rb @@ -37,12 +37,26 @@ module API end helpers do - def authorize_view_in_activated_project(custom_option) + def authorize_custom_option_visibility(custom_option) + case custom_option.custom_field + when WorkPackageCustomField + authorized_work_package_option(custom_option) + when ProjectCustomField + authorize_any(%i[view_project], global: true) { raise API::Errors::NotFound } + when TimeEntryCustomField + authorize_any(%i[log_time log_own_time], global: true) { raise API::Errors::NotFound } + when UserCustomField, GroupCustomField + true + else + raise API::Errors::NotFound + end + end + + def authorized_work_package_option(custom_option) allowed = Project - .allowed_to(current_user, :view_work_packages) - .joins(:work_package_custom_fields) - .where(custom_fields: { id: custom_option.custom_field_id }) - .exists? + .allowed_to(current_user, :view_work_packages) + .joins(:work_package_custom_fields) + .exists?(custom_fields: { id: custom_option.custom_field_id }) unless allowed raise API::Errors::NotFound @@ -53,7 +67,7 @@ module API get do co = CustomOption.find(params[:id]) - authorize_view_in_activated_project(co) + authorize_custom_option_visibility(co) CustomOptionRepresenter.new(co, current_user:) end diff --git a/modules/costs/spec/lib/api/v3/time_entries/schemas/time_entry_schema_representer_spec.rb b/modules/costs/spec/lib/api/v3/time_entries/schemas/time_entry_schema_representer_spec.rb index 3b7b5287a3..2a25aa797f 100644 --- a/modules/costs/spec/lib/api/v3/time_entries/schemas/time_entry_schema_representer_spec.rb +++ b/modules/costs/spec/lib/api/v3/time_entries/schemas/time_entry_schema_representer_spec.rb @@ -268,7 +268,7 @@ describe ::API::V3::TimeEntries::Schemas::TimeEntrySchemaRepresenter do end context 'custom value' do - let(:custom_field) { build_stubbed(:time_entry_custom_field) } + let(:custom_field) { build_stubbed(:text_time_entry_custom_field) } let(:path) { "customField#{custom_field.id}" } before do diff --git a/modules/costs/spec/lib/api/v3/time_entries/time_entry_representer_rendering_spec.rb b/modules/costs/spec/lib/api/v3/time_entries/time_entry_representer_rendering_spec.rb index 6fb622f93b..83a1a304be 100644 --- a/modules/costs/spec/lib/api/v3/time_entries/time_entry_representer_rendering_spec.rb +++ b/modules/costs/spec/lib/api/v3/time_entries/time_entry_representer_rendering_spec.rb @@ -255,7 +255,7 @@ describe ::API::V3::TimeEntries::TimeEntryRepresenter, 'rendering' do end context 'custom value' do - let(:custom_field) { build_stubbed(:time_entry_custom_field) } + let(:custom_field) { build_stubbed(:text_time_entry_custom_field) } let(:custom_value) do CustomValue.new(custom_field:, value: '1234', diff --git a/modules/costs/spec/requests/api/time_entries/create_form_resource_spec.rb b/modules/costs/spec/requests/api/time_entries/create_form_resource_spec.rb index f89e383ec9..de73bc8530 100644 --- a/modules/costs/spec/requests/api/time_entries/create_form_resource_spec.rb +++ b/modules/costs/spec/requests/api/time_entries/create_form_resource_spec.rb @@ -39,7 +39,7 @@ describe ::API::V3::TimeEntries::CreateFormAPI, content_type: :json do TimeEntryActivitiesProject.insert(project_id: project.id, activity_id: tea.id, active: false) end end - let(:custom_field) { create(:time_entry_custom_field) } + let(:custom_field) { create(:text_time_entry_custom_field) } let(:user) do create(:user, member_in_project: project, diff --git a/modules/costs/spec/requests/api/time_entries/update_form_resource_spec.rb b/modules/costs/spec/requests/api/time_entries/update_form_resource_spec.rb index 403eccd67a..eaddbe7dba 100644 --- a/modules/costs/spec/requests/api/time_entries/update_form_resource_spec.rb +++ b/modules/costs/spec/requests/api/time_entries/update_form_resource_spec.rb @@ -40,7 +40,7 @@ describe ::API::V3::TimeEntries::UpdateFormAPI, content_type: :json do TimeEntryActivitiesProject.insert(project_id: project.id, activity_id: tea.id, active: false) end end - let(:custom_field) { create(:time_entry_custom_field) } + let(:custom_field) { create(:text_time_entry_custom_field) } let(:user) do create(:user, member_in_project: project, diff --git a/modules/costs/spec/requests/api/time_entry_resource_spec.rb b/modules/costs/spec/requests/api/time_entry_resource_spec.rb index b47a7f2431..f284c79314 100644 --- a/modules/costs/spec/requests/api/time_entry_resource_spec.rb +++ b/modules/costs/spec/requests/api/time_entry_resource_spec.rb @@ -54,7 +54,7 @@ describe 'API v3 time_entry resource', type: :request do let(:other_project) { other_work_package.project } let(:role) { create(:role, permissions:) } let(:permissions) { %i(view_time_entries view_work_packages) } - let(:custom_field) { create(:time_entry_custom_field) } + let(:custom_field) { create(:text_time_entry_custom_field) } let(:custom_value) do CustomValue.create(custom_field:, value: '1234', diff --git a/spec/factories/custom_field_factory.rb b/spec/factories/custom_field_factory.rb index e9c004cac1..366633704d 100644 --- a/spec/factories/custom_field_factory.rb +++ b/spec/factories/custom_field_factory.rb @@ -136,6 +136,47 @@ FactoryBot.define do end end + factory :group_custom_field, class: 'GroupCustomField' do + sequence(:name) { |n| "User Custom Field #{n}" } + type { 'GroupCustomField' } + + factory :boolean_group_custom_field do + name { 'BooleanGroupCustomField' } + field_format { 'bool' } + end + + factory :integer_group_custom_field do + name { 'IntegerGroupCustomField' } + field_format { 'int' } + end + + factory :text_group_custom_field do + name { 'TextGroupCustomField' } + field_format { 'text' } + end + + factory :string_group_custom_field do + name { 'StringGroupCustomField' } + field_format { 'string' } + end + + factory :float_group_custom_field do + name { 'FloatGroupCustomField' } + field_format { 'float' } + end + + factory :list_group_custom_field do + name { 'ListGroupCustomField' } + field_format { 'list' } + possible_values { ['1', '2', '3', '4', '5', '6', '7'] } + end + + factory :date_group_custom_field do + name { 'DateGroupCustomField' } + field_format { 'date' } + end + end + factory :wp_custom_field, class: 'WorkPackageCustomField' do sequence(:name) { |n| "Work package custom field #{n}" } type { 'WorkPackageCustomField' } @@ -208,8 +249,44 @@ FactoryBot.define do end factory :time_entry_custom_field, class: 'TimeEntryCustomField' do - field_format { 'text' } - sequence(:name) { |n| "TimeEntryCustomField #{n}" } + sequence(:name) { |n| "User Custom Field #{n}" } + type { 'TimeEntryCustomField' } + + factory :boolean_time_entry_custom_field do + name { 'BooleanTimeEntryCustomField' } + field_format { 'bool' } + end + + factory :integer_time_entry_custom_field do + name { 'IntegerTimeEntryCustomField' } + field_format { 'int' } + end + + factory :text_time_entry_custom_field do + name { 'TextTimeEntryCustomField' } + field_format { 'text' } + end + + factory :string_time_entry_custom_field do + name { 'StringTimeEntryCustomField' } + field_format { 'string' } + end + + factory :float_time_entry_custom_field do + name { 'FloatTimeEntryCustomField' } + field_format { 'float' } + end + + factory :list_time_entry_custom_field do + name { 'ListTimeEntryCustomField' } + field_format { 'list' } + possible_values { ['A', 'B'] } + end + + factory :date_time_entry_custom_field do + name { 'DateTimeEntryCustomField' } + field_format { 'date' } + end end factory :version_custom_field, class: 'VersionCustomField' do diff --git a/spec/requests/api/v3/custom_options/custom_options_resource_spec.rb b/spec/requests/api/v3/custom_options/custom_options_resource_spec.rb index 84fb8ba18b..501a8e50f5 100644 --- a/spec/requests/api/v3/custom_options/custom_options_resource_spec.rb +++ b/spec/requests/api/v3/custom_options/custom_options_resource_spec.rb @@ -29,29 +29,19 @@ require 'spec_helper' require 'rack/test' -describe 'API v3 Custom Options resource' do +describe 'API v3 Custom Options resource', :aggregate_failures do include Rack::Test::Methods include API::V3::Utilities::PathHelper + shared_let(:project) { create(:project) } let(:user) do create(:user, member_in_project: project, member_through_role: role) end - let(:project) { create(:project) } let(:role) { create(:role, permissions:) } - let(:permissions) { [:view_work_packages] } - let(:custom_field) do - cf = create(:list_wp_custom_field) - project.work_package_custom_fields << cf - - cf - end - let(:custom_option) do - create(:custom_option, - custom_field:) - end + let(:modification) { nil } subject(:response) { last_response } @@ -59,56 +49,178 @@ describe 'API v3 Custom Options resource' do let(:path) { api_v3_paths.custom_option custom_option.id } before do + modification&.call allow(User) .to receive(:current) - .and_return(user) + .and_return(user) get path end - context 'when being allowed' do - it 'is successful' do - expect(subject.status) - .to be(200) + describe 'WorkPackageCustomField' do + shared_let(:custom_field) do + cf = create(:list_wp_custom_field) + + project.work_package_custom_fields << cf + + cf + end + shared_let(:custom_option) do + create(:custom_option, + custom_field:) + end + + context 'when being allowed' do + let(:permissions) { [:view_work_packages] } + + it 'is successful' do + expect(subject.status) + .to be(200) + + expect(response.body) + .to be_json_eql('CustomOption'.to_json) + .at_path('_type') + + expect(response.body) + .to be_json_eql(custom_option.id.to_json) + .at_path('id') + + expect(response.body) + .to be_json_eql(custom_option.value.to_json) + .at_path('value') + end end - it 'returns the custom option' do - expect(response.body) - .to be_json_eql('CustomOption'.to_json) - .at_path('_type') + context 'when lacking permission' do + let(:permissions) { [] } - expect(response.body) - .to be_json_eql(custom_option.id.to_json) - .at_path('id') + it 'is 404' do + expect(subject.status) + .to be(404) + end + end - expect(response.body) - .to be_json_eql(custom_option.value.to_json) - .at_path('value') + context 'when custom option not in project' do + let(:permissions) { [:view_work_packages] } + let(:modification) do + -> do + project.work_package_custom_fields = [] + project.save! + end + end + + it 'is 404' do + expect(subject.status) + .to be(404) + end end end - context 'when lacking permission' do + describe 'ProjectCustomField' do + shared_let(:custom_field) { create(:list_project_custom_field) } + shared_let(:custom_option) { create(:custom_option, custom_field:) } + + context 'when being allowed' do + let(:permissions) { [:view_project] } + + it 'is successful' do + expect(subject.status) + .to be(200) + + expect(response.body) + .to be_json_eql('CustomOption'.to_json) + .at_path('_type') + + expect(response.body) + .to be_json_eql(custom_option.id.to_json) + .at_path('id') + + expect(response.body) + .to be_json_eql(custom_option.value.to_json) + .at_path('value') + end + end + + context 'when lacking permission' do + let(:user) { User.anonymous } + let(:permissions) { [] } + + it 'is 404' do + expect(subject.status) + .to be(404) + end + end + end + + describe 'TimeEntryCustomField' do + shared_let(:custom_field) { create(:list_time_entry_custom_field) } + shared_let(:custom_option) { create(:custom_option, custom_field:) } + + context 'when being allowed with log_time' do + let(:permissions) { [:log_time] } + + it 'is successful' do + expect(subject.status) + .to be(200) + + expect(response.body) + .to be_json_eql('CustomOption'.to_json) + .at_path('_type') + + expect(response.body) + .to be_json_eql(custom_option.id.to_json) + .at_path('id') + + expect(response.body) + .to be_json_eql(custom_option.value.to_json) + .at_path('value') + end + end + + context 'when being allowed with log_own_time' do + let(:permissions) { [:log_own_time] } + + it 'is successful' do + expect(subject.status) + .to be(200) + end + end + + context 'when lacking permission' do + let(:user) { User.anonymous } + let(:permissions) { [] } + + it 'is 404' do + expect(subject.status) + .to be(404) + end + end + end + + describe 'UserCustomField' do + shared_let(:custom_field) { create(:list_user_custom_field) } + shared_let(:custom_option) { create(:custom_option, custom_field:) } let(:permissions) { [] } - it 'is 404' do + it 'is successful' do expect(subject.status) - .to be(404) + .to be(200) end end - context 'when custom option not in project' do - let(:custom_field) do - # not added to project - create(:list_wp_custom_field) - end + describe 'GroupCustomField' do + shared_let(:custom_field) { create(:list_group_custom_field) } + shared_let(:custom_option) { create(:custom_option, custom_field:) } + let(:permissions) { [] } - it 'is 404' do + it 'is successful' do expect(subject.status) - .to be(404) + .to be(200) end end context 'when not existing' do let(:path) { api_v3_paths.custom_option 0 } + let(:permissions) { [:view_work_packages] } it 'is 404' do expect(subject.status) From b6a94cf325b9aa600b18fdbecf4ef73cc120bae5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 4 Oct 2022 09:23:49 +0200 Subject: [PATCH 011/148] Add rake task to find unsynced ldap group members --- .../ldap_groups/lib/tasks/ldap_groups.rake | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/ldap_groups/lib/tasks/ldap_groups.rake b/modules/ldap_groups/lib/tasks/ldap_groups.rake index cbcd107216..7dc5d14d6c 100644 --- a/modules/ldap_groups/lib/tasks/ldap_groups.rake +++ b/modules/ldap_groups/lib/tasks/ldap_groups.rake @@ -33,6 +33,25 @@ namespace :ldap_groups do ::LdapGroups::SynchronizationService.synchronize! end + desc 'Print all members of groups tied to a synchronized group that are not derived from LDAP' + task print_unsynced_members: :environment do + ::LdapGroups::SynchronizedGroup + .includes(:group) + .find_each do |sync| + + group = sync.group + unsynced_logins = User + .where(id: group.user_ids) + .where.not(id: sync.users.select(:user_id)) + .pluck(:login) + + if unsynced_logins.any? + puts "In group #{group}, #{unsynced_logins.count} user(s) exist that are not synced from LDAP:" + puts unsynced_logins.join(", ") + end + end + end + namespace :development do desc 'Create a development LDAP server from the fixtures LDIF' task :ldap_server do From f77410cba8c9ce5fda61ccac65fb2aadd248a9cf Mon Sep 17 00:00:00 2001 From: Dombi Attila <83396+dombesz@users.noreply.github.com> Date: Fri, 30 Sep 2022 16:34:43 +0200 Subject: [PATCH 012/148] [#44347] Milestones existing before 12.3 will have nil for duration https://community.openproject.org/work_packages/44347 --- ...et_duration_for_milestone_work_packages.rb | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 db/migrate/20220930133418_set_duration_for_milestone_work_packages.rb diff --git a/db/migrate/20220930133418_set_duration_for_milestone_work_packages.rb b/db/migrate/20220930133418_set_duration_for_milestone_work_packages.rb new file mode 100644 index 0000000000..261fc144ad --- /dev/null +++ b/db/migrate/20220930133418_set_duration_for_milestone_work_packages.rb @@ -0,0 +1,24 @@ +class SetDurationForMilestoneWorkPackages < ActiveRecord::Migration[7.0] + def up + set_duration(:work_packages) + set_duration(:work_package_journals) + end + + private + + def set_duration(table) + execute <<~SQL.squish + UPDATE + #{table} + SET + duration = 1 + WHERE + EXISTS ( + SELECT * FROM types type + WHERE + type.is_milestone = TRUE AND + type.id = #{table}.type_id + ) + SQL + end +end From 6af5d022a6b80d0ef17a3569fee02a15f34d2b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 4 Oct 2022 11:31:53 +0200 Subject: [PATCH 013/148] Remove dev teams from automatic reviews --- .github/CODEOWNERS | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a6a9847264..64a87d0f36 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,14 +1,3 @@ -# Frontend rules -*.js @opf/frontend -*.ts @opf/frontend - -# Backend rules -/app/ @opf/backend -/config/ @opf/backend -/lib/ @opf/backend -/lib_static/ @opf/backend -/modules/ @opf/backend - # docs rules /docs/ @opf/doc-writers @@ -16,4 +5,4 @@ /docs/development @opf/tech-writers /docs/installation-and-operations @opf/tech-writers /docs/system-admin-guide @opf/tech-writers -/docs/api @opf/tech-writers @opf/backend +/docs/api @opf/tech-writers From 57bd59de96e4f14eb76bb7a6249acf864e6a9979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 4 Oct 2022 11:37:29 +0200 Subject: [PATCH 014/148] Add release-notes file --- docs/release-notes/12-2-5/README.md | 27 +++++++++++++++++++++++++++ docs/release-notes/README.md | 7 +++++++ 2 files changed, 34 insertions(+) create mode 100644 docs/release-notes/12-2-5/README.md diff --git a/docs/release-notes/12-2-5/README.md b/docs/release-notes/12-2-5/README.md new file mode 100644 index 0000000000..5f0f012af8 --- /dev/null +++ b/docs/release-notes/12-2-5/README.md @@ -0,0 +1,27 @@ +--- +title: OpenProject 12.2.5 +sidebar_navigation: + title: 12.2.5 +release_version: 12.2.5 +release_date: 2022-10-04 +--- + +# OpenProject 12.2.5 + +Release date: 2022-10-04 + +We released [OpenProject 12.2.5](https://community.openproject.com/versions/1602). +The release contains several bug fixes and we recommend updating to the newest version. + + +#### Bug fixes and changes + +- Fixed: User from synchronized group not removed in OpenProject group after removed in LDAP \[[#41256](https://community.openproject.com/wp/41256)\] +- Fixed: When adding users to a group, existing users are shown in the autocompleter \[[#43892](https://community.openproject.com/wp/43892)\] + +#### Contributions +A big thanks to community members for reporting bugs and helping us identifying and providing fixes. + +Special thanks for reporting and finding bugs go to + +Daniel Narberhaus diff --git a/docs/release-notes/README.md b/docs/release-notes/README.md index 33360d4b73..7efc41197b 100644 --- a/docs/release-notes/README.md +++ b/docs/release-notes/README.md @@ -14,6 +14,13 @@ Stay up to date and get an overview of the new features included in the releases +## 12.2.5 + +Release date: 2022-10-04 + +[Release Notes](12-2-5/) + + ## 12.2.4 Release date: 2022-09-15 From b02499c544acbb91f46276c99222398b472d19fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 4 Oct 2022 11:37:31 +0200 Subject: [PATCH 015/148] Bumped version to 12.2.6 [ci skip] --- lib/open_project/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/open_project/version.rb b/lib/open_project/version.rb index a596154619..cda5d50e7f 100644 --- a/lib/open_project/version.rb +++ b/lib/open_project/version.rb @@ -33,7 +33,7 @@ module OpenProject module VERSION # :nodoc: MAJOR = 12 MINOR = 2 - PATCH = 5 + PATCH = 6 class << self # Used by semver to define the special version (if any). From 47f657135b7544b08fe11fd535c5e9e8dfe57c81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 4 Oct 2022 11:41:43 +0200 Subject: [PATCH 016/148] Add notice to LDAP group sync bug --- docs/release-notes/12-2-5/README.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/release-notes/12-2-5/README.md b/docs/release-notes/12-2-5/README.md index 5f0f012af8..120d0e85b0 100644 --- a/docs/release-notes/12-2-5/README.md +++ b/docs/release-notes/12-2-5/README.md @@ -16,12 +16,17 @@ The release contains several bug fixes and we recommend updating to the newest v #### Bug fixes and changes -- Fixed: User from synchronized group not removed in OpenProject group after removed in LDAP \[[#41256](https://community.openproject.com/wp/41256)\] -- Fixed: When adding users to a group, existing users are shown in the autocompleter \[[#43892](https://community.openproject.com/wp/43892)\] +## LDAP group synchronization bug + +Users synchronized from LDAP into OpenProject groups were incorrectly removed when, in the same group, a new user was added in the same synchronization step. +This results in users still being present in the group despite being removed in LDAP. -#### Contributions -A big thanks to community members for reporting bugs and helping us identifying and providing fixes. +To aid in the discovery of these users, you can use the following rake task to print synchronized groups that have members originating not from LDAP: -Special thanks for reporting and finding bugs go to +- Packaged installation: `sudo openproject run bundle exec rake ldap_groups:print_unsynced_members` +- Docker-based installation: `docker exec -it bash -c "openproject run bundle exec rake ldap_groups:print_unsynced_members"` -Daniel Narberhaus +Please note that these affected users are not automatically removed in this patch release, due to the system not knowing if are expected to be members. + +- Fixed: User from synchronized group not removed in OpenProject group after removed in LDAP \[[#41256](https://community.openproject.com/wp/41256)\] +- Fixed: When adding users to a group, existing users are shown in the autocompleter \[[#43892](https://community.openproject.com/wp/43892)\] From 2040c55327b284d35dedf934fabb455545f9cc53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Tue, 4 Oct 2022 11:42:43 +0200 Subject: [PATCH 017/148] Fix command in release notes --- docs/release-notes/12-2-5/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/release-notes/12-2-5/README.md b/docs/release-notes/12-2-5/README.md index 120d0e85b0..e62c707e1c 100644 --- a/docs/release-notes/12-2-5/README.md +++ b/docs/release-notes/12-2-5/README.md @@ -24,7 +24,7 @@ This results in users still being present in the group despite being removed in To aid in the discovery of these users, you can use the following rake task to print synchronized groups that have members originating not from LDAP: - Packaged installation: `sudo openproject run bundle exec rake ldap_groups:print_unsynced_members` -- Docker-based installation: `docker exec -it bash -c "openproject run bundle exec rake ldap_groups:print_unsynced_members"` +- Docker-based installation: `docker exec -it bash -c "bundle exec rake ldap_groups:print_unsynced_members"` Please note that these affected users are not automatically removed in this patch release, due to the system not knowing if are expected to be members. From 0e471ad866586f31915bd8b39377be99347dc071 Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 4 Oct 2022 12:15:21 +0200 Subject: [PATCH 018/148] on-boarding video modal changes --- app/views/onboarding/_onboarding_video_modal.html.erb | 1 - frontend/src/global_styles/openproject/_onboarding.sass | 1 - 2 files changed, 2 deletions(-) diff --git a/app/views/onboarding/_onboarding_video_modal.html.erb b/app/views/onboarding/_onboarding_video_modal.html.erb index 6f5569d40b..091b08eb93 100644 --- a/app/views/onboarding/_onboarding_video_modal.html.erb +++ b/app/views/onboarding/_onboarding_video_modal.html.erb @@ -34,7 +34,6 @@ See COPYRIGHT and LICENSE files for more details.
-

<%= I18n.t('onboarding.heading_getting_started') %>

<%= I18n.t('onboarding.text_getting_started_description') %> diff --git a/frontend/src/global_styles/openproject/_onboarding.sass b/frontend/src/global_styles/openproject/_onboarding.sass index f767e8db2a..19b71c7e16 100644 --- a/frontend/src/global_styles/openproject/_onboarding.sass +++ b/frontend/src/global_styles/openproject/_onboarding.sass @@ -36,7 +36,6 @@ line-height: 1.25 .onboarding--video - margin: 2em 0 align-self: center width: 100% From a093fe1ce0ce7b902a65b667ac67e22c06a2fc7c Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 4 Oct 2022 12:15:56 +0200 Subject: [PATCH 019/148] attribute help text modal changes --- .../components/attribute-help-texts/help-text.modal.html | 1 + frontend/src/app/spot/styles/sass/common/container.sass | 3 +++ 2 files changed, 4 insertions(+) diff --git a/frontend/src/app/shared/components/attribute-help-texts/help-text.modal.html b/frontend/src/app/shared/components/attribute-help-texts/help-text.modal.html index 2dcebcb523..39125a790e 100644 --- a/frontend/src/app/shared/components/attribute-help-texts/help-text.modal.html +++ b/frontend/src/app/shared/components/attribute-help-texts/help-text.modal.html @@ -18,6 +18,7 @@ >
diff --git a/frontend/src/app/spot/styles/sass/common/container.sass b/frontend/src/app/spot/styles/sass/common/container.sass index a8d038d40e..b2cdc4bbdd 100644 --- a/frontend/src/app/spot/styles/sass/common/container.sass +++ b/frontend/src/app/spot/styles/sass/common/container.sass @@ -19,3 +19,6 @@ > .spot-list margin: $spot-spacing-1 0 + + > .op-uc-container + padding-bottom: 0 From 07f470c075be9003dd11515bae1d3758c5b711ed Mon Sep 17 00:00:00 2001 From: bsatarnejad Date: Tue, 4 Oct 2022 12:17:36 +0200 Subject: [PATCH 020/148] response body modal changes --- .../vendor/foundation-apps/scss/vendor/_normalize.scss | 2 +- modules/webhooks/app/cells/views/response_body.erb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/global_styles/vendor/foundation-apps/scss/vendor/_normalize.scss b/frontend/src/global_styles/vendor/foundation-apps/scss/vendor/_normalize.scss index ae8bc83d72..5239f2e168 100644 --- a/frontend/src/global_styles/vendor/foundation-apps/scss/vendor/_normalize.scss +++ b/frontend/src/global_styles/vendor/foundation-apps/scss/vendor/_normalize.scss @@ -229,7 +229,7 @@ kbd, pre, samp { font-family: monospace, monospace; - font-size: 1em; + font-size: 0.875em; } /* Forms diff --git a/modules/webhooks/app/cells/views/response_body.erb b/modules/webhooks/app/cells/views/response_body.erb index b5ad03ee9f..e9b91c950e 100644 --- a/modules/webhooks/app/cells/views/response_body.erb +++ b/modules/webhooks/app/cells/views/response_body.erb @@ -8,14 +8,14 @@