Merge pull request #7124 from opf/feature/board-highlighting
Replace display-mode tab with highlighting tabpull/7134/head
commit
eb040ee2ea
@ -1 +1,3 @@ |
||||
export type HighlightingMode = 'status'|'priority'|'type'|'inline'|'none'; |
||||
|
||||
export type CardHighlightingMode = 'status'|'priority'|'type'|'inline'|'none'|'entire-card'; |
||||
|
@ -1,31 +0,0 @@ |
||||
<div> |
||||
<form> |
||||
<p [textContent]="text.choose_mode"></p> |
||||
<div class="form--field -full-width"> |
||||
<div class="form--field-container"> |
||||
<label class="option-label"> |
||||
<input type="radio" |
||||
[(ngModel)]="displayMode" |
||||
value="cards" |
||||
name="display_mode_switch"> |
||||
<op-icon icon-classes="icon-projects" [attr.icon-title]="text.card_mode"></op-icon> |
||||
&ngsp; |
||||
<span [textContent]="text.card_mode"></span> |
||||
</label> |
||||
</div> |
||||
</div> |
||||
<div class="form--field -full-width"> |
||||
<div class="form--field-container"> |
||||
<label class="option-label"> |
||||
<input type="radio" |
||||
[(ngModel)]="displayMode" |
||||
value="table" |
||||
name="display_mode_switch"> |
||||
<op-icon icon-classes="icon-view-list" [attr.icon-title]="text.table_mode"></op-icon> |
||||
&ngsp; |
||||
<span [textContent]="text.table_mode"></span> |
||||
</label> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
@ -1,39 +0,0 @@ |
||||
import {Component, Inject, Injector} from '@angular/core'; |
||||
import {I18nService} from 'core-app/modules/common/i18n/i18n.service'; |
||||
import {TabComponent} from 'core-components/wp-table/configuration-modal/tab-portal-outlet'; |
||||
import {OpModalLocalsMap} from "core-components/op-modals/op-modal.types"; |
||||
import {Board, BoardDisplayMode} from "core-app/modules/boards/board/board"; |
||||
import {OpModalLocalsToken} from "core-components/op-modals/op-modal.service"; |
||||
|
||||
@Component({ |
||||
templateUrl: './display-settings-tab.component.html' |
||||
}) |
||||
export class BoardConfigurationDisplaySettingsTab implements TabComponent { |
||||
|
||||
// Current board resource
|
||||
public board:Board; |
||||
|
||||
// Display mode
|
||||
public displayMode:BoardDisplayMode = 'cards'; |
||||
|
||||
public text = { |
||||
choose_mode: this.I18n.t('js.work_packages.table_configuration.choose_display_mode'), |
||||
card_mode: this.I18n.t('js.boards.configuration_modal.display_settings.card_mode'), |
||||
table_mode: this.I18n.t('js.boards.configuration_modal.display_settings.table_mode'), |
||||
|
||||
}; |
||||
|
||||
constructor(readonly injector:Injector, |
||||
@Inject(OpModalLocalsToken) public locals:OpModalLocalsMap, |
||||
readonly I18n:I18nService) { |
||||
} |
||||
|
||||
public onSave() { |
||||
this.board.displayMode = this.displayMode; |
||||
} |
||||
|
||||
ngOnInit() { |
||||
this.board = this.locals.board; |
||||
this.displayMode = this.board.displayMode; |
||||
} |
||||
} |
@ -0,0 +1,60 @@ |
||||
<div> |
||||
<form> |
||||
<p [textContent]="text.highlighting_mode.description"></p> |
||||
|
||||
<div class="form--field -full-width"> |
||||
<div class="form--field-container"> |
||||
<label class="option-label"> |
||||
<input type="radio" |
||||
[(ngModel)]="highlightingMode" |
||||
(change)="updateMode($event.target.value)" |
||||
value="inline" |
||||
name="highlighting_mode_switch"> |
||||
{{ text.highlighting_mode.inline }} |
||||
{{ text.highlighting_mode.type }} |
||||
</label> |
||||
</div> |
||||
</div> |
||||
<div class="form--field -full-width"> |
||||
<div class="form--field-container"> |
||||
<label class="option-label"> |
||||
<input type="radio" |
||||
[(ngModel)]="entireCardMode" |
||||
(change)="updateMode('entire-card')" |
||||
[value]="true" |
||||
name="entire_card_switch"> |
||||
<span [textContent]="text.highlighting_mode.entire_card_by"></span> |
||||
&ngsp; |
||||
<select (change)="updateMode($event.target.value)" |
||||
id="selected_attribute" |
||||
name="selected_attribute" |
||||
class="form--select form--inline-select"> |
||||
<option [textContent]="text.highlighting_mode.status" |
||||
[selected]="lastEntireCardAttribute === 'status'" |
||||
value="status"></option> |
||||
<option [textContent]="text.highlighting_mode.type" |
||||
[selected]="lastEntireCardAttribute === 'type'" |
||||
value="type"></option> |
||||
<option [textContent]="text.highlighting_mode.priority" |
||||
[selected]="lastEntireCardAttribute === 'priority'" |
||||
value="priority"></option> |
||||
</select> |
||||
</label> |
||||
</div> |
||||
</div> |
||||
<div class="form--field -full-width"> |
||||
<div class="form--field-container"> |
||||
<label class="option-label"> |
||||
<input type="radio" |
||||
[(ngModel)]="highlightingMode" |
||||
(change)="updateMode($event.target.value)" |
||||
value="none" |
||||
name="highlighting_mode_switch"> |
||||
<span [textContent]="text.highlighting_mode.none"></span> |
||||
</label> |
||||
</div> |
||||
</div> |
||||
|
||||
</form> |
||||
</div> |
||||
|
@ -0,0 +1,70 @@ |
||||
import {Component, Inject, Injector} from '@angular/core'; |
||||
import {I18nService} from 'core-app/modules/common/i18n/i18n.service'; |
||||
import {TabComponent} from 'core-components/wp-table/configuration-modal/tab-portal-outlet'; |
||||
import {OpModalLocalsMap} from "core-components/op-modals/op-modal.types"; |
||||
import {Board} from "core-app/modules/boards/board/board"; |
||||
import {OpModalLocalsToken} from "core-components/op-modals/op-modal.service"; |
||||
import { |
||||
CardHighlightingMode, |
||||
HighlightingMode |
||||
} from "core-components/wp-fast-table/builders/highlighting/highlighting-mode.const"; |
||||
import {WorkPackageTableHighlightingService} from "core-components/wp-fast-table/state/wp-table-highlighting.service"; |
||||
import {HalResource} from "core-app/modules/hal/resources/hal-resource"; |
||||
|
||||
@Component({ |
||||
templateUrl: './highlighting-tab.component.html' |
||||
}) |
||||
export class BoardHighlightingTabComponent implements TabComponent { |
||||
|
||||
// Highlighting mode
|
||||
public highlightingMode:CardHighlightingMode = 'inline'; |
||||
public entireCardMode:boolean = false; |
||||
public lastEntireCardAttribute:CardHighlightingMode = 'status'; |
||||
|
||||
// Current board resource
|
||||
public board:Board; |
||||
|
||||
public text = { |
||||
highlighting_mode: { |
||||
description: this.I18n.t('js.work_packages.table_configuration.highlighting_mode.description'), |
||||
none: this.I18n.t('js.work_packages.table_configuration.highlighting_mode.none'), |
||||
inline: this.I18n.t('js.card.highlighting.inline'), |
||||
status: this.I18n.t('js.work_packages.table_configuration.highlighting_mode.status'), |
||||
type: this.I18n.t('js.work_packages.properties.type'), |
||||
priority: this.I18n.t('js.work_packages.table_configuration.highlighting_mode.priority'), |
||||
entire_card_by: this.I18n.t('js.card.highlighting.entire_card_by'), |
||||
} |
||||
}; |
||||
|
||||
constructor(readonly injector:Injector, |
||||
@Inject(OpModalLocalsToken) public locals:OpModalLocalsMap, |
||||
readonly I18n:I18nService) { |
||||
} |
||||
|
||||
public onSave() { |
||||
this.updateMode(this.highlightingMode); |
||||
this.board.highlightingMode = this.highlightingMode; |
||||
} |
||||
|
||||
ngOnInit() { |
||||
this.board = this.locals.board; |
||||
this.highlightingMode = this.board.highlightingMode; |
||||
this.updateMode(this.highlightingMode); |
||||
} |
||||
|
||||
public updateMode(mode:CardHighlightingMode) { |
||||
if (mode === 'entire-card') { |
||||
this.highlightingMode = this.lastEntireCardAttribute; |
||||
} else { |
||||
this.highlightingMode = mode; |
||||
} |
||||
|
||||
if (['status', 'priority', 'type'].indexOf(this.highlightingMode) !== -1) { |
||||
this.lastEntireCardAttribute = this.highlightingMode; |
||||
this.entireCardMode = true; |
||||
} else { |
||||
this.entireCardMode = false; |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,104 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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-2017 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 'spec_helper' |
||||
require_relative './support/board_index_page' |
||||
require_relative './support/board_page' |
||||
|
||||
describe 'Work Package boards spec', type: :feature, js: true do |
||||
let(:user) do |
||||
FactoryBot.create(:user, |
||||
member_in_project: project, |
||||
member_through_role: role) |
||||
end |
||||
let(:project) { FactoryBot.create(:project, enabled_module_names: %i[work_package_tracking board_view]) } |
||||
let(:permissions) { %i[show_board_views manage_board_views add_work_packages view_work_packages manage_public_queries] } |
||||
let(:role) { FactoryBot.create(:role, permissions: permissions) } |
||||
|
||||
let!(:wp) do |
||||
FactoryBot.create(:work_package, |
||||
project: project, |
||||
type: type, |
||||
priority: priority, |
||||
status: open_status) |
||||
end |
||||
let!(:wp2) do |
||||
FactoryBot.create(:work_package, |
||||
project: project, |
||||
type: type2, |
||||
priority: priority2, |
||||
status: open_status) |
||||
end |
||||
|
||||
let!(:priority) { FactoryBot.create :priority, color: color } |
||||
let!(:priority2) { FactoryBot.create :priority, color: color2 } |
||||
let!(:type) { FactoryBot.create :type, color: color } |
||||
let!(:type2) { FactoryBot.create :type, color: color2 } |
||||
let!(:open_status) { FactoryBot.create :default_status, name: 'Open' } |
||||
|
||||
let(:board_index) { Pages::BoardIndex.new(project) } |
||||
|
||||
let(:color) { FactoryBot.create :color } |
||||
let(:color2) { FactoryBot.create :color } |
||||
|
||||
before do |
||||
project |
||||
login_as(user) |
||||
end |
||||
|
||||
it 'navigates from boards to the WP full view and back' do |
||||
board_index.visit! |
||||
|
||||
board_page = board_index.create_board action: :Status |
||||
|
||||
# See the work packages |
||||
board_page.expect_query 'Open', editable: true |
||||
board_page.expect_card 'Open', wp.subject |
||||
board_page.expect_card 'Open', wp2.subject |
||||
|
||||
# Highlight inline |
||||
board_page.change_board_highlighting 'inline' |
||||
expect(page).to have_selector('.__hl_dot_type_' + type.id.to_s) |
||||
expect(page).to have_selector('.__hl_dot_type_' + type2.id.to_s) |
||||
|
||||
# Highlight whole card by type |
||||
board_page.change_board_highlighting 'entire-card', 'Type' |
||||
expect(page).to have_selector('.__hl_row_type_' + type.id.to_s) |
||||
expect(page).to have_selector('.__hl_row_type_' + type2.id.to_s) |
||||
|
||||
# Highlight whole card by priority |
||||
board_page.change_board_highlighting 'entire-card', 'Priority' |
||||
expect(page).to have_selector('.__hl_row_priority_' + priority.id.to_s) |
||||
expect(page).to have_selector('.__hl_row_priority_' + priority2.id.to_s) |
||||
|
||||
# Disable highlighting |
||||
board_page.change_board_highlighting 'none' |
||||
expect(page).not_to have_selector('.__hl_row_priority_' + priority.id.to_s) |
||||
expect(page).not_to have_selector('.__hl_row_priority_' + priority2.id.to_s) |
||||
end |
||||
end |
Loading…
Reference in new issue