Skip to content

Commit c1751b3

Browse files
committed
[#73188] Remove EE guards from boards
Make action boards available in Community Edition by removing board_view-based frontend and create-form gating, and align boards feature coverage with the new default behavior. https://community.openproject.org/wp/73188
1 parent 772fae7 commit c1751b3

27 files changed

+227
-339
lines changed

frontend/src/app/core/setup/globals/onboarding/onboarding_tour.ts

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -92,28 +92,18 @@ function workPackageFullViewTour() {
9292
});
9393
}
9494

95-
function ganttTour(configuration:ConfigurationService) {
95+
function ganttTour(_configuration:ConfigurationService) {
9696
initializeTour('ganttTourFinished');
9797

9898
const boardsDemoDataAvailable = getMetaContent('boards_demo_data_available') === 'true';
9999
const teamPlannerDemoDataAvailable = getMetaContent('demo_view_of_type_team_planner_seeded') === 'true';
100-
const eeTokenAvailable = configuration.availableFeatures.includes('board_view');
101100

102101
waitForElement('.work-package--results-tbody', '#content', () => {
103102
let steps:OnboardingStep[] = ganttOnboardingTourSteps();
104-
// Check for EE edition
105-
if (eeTokenAvailable) {
106-
// ... and available seed data of boards.
107-
// Then add boards to the tour, otherwise skip it.
108-
if (boardsDemoDataAvailable && moduleVisible('boards')) {
109-
steps = steps.concat(navigateToBoardStep('enterprise'));
110-
} else if (teamPlannerDemoDataAvailable && moduleVisible('team-planner-view')) {
111-
steps = steps.concat(navigateToTeamPlannerStep());
112-
} else {
113-
steps = steps.concat(menuTourSteps());
114-
}
115-
} else if (boardsDemoDataAvailable && moduleVisible('boards')) {
116-
steps = steps.concat(navigateToBoardStep('basic'));
103+
if (boardsDemoDataAvailable && moduleVisible('boards')) {
104+
steps = steps.concat(navigateToBoardStep('enterprise'));
105+
} else if (teamPlannerDemoDataAvailable && moduleVisible('team-planner-view')) {
106+
steps = steps.concat(navigateToTeamPlannerStep());
117107
} else {
118108
steps = steps.concat(menuTourSteps());
119109
}
@@ -122,14 +112,13 @@ function ganttTour(configuration:ConfigurationService) {
122112
});
123113
}
124114

125-
function boardTour(configuration:ConfigurationService) {
115+
function boardTour(_configuration:ConfigurationService) {
126116
initializeTour('boardsTourFinished');
127117

128118
const teamPlannerDemoDataAvailable = getMetaContent('demo_view_of_type_team_planner_seeded') === 'true';
129-
const eeTokenAvailable = configuration.availableFeatures.includes('board_view');
130119

131120
waitForElement('wp-single-card', '#content', () => {
132-
let steps:OnboardingStep[] = eeTokenAvailable ? boardTourSteps('enterprise') : boardTourSteps('basic');
121+
let steps:OnboardingStep[] = boardTourSteps('enterprise');
133122

134123
// Available seed data of team planner.
135124
// Then add Team planner to the tour, otherwise skip it.

frontend/src/app/features/boards/board/board-actions/board-actions-registry.service.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Injectable } from '@angular/core';
22
import { BoardActionService } from 'core-app/features/boards/board/board-actions/board-action.service';
3-
import { BannersService } from 'core-app/core/enterprise/banners.service';
43

54
export interface ITileViewEntry {
65
text:string;
@@ -13,10 +12,6 @@ export interface ITileViewEntry {
1312

1413
@Injectable({ providedIn: 'root' })
1514
export class BoardActionsRegistryService {
16-
constructor(
17-
private bannersService:BannersService,
18-
) {}
19-
2015
private mapping:Record<string, BoardActionService> = {};
2116

2217
public add(attribute:string, service:BoardActionService):void {
@@ -30,7 +25,6 @@ export class BoardActionsRegistryService {
3025
icon: '',
3126
description: '',
3227
image: '',
33-
disabled: !this.bannersService.allowsTo('board_view'),
3428
}));
3529
}
3630

Lines changed: 46 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,49 @@
11
@if ((board$ | async); as board) {
2-
@if (!board.isFree) {
3-
<op-enterprise-banner-frame class="boards-list--enterprise-banner"
4-
feature="board_view"
5-
[dismissable]="true"
6-
/>
7-
}
8-
@if (available) {
9-
<div
10-
class="boards-list--container"
11-
[ngClass]="{ '-free' : board.isFree }"
12-
#container
13-
cdkDropList
14-
[cdkDropListDisabled]="!board.editable"
15-
cdkDropListOrientation="horizontal"
16-
(cdkDropListDropped)="moveList(board, $event)"
17-
>
18-
@for (boardWidget of boardWidgets; track trackByQueryId($index, boardWidget)) {
19-
<div
20-
class="boards-list--item"
21-
cdkDrag
22-
[cdkDragData]="boardWidget"
23-
>
24-
@if (board.editable) {
25-
<span
26-
class="boards-list-item-handle icon icon-drag-handle"
27-
cdkDragHandle></span>
28-
}
29-
<board-list [resource]="boardWidget"
30-
[board]="board"
31-
(onRemove)="removeList(board, boardWidget)"
32-
(visibilityChange)="changeVisibilityOfList(board, boardWidget, $event)" />
2+
<div
3+
class="boards-list--container"
4+
[ngClass]="{ '-free' : board.isFree }"
5+
#container
6+
cdkDropList
7+
[cdkDropListDisabled]="!board.editable"
8+
cdkDropListOrientation="horizontal"
9+
(cdkDropListDropped)="moveList(board, $event)"
10+
>
11+
@for (boardWidget of boardWidgets; track trackByQueryId($index, boardWidget)) {
12+
<div
13+
class="boards-list--item"
14+
cdkDrag
15+
[cdkDragData]="boardWidget"
16+
>
17+
@if (board.editable) {
18+
<span
19+
class="boards-list-item-handle icon icon-drag-handle"
20+
cdkDragHandle></span>
21+
}
22+
<board-list [resource]="boardWidget"
23+
[board]="board"
24+
(onRemove)="removeList(board, boardWidget)"
25+
(visibilityChange)="changeVisibilityOfList(board, boardWidget, $event)" />
26+
</div>
27+
}
28+
@if (showHiddenListWarning) {
29+
<span
30+
class="boards-list--tooltip tooltip--right"
31+
[attr.data-tooltip]="text.hiddenListWarning">
32+
<i class="icon icon-attention"></i>
33+
</span>
34+
}
35+
@if (board.editable) {
36+
<div class="boards-list--add-item -no-text-select"
37+
role="button"
38+
tabindex="0"
39+
(click)="addList(board)"
40+
(keydown.enter)="addList(board)"
41+
(keydown.space)="addList(board)">
42+
<div class="boards-list--add-item-text">
43+
<op-icon icon-classes="icon-add icon-context" />
44+
<span [textContent]="text.addList"></span>
3345
</div>
34-
}
35-
@if (showHiddenListWarning) {
36-
<span
37-
class="boards-list--tooltip tooltip--right"
38-
[attr.data-tooltip]="text.hiddenListWarning">
39-
<i class="icon icon-attention"></i>
40-
</span>
41-
}
42-
@if (board.editable) {
43-
<div class="boards-list--add-item -no-text-select"
44-
role="button"
45-
tabindex="0"
46-
(click)="addList(board)"
47-
(keydown.enter)="addList(board)"
48-
(keydown.space)="addList(board)">
49-
<div class="boards-list--add-item-text">
50-
<op-icon icon-classes="icon-add icon-context" />
51-
<span [textContent]="text.addList"></span>
52-
</div>
53-
</div>
54-
}
55-
</div>
56-
}
46+
</div>
47+
}
48+
</div>
5749
}

frontend/src/app/features/boards/board/board-partitioned-page/board-list-container.component.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { HalResourceNotificationService } from 'core-app/features/hal/services/h
1717
import { BoardListsService } from 'core-app/features/boards/board/board-list/board-lists.service';
1818
import { OpModalService } from 'core-app/shared/components/modal/modal.service';
1919
import { BoardService } from 'core-app/features/boards/board/board.service';
20-
import { BannersService } from 'core-app/core/enterprise/banners.service';
2120
import { DragAndDropService } from 'core-app/shared/helpers/drag-and-drop/drag-and-drop.service';
2221
import { QueryUpdatedService } from 'core-app/features/boards/board/query-updated/query-updated.service';
2322
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin';
@@ -89,8 +88,6 @@ export class BoardListContainerComponent extends UntilDestroyedMixin implements
8988

9089
showHiddenListWarning = false;
9190

92-
available = this.Banner.allowsTo('board_view');
93-
9491
private currentQueryUpdatedMonitoring:Subscription;
9592

9693
constructor(
@@ -105,7 +102,6 @@ readonly I18n:I18nService,
105102
readonly injector:Injector,
106103
readonly apiV3Service:ApiV3Service,
107104
readonly Boards:BoardService,
108-
readonly Banner:BannersService,
109105
readonly boardListCrossSelectionService:BoardListCrossSelectionService,
110106
readonly wpStatesInitialization:WorkPackageStatesInitializationService,
111107
readonly Drag:DragAndDropService,
@@ -126,10 +122,6 @@ readonly I18n:I18nService,
126122
tap((board) => this.setupQueryUpdatedMonitoring(board)),
127123
);
128124

129-
this.board$.subscribe((board) => {
130-
this.available = this.Banner.allowsTo('board_view') || board.isFree;
131-
});
132-
133125
this.Boards.currentBoard$.next(id);
134126

135127
this.boardListCrossSelectionService

modules/boards/app/controllers/boards/boards_controller.rb

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# frozen_string_literal: true
2+
13
module ::Boards
24
class BoardsController < BaseController
35
include Layout
@@ -11,7 +13,6 @@ class BoardsController < BaseController
1113

1214
before_action :build_board_grid, only: %i[new]
1315
before_action :load_query, only: %i[index]
14-
before_action :ensure_board_type_not_restricted, only: %i[create]
1516

1617
menu_item :boards
1718

@@ -85,14 +86,6 @@ def build_board_grid
8586
@board_grid = Boards::Grid.new
8687
end
8788

88-
def ensure_board_type_not_restricted
89-
render_403 if restricted_board_type?
90-
end
91-
92-
def restricted_board_type?
93-
!EnterpriseToken.allows_to?(:board_view) && board_grid_params[:attribute] != "basic"
94-
end
95-
9689
def service_call
9790
service_class.new(user: User.current)
9891
.call(
@@ -114,7 +107,7 @@ def service_class
114107
end
115108

116109
def board_grid_params
117-
params.require(:boards_grid).permit(%i[name attribute])
110+
params.expect(boards_grid: %i[name attribute])
118111
end
119112
end
120113
end

modules/boards/app/helpers/boards_helper.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ module BoardsHelper
99

1010
def board_types
1111
[
12-
build_board_type_attributes("basic", "lists", false),
12+
build_board_type_attributes("basic", "lists", disabled: false),
1313
build_board_type_attributes("status", "status"),
1414
build_board_type_attributes("assignee", "assignees"),
1515
build_board_type_attributes("version", "version"),
@@ -18,7 +18,7 @@ def board_types
1818
]
1919
end
2020

21-
def build_board_type_attributes(type_name, image_name, disabled = !EnterpriseToken.allows_to?(:board_view))
21+
def build_board_type_attributes(type_name, image_name, disabled: false)
2222
BoardTypeAttributes.new(type_name,
2323
I18n.t("boards.board_type_attributes.#{type_name}"),
2424
I18n.t("boards.board_type_descriptions.#{type_name}"),
@@ -35,6 +35,6 @@ def global_board_new_action?
3535
end
3636

3737
def global_board_create_action?
38-
request.path == work_package_boards_path && @project.nil?
38+
request.path == work_package_boards_path && controller.params[:project_id].blank?
3939
end
4040
end

modules/boards/app/views/boards/boards/_form.html.erb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,7 @@ See COPYRIGHT and LICENSE files for more details.
5959

6060
<div class="form--field -required -align-start">
6161
<label class="form--label" for="board_type"><%= t("boards.label_board_type") %></label>
62-
<div class="form--field-container -enterprise-restricted">
63-
<%=
64-
render(EnterpriseEdition::BannerComponent.new(:board_view))
65-
%>
66-
62+
<div class="form--field-container">
6763
<div class="op-tile-block">
6864
<% board_types.each_with_index do |board_type, tile_number| %>
6965
<label class="op-tile-block--tile form--radio-button-container -wide <%= "-disabled" if board_type.disabled? %>"
@@ -84,7 +80,7 @@ See COPYRIGHT and LICENSE files for more details.
8480
</div>
8581
</div>
8682

87-
<img src="<%= frontend_asset_path board_type.image_path%>"
83+
<img src="<%= frontend_asset_path board_type.image_path %>"
8884
alt=""
8985
class="op-tile-block--image">
9086
</label>

modules/boards/spec/features/action_boards/assignee_board_spec.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@
3232

3333
RSpec.describe "Assignee action board",
3434
:js,
35-
:selenium,
36-
with_ee: %i[board_view] do
35+
:selenium do
3736
let(:bobself_user) do
3837
create(:user,
3938
firstname: "Bob",

modules/boards/spec/features/action_boards/custom_field_filters_spec.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434

3535
RSpec.describe "Custom field filter in boards",
3636
:js,
37-
:selenium,
38-
with_ee: %i[board_view] do
37+
:selenium do
3938
let(:user) do
4039
create(:user,
4140
member_with_roles: { project => role })

modules/boards/spec/features/action_boards/status_board_spec.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@
3232

3333
RSpec.describe "Status action board",
3434
:js,
35-
:selenium,
36-
with_ee: %i[board_view] do
35+
:selenium do
3736
let(:user) do
3837
create(:user,
3938
member_with_roles: { project => role })

0 commit comments

Comments
 (0)