parent
f1b30c547f
commit
1cca351d31
@ -0,0 +1,19 @@ |
||||
<div class="title-container"> |
||||
<h2 [textContent]="text.title"></h2> |
||||
</div> |
||||
|
||||
<form> |
||||
<section class="form--section"> |
||||
<h3 [textContent]="text.daily.title"></h3> |
||||
<span [textContent]="text.daily.explanation"></span> |
||||
|
||||
<op-reminder-settings-daily-time> |
||||
</op-reminder-settings-daily-time> |
||||
</section> |
||||
<button |
||||
class="button -highlight" |
||||
[textContent]="text.save" |
||||
(click)="saveChanges()" |
||||
> |
||||
</button> |
||||
</form> |
@ -0,0 +1,55 @@ |
||||
import { |
||||
ChangeDetectionStrategy, Component, Input, OnInit, |
||||
} from '@angular/core'; |
||||
import { I18nService } from 'core-app/core/i18n/i18n.service'; |
||||
import { CurrentUserService } from 'core-app/core/current-user/current-user.service'; |
||||
import { take } from 'rxjs/internal/operators/take'; |
||||
import { UIRouterGlobals } from '@uirouter/core'; |
||||
import { UserPreferencesService } from 'core-app/features/user-preferences/state/user-preferences.service'; |
||||
import { UserPreferencesQuery } from 'core-app/features/user-preferences/state/user-preferences.query'; |
||||
|
||||
export const myReminderPageComponentSelector = 'op-reminders-page'; |
||||
|
||||
@Component({ |
||||
selector: myReminderPageComponentSelector, |
||||
templateUrl: './reminder-settings-page.component.html', |
||||
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
}) |
||||
export class ReminderSettingsPageComponent implements OnInit { |
||||
@Input() userId:string; |
||||
|
||||
text = { |
||||
title: this.I18n.t('js.reminders.settings.title'), |
||||
save: this.I18n.t('js.button_save'), |
||||
daily: { |
||||
title: this.I18n.t('js.reminders.settings.daily.title'), |
||||
explanation: this.I18n.t('js.reminders.settings.daily.explanation'), |
||||
}, |
||||
}; |
||||
|
||||
constructor( |
||||
private I18n:I18nService, |
||||
private stateService:UserPreferencesService, |
||||
private query:UserPreferencesQuery, |
||||
private currentUserService:CurrentUserService, |
||||
private uiRouterGlobals:UIRouterGlobals, |
||||
) { |
||||
} |
||||
|
||||
ngOnInit():void { |
||||
this.userId = this.userId || this.uiRouterGlobals.params.userId; |
||||
this |
||||
.currentUserService |
||||
.user$ |
||||
.pipe(take(1)) |
||||
.subscribe((user) => { |
||||
this.userId = this.userId || user.id!; |
||||
this.stateService.get(this.userId); |
||||
}); |
||||
} |
||||
|
||||
public saveChanges():void { |
||||
const prefs = this.query.getValue(); |
||||
this.stateService.update(this.userId, prefs); |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
<label |
||||
*ngFor="let time of dailyReminderTimes; index as i" |
||||
class="form--label-with-check-box"> |
||||
<div class="form--check-box-container"> |
||||
<input type="checkbox" class="form--check-box" checked> |
||||
</div> |
||||
{{text.label(i + 1)}} |
||||
<div class="form--field -no-label"> |
||||
<div class="form--field-container"> |
||||
<div class="form--text-field-container"> |
||||
<input |
||||
type="time" |
||||
[value]="time" |
||||
step="1800" |
||||
required |
||||
attr.data-qa-selector="op-settings-daily-time--time-{{i + 1}}"> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</label> |
@ -0,0 +1,30 @@ |
||||
import { Component, Input, OnInit } from "@angular/core"; |
||||
import { ChangeDetectionStrategy } from "@angular/core"; |
||||
import { I18nService } from 'core-app/core/i18n/i18n.service'; |
||||
import { UserPreferencesStore } from 'core-app/features/user-preferences/state/user-preferences.store'; |
||||
|
||||
@Component({ |
||||
selector: 'op-reminder-settings-daily-time', |
||||
templateUrl: './reminder-settings-daily-time.component.html', |
||||
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
}) |
||||
export class ReminderSettingsDailyTimeComponent implements OnInit { |
||||
public dailyReminderTimes = ["08:00", "12:00", "16:00"] |
||||
|
||||
text = { |
||||
label: (counter:number):string => this.I18n.t('js.reminders.settings.daily.label', { counter: counter }), |
||||
}; |
||||
|
||||
constructor( |
||||
private I18n:I18nService, |
||||
private store:UserPreferencesStore, |
||||
) { |
||||
} |
||||
|
||||
ngOnInit():void { |
||||
|
||||
} |
||||
|
||||
public saveChanges():void { |
||||
} |
||||
} |
Before Width: | Height: | Size: 153 KiB After Width: | Height: | Size: 155 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,65 @@ |
||||
require 'spec_helper' |
||||
require 'support/pages/my/notifications' |
||||
|
||||
describe "Reminder email", type: :feature, js: true do |
||||
let!(:project) { FactoryBot.create :project, members: { current_user => role } } |
||||
let!(:mute_project) { FactoryBot.create :project, members: { current_user => role } } |
||||
let(:reminders_settings_page) { Pages::My::Reminders.new(current_user) } |
||||
let(:role) { FactoryBot.create(:role, permissions: %i[view_work_packages]) } |
||||
let(:other_user) { FactoryBot.create(:user) } |
||||
let(:work_package) { FactoryBot.create(:work_package, project: project) } |
||||
let(:watched_work_package) { FactoryBot.create(:work_package, project: project, watcher_users: [current_user]) } |
||||
let(:involved_work_package) { FactoryBot.create(:work_package, project: project, assigned_to: current_user) } |
||||
|
||||
current_user do |
||||
FactoryBot.create :user, |
||||
notification_settings: [ |
||||
FactoryBot.build(:mail_notification_setting, |
||||
involved: false, |
||||
watched: false, |
||||
mentioned: false, |
||||
work_package_commented: false, |
||||
work_package_created: false, |
||||
work_package_processed: false, |
||||
work_package_prioritized: false, |
||||
work_package_scheduled: false, |
||||
all: false), |
||||
FactoryBot.build(:in_app_notification_setting, |
||||
involved: false, |
||||
watched: false, |
||||
mentioned: false, |
||||
work_package_commented: false, |
||||
work_package_created: false, |
||||
work_package_processed: false, |
||||
work_package_prioritized: false, |
||||
work_package_scheduled: false, |
||||
all: false), |
||||
FactoryBot.build(:mail_digest_notification_setting, |
||||
involved: true, |
||||
watched: true, |
||||
mentioned: true, |
||||
work_package_commented: true, |
||||
work_package_created: true, |
||||
work_package_processed: true, |
||||
work_package_prioritized: true, |
||||
work_package_scheduled: true, |
||||
all: false) |
||||
] |
||||
end |
||||
|
||||
before do |
||||
watched_work_package |
||||
work_package |
||||
involved_work_package |
||||
|
||||
ActiveJob::Base.queue_adapter.enqueued_jobs.clear |
||||
end |
||||
|
||||
it 'sends a reminder mail based on the configuration', with_settings: { journal_aggregation_time_minutes: 0 } do |
||||
# Configure the digest |
||||
reminders_settings_page.visit! |
||||
|
||||
# By default a reminder timed for 8:00 should be configured |
||||
reminders_settings_page.expect_active_daily_times("08:00") |
||||
end |
||||
end |
@ -0,0 +1,39 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'support/pages/reminders/settings' |
||||
|
||||
module Pages |
||||
module My |
||||
class Reminders < ::Pages::Reminders::Settings |
||||
def path |
||||
my_reminders_path |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,64 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2021 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 docs/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'support/pages/page' |
||||
|
||||
module Pages |
||||
module Reminders |
||||
class Settings < ::Pages::Page |
||||
attr_reader :user |
||||
|
||||
def initialize(user) |
||||
super() |
||||
@user = user |
||||
end |
||||
|
||||
def path |
||||
edit_user_path(user, tab: :reminders) |
||||
end |
||||
|
||||
def expect_active_daily_times(*times) |
||||
times.each_with_index do |time, index| |
||||
expect(page) |
||||
.to have_checked_field "Time #{index + 1}" |
||||
|
||||
expect(page) |
||||
.to have_css("input[data-qa-selector='op-settings-daily-time--time-#{index + 1}']") |
||||
|
||||
expect(page.find("input[data-qa-selector='op-settings-daily-time--time-#{index + 1}']").value) |
||||
.to eql(time) |
||||
end |
||||
end |
||||
|
||||
def save |
||||
click_button 'Save' |
||||
end |
||||
|
||||
end |
||||
end |
||||
end |
After Width: | Height: | Size: 2.5 KiB |
Loading…
Reference in new issue