Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 7 additions & 18 deletions frontend/src/app/core/setup/globals/onboarding/onboarding_tour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,28 +92,18 @@ function workPackageFullViewTour() {
});
}

function ganttTour(configuration:ConfigurationService) {
function ganttTour(_configuration:ConfigurationService) {
initializeTour('ganttTourFinished');

const boardsDemoDataAvailable = getMetaContent('boards_demo_data_available') === 'true';
const teamPlannerDemoDataAvailable = getMetaContent('demo_view_of_type_team_planner_seeded') === 'true';
const eeTokenAvailable = configuration.availableFeatures.includes('board_view');

waitForElement('.work-package--results-tbody', '#content', () => {
let steps:OnboardingStep[] = ganttOnboardingTourSteps();
// Check for EE edition
if (eeTokenAvailable) {
// ... and available seed data of boards.
// Then add boards to the tour, otherwise skip it.
if (boardsDemoDataAvailable && moduleVisible('boards')) {
steps = steps.concat(navigateToBoardStep('enterprise'));
} else if (teamPlannerDemoDataAvailable && moduleVisible('team-planner-view')) {
steps = steps.concat(navigateToTeamPlannerStep());
} else {
steps = steps.concat(menuTourSteps());
}
} else if (boardsDemoDataAvailable && moduleVisible('boards')) {
steps = steps.concat(navigateToBoardStep('basic'));
if (boardsDemoDataAvailable && moduleVisible('boards')) {
steps = steps.concat(navigateToBoardStep('enterprise'));
} else if (teamPlannerDemoDataAvailable && moduleVisible('team-planner-view')) {
steps = steps.concat(navigateToTeamPlannerStep());
} else {
steps = steps.concat(menuTourSteps());
}
Expand All @@ -122,14 +112,13 @@ function ganttTour(configuration:ConfigurationService) {
});
}

function boardTour(configuration:ConfigurationService) {
function boardTour(_configuration:ConfigurationService) {
initializeTour('boardsTourFinished');

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

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

// Available seed data of team planner.
// Then add Team planner to the tour, otherwise skip it.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Injectable } from '@angular/core';
import { BoardActionService } from 'core-app/features/boards/board/board-actions/board-action.service';
import { BannersService } from 'core-app/core/enterprise/banners.service';

export interface ITileViewEntry {
text:string;
Expand All @@ -13,10 +12,6 @@ export interface ITileViewEntry {

@Injectable({ providedIn: 'root' })
export class BoardActionsRegistryService {
constructor(
private bannersService:BannersService,
) {}

private mapping:Record<string, BoardActionService> = {};

public add(attribute:string, service:BoardActionService):void {
Expand All @@ -30,7 +25,6 @@ export class BoardActionsRegistryService {
icon: '',
description: '',
image: '',
disabled: !this.bannersService.allowsTo('board_view'),
}));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,57 +1,49 @@
@if ((board$ | async); as board) {
@if (!board.isFree) {
<op-enterprise-banner-frame class="boards-list--enterprise-banner"
feature="board_view"
[dismissable]="true"
/>
}
@if (available) {
<div
class="boards-list--container"
[ngClass]="{ '-free' : board.isFree }"
#container
cdkDropList
[cdkDropListDisabled]="!board.editable"
cdkDropListOrientation="horizontal"
(cdkDropListDropped)="moveList(board, $event)"
>
@for (boardWidget of boardWidgets; track trackByQueryId($index, boardWidget)) {
<div
class="boards-list--item"
cdkDrag
[cdkDragData]="boardWidget"
>
@if (board.editable) {
<span
class="boards-list-item-handle icon icon-drag-handle"
cdkDragHandle></span>
}
<board-list [resource]="boardWidget"
[board]="board"
(onRemove)="removeList(board, boardWidget)"
(visibilityChange)="changeVisibilityOfList(board, boardWidget, $event)" />
<div
class="boards-list--container"
[ngClass]="{ '-free' : board.isFree }"
#container
cdkDropList
[cdkDropListDisabled]="!board.editable"
cdkDropListOrientation="horizontal"
(cdkDropListDropped)="moveList(board, $event)"
>
@for (boardWidget of boardWidgets; track trackByQueryId($index, boardWidget)) {
<div
class="boards-list--item"
cdkDrag
[cdkDragData]="boardWidget"
>
@if (board.editable) {
<span
class="boards-list-item-handle icon icon-drag-handle"
cdkDragHandle></span>
}
<board-list [resource]="boardWidget"
[board]="board"
(onRemove)="removeList(board, boardWidget)"
(visibilityChange)="changeVisibilityOfList(board, boardWidget, $event)" />
</div>
}
@if (showHiddenListWarning) {
<span
class="boards-list--tooltip tooltip--right"
[attr.data-tooltip]="text.hiddenListWarning">
<i class="icon icon-attention"></i>
</span>
}
@if (board.editable) {
<div class="boards-list--add-item -no-text-select"
role="button"
tabindex="0"
(click)="addList(board)"
(keydown.enter)="addList(board)"
(keydown.space)="addList(board)">
<div class="boards-list--add-item-text">
<op-icon icon-classes="icon-add icon-context" />
<span [textContent]="text.addList"></span>
</div>
}
@if (showHiddenListWarning) {
<span
class="boards-list--tooltip tooltip--right"
[attr.data-tooltip]="text.hiddenListWarning">
<i class="icon icon-attention"></i>
</span>
}
@if (board.editable) {
<div class="boards-list--add-item -no-text-select"
role="button"
tabindex="0"
(click)="addList(board)"
(keydown.enter)="addList(board)"
(keydown.space)="addList(board)">
<div class="boards-list--add-item-text">
<op-icon icon-classes="icon-add icon-context" />
<span [textContent]="text.addList"></span>
</div>
</div>
}
</div>
}
</div>
}
</div>
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import { HalResourceNotificationService } from 'core-app/features/hal/services/h
import { BoardListsService } from 'core-app/features/boards/board/board-list/board-lists.service';
import { OpModalService } from 'core-app/shared/components/modal/modal.service';
import { BoardService } from 'core-app/features/boards/board/board.service';
import { BannersService } from 'core-app/core/enterprise/banners.service';
import { DragAndDropService } from 'core-app/shared/helpers/drag-and-drop/drag-and-drop.service';
import { QueryUpdatedService } from 'core-app/features/boards/board/query-updated/query-updated.service';
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin';
Expand All @@ -40,7 +39,6 @@ import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import {
WorkPackageStatesInitializationService,
} from 'core-app/features/work-packages/components/wp-list/wp-states-initialization.service';
import { enterpriseDocsUrl } from 'core-app/core/setup/globals/constants.const';

@Component({
templateUrl: './board-list-container.component.html',
Expand Down Expand Up @@ -89,8 +87,6 @@ export class BoardListContainerComponent extends UntilDestroyedMixin implements

showHiddenListWarning = false;

available = this.Banner.allowsTo('board_view');

private currentQueryUpdatedMonitoring:Subscription;

constructor(
Expand All @@ -105,7 +101,6 @@ readonly I18n:I18nService,
readonly injector:Injector,
readonly apiV3Service:ApiV3Service,
readonly Boards:BoardService,
readonly Banner:BannersService,
readonly boardListCrossSelectionService:BoardListCrossSelectionService,
readonly wpStatesInitialization:WorkPackageStatesInitializationService,
readonly Drag:DragAndDropService,
Expand All @@ -126,10 +121,6 @@ readonly I18n:I18nService,
tap((board) => this.setupQueryUpdatedMonitoring(board)),
);

this.board$.subscribe((board) => {
this.available = this.Banner.allowsTo('board_view') || board.isFree;
});

this.Boards.currentBoard$.next(id);

this.boardListCrossSelectionService
Expand Down
13 changes: 3 additions & 10 deletions modules/boards/app/controllers/boards/boards_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# frozen_string_literal: true

module ::Boards
class BoardsController < BaseController
include Layout
Expand All @@ -11,7 +13,6 @@ class BoardsController < BaseController

before_action :build_board_grid, only: %i[new]
before_action :load_query, only: %i[index]
before_action :ensure_board_type_not_restricted, only: %i[create]

menu_item :boards

Expand Down Expand Up @@ -85,14 +86,6 @@ def build_board_grid
@board_grid = Boards::Grid.new
end

def ensure_board_type_not_restricted
render_403 if restricted_board_type?
end

def restricted_board_type?
!EnterpriseToken.allows_to?(:board_view) && board_grid_params[:attribute] != "basic"
end

def service_call
service_class.new(user: User.current)
.call(
Expand All @@ -114,7 +107,7 @@ def service_class
end

def board_grid_params
params.require(:boards_grid).permit(%i[name attribute])
params.expect(boards_grid: %i[name attribute])
end
end
end
12 changes: 5 additions & 7 deletions modules/boards/app/helpers/boards_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ module BoardsHelper
BoardTypeAttributes = Struct.new(:radio_button_value,
:title,
:description,
:image_path,
:disabled?)
:image_path)

def board_types
[
build_board_type_attributes("basic", "lists", false),
build_board_type_attributes("basic", "lists"),
build_board_type_attributes("status", "status"),
build_board_type_attributes("assignee", "assignees"),
build_board_type_attributes("version", "version"),
Expand All @@ -18,12 +17,11 @@ def board_types
]
end

def build_board_type_attributes(type_name, image_name, disabled = !EnterpriseToken.allows_to?(:board_view))
def build_board_type_attributes(type_name, image_name)
BoardTypeAttributes.new(type_name,
I18n.t("boards.board_type_attributes.#{type_name}"),
I18n.t("boards.board_type_descriptions.#{type_name}"),
"assets/images/board_creation_modal/#{image_name}.svg",
disabled)
"assets/images/board_creation_modal/#{image_name}.svg")
end

def global_board_create_context?
Expand All @@ -35,6 +33,6 @@ def global_board_new_action?
end

def global_board_create_action?
request.path == work_package_boards_path && @project.nil?
request.path == work_package_boards_path && controller.params[:project_id].blank?
end
end
11 changes: 3 additions & 8 deletions modules/boards/app/views/boards/boards/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,17 @@ See COPYRIGHT and LICENSE files for more details.

<div class="form--field -required -align-start">
<label class="form--label" for="board_type"><%= t("boards.label_board_type") %></label>
<div class="form--field-container -enterprise-restricted">
<%=
render(EnterpriseEdition::BannerComponent.new(:board_view))
%>

<div class="form--field-container">
<div class="op-tile-block">
<% board_types.each_with_index do |board_type, tile_number| %>
<label class="op-tile-block--tile form--radio-button-container -wide <%= "-disabled" if board_type.disabled? %>"
<label class="op-tile-block--tile form--radio-button-container -wide"
for="boards_grid_attribute_<%= board_type.radio_button_value %>"
data-test-selector="op-tile-block">
<div class="op-tile-block--content">
<%= styled_radio_button_tag "boards_grid[attribute]",
board_type.radio_button_value,
tile_number == 0,
no_label: true,
disabled: board_type.disabled?,
class: "radio-button" %>
<div>
<span data-test-selector="op-tile-block-title" class="op-tile-block--title">
Expand All @@ -84,7 +79,7 @@ See COPYRIGHT and LICENSE files for more details.
</div>
</div>

<img src="<%= frontend_asset_path board_type.image_path%>"
<img src="<%= frontend_asset_path board_type.image_path %>"
alt=""
class="op-tile-block--image">
</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@

RSpec.describe "Assignee action board",
:js,
:selenium,
with_ee: %i[board_view] do
:selenium do
let(:bobself_user) do
create(:user,
firstname: "Bob",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@

RSpec.describe "Custom field filter in boards",
:js,
:selenium,
with_ee: %i[board_view] do
:selenium do
let(:user) do
create(:user,
member_with_roles: { project => role })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@

RSpec.describe "Status action board",
:js,
:selenium,
with_ee: %i[board_view] do
:selenium do
let(:user) do
create(:user,
member_with_roles: { project => role })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@

RSpec.describe "Status action board",
:js,
:selenium,
with_ee: %i[board_view] do
:selenium do
let(:user) do
create(:user,
member_with_roles: { project => role })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@

RSpec.describe "Subproject action board",
:js,
:selenium,
with_ee: %i[board_view] do
:selenium do
let(:user) do
create(:user,
member_with_roles: { project => role })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
require_relative "../support//board_index_page"
require_relative "../support/board_page"

RSpec.describe "Subtasks action board", :js, :selenium, with_ee: %i[board_view] do
RSpec.describe "Subtasks action board", :js, :selenium do
let(:type) { create(:type_standard) }
let(:project) { create(:project, types: [type], enabled_module_names: %i[work_package_tracking board_view]) }
let(:role) { create(:project_role, permissions:) }
Expand Down
Loading
Loading