Convert wp-list toolbar buttons

pull/6153/head
Oliver Günther 7 years ago
parent 1b00a67988
commit eb3d5f50eb
No known key found for this signature in database
GPG Key ID: 88872239EB414F99
  1. 21
      frontend/app/angular4-modules.ts
  2. 1
      frontend/app/angular4-transition-utils.ts
  3. 1
      frontend/app/components/filters/filter-container/filter-container.directive.html
  4. 23
      frontend/app/components/filters/filter-container/filter-container.directive.ts
  5. 8
      frontend/app/components/routing/wp-list/wp-list.component.ts
  6. 70
      frontend/app/components/routing/wp-list/wp.list.component.html
  7. 16
      frontend/app/components/wp-buttons/wp-button.template.html
  8. 171
      frontend/app/components/wp-buttons/wp-buttons.module.test.ts
  9. 4
      frontend/app/components/wp-buttons/wp-buttons.module.ts
  10. 34
      frontend/app/components/wp-buttons/wp-create-button/wp-create-button.component.ts
  11. 28
      frontend/app/components/wp-buttons/wp-create-button/wp-create-button.directive.html
  12. 48
      frontend/app/components/wp-buttons/wp-create-button/wp-create-button.directive.ts
  13. 26
      frontend/app/components/wp-buttons/wp-create-button/wp-create-button.html
  14. 42
      frontend/app/components/wp-buttons/wp-details-view-button/wp-details-view-button.component.ts
  15. 70
      frontend/app/components/wp-buttons/wp-details-view-button/wp-details-view-button.directive.test.ts
  16. 12
      frontend/app/components/wp-buttons/wp-filter-button/wp-filter-button.directive.html
  17. 116
      frontend/app/components/wp-buttons/wp-filter-button/wp-filter-button.directive.test.ts
  18. 40
      frontend/app/components/wp-buttons/wp-filter-button/wp-filter-button.directive.ts
  19. 12
      frontend/app/components/wp-buttons/wp-filter-button/wp-filter-button.html
  20. 5
      frontend/app/components/wp-buttons/wp-list-view-button/wp-list-view-button.directive.ts
  21. 29
      frontend/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component.ts
  22. 38
      frontend/app/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.html
  23. 84
      frontend/app/components/wp-buttons/wp-view-button/wp-view-button.directive.test.ts
  24. 90
      frontend/app/components/wp-buttons/wp-view-button/wp-view-button.directive.ts
  25. 37
      frontend/app/components/wp-buttons/wp-zen-mode-toggle-button/wp-zen-mode-toggle-button.component.ts
  26. 5
      frontend/app/components/wp-table/wp-table.directive.ts
  27. 17
      frontend/app/templates/components/selectable_title.html

@ -67,15 +67,14 @@ import {WorkPackageTableSumsRowController} from 'core-components/wp-table/wp-tab
import {WorkPackagesTableController,} from 'core-components/wp-table/wp-table.directive';
import {
$qToken,
$rootScopeToken,
$stateToken,
$rootScopeToken, $stateToken,
$timeoutToken,
columnsModalToken,
FocusHelperToken,
halRequestToken,
I18nToken,
NotificationsServiceToken,
PathHelperToken, StateToken,
PathHelperToken,
upgradeService,
upgradeServiceWithToken
} from './angular4-transition-utils';
@ -93,6 +92,13 @@ import {WorkPackageTableSumService} from 'core-components/wp-fast-table/state/wp
import {WorkPackagesListService} from 'core-components/wp-list/wp-list.service';
import {WorkPackagesListChecksumService} from 'core-components/wp-list/wp-list-checksum.service';
import {LoadingIndicatorService} from 'core-components/common/loading-indicator/loading-indicator.service';
import {WorkPackageCreateButtonComponent} from 'core-components/wp-buttons/wp-create-button/wp-create-button.component';
import {WorkPackageFilterButtonComponent} from 'core-components/wp-buttons/wp-filter-button/wp-filter-button.directive';
import {WorkPackageDetailsViewButtonComponent} from 'core-components/wp-buttons/wp-details-view-button/wp-details-view-button.component';
import {WorkPackageTimelineButtonComponent} from 'core-components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.component';
import {WorkPackageZenModeButtonComponent} from 'core-components/wp-buttons/wp-zen-mode-toggle-button/wp-zen-mode-toggle-button.component';
import {WorkPackageFilterContainerComponent} from 'core-components/filters/filter-container/filter-container.directive';
import WorkPackageFiltersService from 'core-components/filters/wp-filters/wp-filters.service';
@NgModule({
imports: [
@ -105,7 +111,7 @@ import {LoadingIndicatorService} from 'core-components/common/loading-indicator/
HideSectionService,
upgradeServiceWithToken('$rootScope', $rootScopeToken),
upgradeServiceWithToken('I18n', I18nToken),
upgradeServiceWithToken('$state', StateToken),
upgradeServiceWithToken('$state', $stateToken),
upgradeServiceWithToken('$q', $qToken),
upgradeServiceWithToken('$timeout', $timeoutToken),
upgradeServiceWithToken('NotificationsService', NotificationsServiceToken),
@ -133,6 +139,7 @@ import {LoadingIndicatorService} from 'core-components/common/loading-indicator/
upgradeService('wpTableSum', WorkPackageTableSumService),
upgradeService('wpListService', WorkPackagesListService),
upgradeService('wpListChecksumService', WorkPackagesListChecksumService),
upgradeService('wpFiltersService', WorkPackageFiltersService),
upgradeService('loadingIndicator', LoadingIndicatorService),
upgradeService('wpTableRelationColumns', WorkPackageTableRelationColumnsService),
upgradeService('wpTableGroupBy', WorkPackageTableGroupByService),
@ -152,6 +159,12 @@ import {LoadingIndicatorService} from 'core-components/common/loading-indicator/
WorkPackageTableTimelineGrid,
WorkPackageTimelineTableController,
WorkPackagesTableController,
WorkPackageCreateButtonComponent,
WorkPackageFilterButtonComponent,
WorkPackageDetailsViewButtonComponent,
WorkPackageTimelineButtonComponent,
WorkPackageZenModeButtonComponent,
WorkPackageFilterContainerComponent,
WpResizerDirectiveUpgraded,
WpCustomActionComponent,
WpCustomActionsComponent,

@ -36,7 +36,6 @@ export const $timeoutToken = new InjectionToken<ITimeoutService>('$timeout');
export const $stateToken = new InjectionToken<StateService>('$state');
export const I18nToken = new InjectionToken<op.I18n>('I18n');
export const StateToken = new InjectionToken<StateService>('$state');
export const columnsModalToken = new InjectionToken<any>('columnsModal');
export const FocusHelperToken = new InjectionToken<any>('FocusHelper');
export const NotificationsServiceToken = new InjectionToken<any>('NotificationsService');

@ -1,5 +1,4 @@
<div class="work-packages--filters-optional-container" ng-show="wpFilters.visible">
<div id="query_form_content" class="hide-when-print">
<query-filters></query-filters>
</div>
</div>

@ -27,18 +27,21 @@
// ++
import {filtersModule} from '../../../angular-modules';
import {Component} from '@angular/core';
import WorkPackageFiltersService from 'core-components/filters/wp-filters/wp-filters.service';
import {downgradeComponent} from '@angular/upgrade/static';
function filterContainerDirective(wpFiltersService:any) {
return {
restrict: 'E',
replace: true,
templateUrl: '/components/filters/filter-container/filter-container.directive.html',
link: (scope:any) => {
scope.wpFilters = wpFiltersService;
@Component({
template: require('!!raw-loader!core-components/filters/filter-container/filter-container.directive.html'),
selector: 'filter-container',
})
export class WorkPackageFilterContainerComponent {
constructor(public wpFiltersService:WorkPackageFiltersService) {
}
};
}
filtersModule.directive('filterContainer', filterContainerDirective);
filtersModule.directive(
'filterContainer',
downgradeComponent({ component: WorkPackageFilterContainerComponent })
);

@ -47,7 +47,7 @@ import {WorkPackagesListChecksumService} from '../../wp-list/wp-list-checksum.se
import {WorkPackagesListService} from '../../wp-list/wp-list.service';
import {WorkPackageTableRefreshService} from '../../wp-table/wp-table-refresh-request.service';
import {WorkPackageTableHierarchiesService} from './../../wp-fast-table/state/wp-table-hierarchy.service';
import {I18nToken, StateToken} from 'core-app/angular4-transition-utils';
import {$stateToken, I18nToken} from 'core-app/angular4-transition-utils';
import {AuthorisationService} from 'core-components/common/model-auth/model-auth.service';
import {downgradeComponent} from '@angular/upgrade/static';
import {TableState} from 'core-components/wp-table/table-state/table-state';
@ -63,7 +63,9 @@ export class WorkPackagesListComponent implements OnInit, OnDestroy {
text = {
'jump_to_pagination': this.I18n.t('js.work_packages.jump_marks.pagination'),
'text_jump_to_pagination': this.I18n.t('js.work_packages.jump_marks.label_pagination')
'text_jump_to_pagination': this.I18n.t('js.work_packages.jump_marks.label_pagination'),
'search_query_title': this.I18n.t('js.toolbar.search_query_title'),
'button_settings': this.I18n.t('js.button_settings')
};
tableInformationLoaded = false;
@ -103,7 +105,7 @@ export class WorkPackagesListComponent implements OnInit, OnDestroy {
readonly wpListService:WorkPackagesListService,
readonly wpListChecksumService:WorkPackagesListChecksumService,
readonly loadingIndicator:LoadingIndicatorService,
@Inject(StateToken) readonly $state:StateService,
@Inject($stateToken) readonly $state:StateService,
@Inject(I18nToken) readonly I18n:op.I18n) {
this.tableState = this.states.globalTable;

@ -1,11 +1,79 @@
<div class="work-packages-list-view--container">
<div class="toolbar-container">
<div class="toolbar">
<div class="title-container">
<div class="text">
<h2>
<span has-dropdown-menu
target="wpQuerySelectService"
collision-container="#content"
locals="selectedTitle">
<accessible-by-keyboard
linkClass="wp-table--query-menu-link"
[linkTitle]="text.search_query_title">
<op-icon
icon-classes="icon-pulldown icon-button icon-small hide-when-print"></op-icon>
{{ selectedTitle | slice:0:50 }}
</accessible-by-keyboard>
</span>
</h2>
</div>
</div>
<ul class="toolbar-items hide-when-print"
*ngIf="tableInformationLoaded">
<li class="toolbar-item">
<wp-create-button
[allowed]="allowed('work_packages', 'createWorkPackage')"
[projectIdentifier]="projectIdentifier"
stateName="work-packages.list.new">
</wp-create-button>
</li>
<li class="toolbar-item hidden-for-mobile">
<wp-filter-button>
</wp-filter-button>
</li>
<li class="toolbar-item hidden-for-mobile">
<wp-details-view-button>
</wp-details-view-button>
</li>
<li class="toolbar-item hidden-for-mobile">
<wp-timeline-toggle-button>
</wp-timeline-toggle-button>
</li>
<li class="toolbar-item hidden-for-mobile">
<wp-zen-mode-toggle-button>
</wp-zen-mode-toggle-button>
</li>
<li class="toolbar-item hidden-for-mobile">
<button id="work-packages-settings-button"
title="{{ text.button_settings }}"
class="button last work-packages-settings-button toolbar-icon"
has-dropdown-menu
target="SettingsDropdownMenu"
locals="query">
<op-icon icon-classes="button--icon icon-show-more"></op-icon>
</button>
</li>
</ul>
</div>
</div>
<filter-container></filter-container>
<accessible-by-keyboard
linkClass="hidden-for-sighted skip-navigation-link"
[linkAriaLabel]="text.text_jump_to_pagination"
(execute)="setAnchorToNextElement()">
<span [textContent]="text.jump_to_pagination"></span>
</accessible-by-keyboard>
<!-- (TABLE + TIMELINE) + DETAILS view -->
<div class="work-packages-split-view">
<!-- (TABLE + TIMELINE) and FOOTER vertical split-->
<div class="work-packages-split-view--tabletimeline-side loading-indicator--location" data-indicator-name="table">
<div class="work-packages-split-view--tabletimeline-side loading-indicator--location"
data-indicator-name="table">
<!-- TABLE + TIMELINE horizontal split -->
<wp-table *ngIf="tableInformationLoaded"

@ -1,9 +1,9 @@
<button id="{{ ::vm.buttonId }}"
class="button {{ ::vm.buttonClass }}"
title="{{ vm.label }}"
ng-click="vm.performAction()"
ng-attr-accesskey="{{ ::vm.accessKey }}"
ng-disabled="vm.disabled || (!vm.isToggle() && vm.isActive())"
ng-class="{ '-active': vm.isActive() }">
<op-icon icon-classes="{{ ::vm.iconClass }} button--icon"></op-icon>
<button class="button {{ buttonClass }}"
[ngClass]="{ '-active': isActive() }"
[disabled]="disabled || (!isToggle() && isActive())"
[attr.id]="buttonId"
[attr.title]="label"
[attr.accesskey]="accessKey"
(click)="performAction()">
<op-icon icon-classes="{{ iconClass }} button--icon"></op-icon>
</button>

@ -1,171 +0,0 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details.
// ++
import {WorkPackageNavigationButtonController} from './wp-buttons.module';
import {StateService} from '@uirouter/angularjs';
var expect = chai.expect;
class GenericWpButtonController extends WorkPackageNavigationButtonController {
public accessKey:number = 1;
public activeState:string = 'some-state.show';
public buttonId:string = 'some-button-id';
public iconClass:string = 'some-icon-class';
constructor(public $state:StateService, public I18n:op.I18n) {
super($state, I18n);
}
public performAction() {
}
public get labelKey():string {
return 'js.some-label';
}
public get textKey():string {
return 'js.some-text';
}
}
describe('WP button directives', () => {
var $state:any, I18n:any, scope:any, label:any, button:any;
var controller:GenericWpButtonController;
before(() => {
angular.module('openproject.wpButtons').directive('genericWpButton', function ():any {
return {
templateUrl: '/components/wp-buttons/wp-button.template.html',
scope: {
disabled: '=?'
},
controller: GenericWpButtonController,
controllerAs: 'vm',
bindToController: true
}
});
});
beforeEach(angular.mock.module('openproject.wpButtons', 'openproject.templates'));
beforeEach(angular.mock.inject(($compile:ng.ICompileService, $rootScope:ng.IRootScopeService,
_$state_:StateService, _I18n_:any) => {
var html = '<generic-wp-button disabled="disabled"></generic-wp-button>';
$state = _$state_;
I18n = _I18n_;
scope = $rootScope.$new();
var element = angular.element(html);
var stub = sinon.stub(I18n, 't');
stub.withArgs('js.some-label').returns('a wonderful title');
stub.withArgs('js.some-text').returns('text');
$compile(element)(scope);
scope.$digest();
controller = element.controller('genericWpButton');
label = element.find('span');
button = element.find('button');
}));
afterEach(() => {
I18n.t.restore();
});
describe('when initial', () => {
it('should have the performAction method', () => {
expect(controller.performAction).not.to.throw(Error);
});
it('should be enabled by default', () => {
expect(controller.disabled).not.to.be.ok;
});
it('should be disabled if disabled attribute is set', () => {
scope.disabled = true;
scope.$digest();
expect(controller.disabled).to.be.true;
});
});
describe('when activeState is set', () => {
var includes:any;
beforeEach(() => {
includes = sinon.stub($state, 'includes');
});
it('should be active if the current state includes the given activeState name', () => {
includes.withArgs(controller.activeState).returns(true);
expect(controller.isActive()).to.be.true;
});
it('should not be active if the current state does not include the activeState name', () => {
includes.returns(false);
expect(controller.isActive()).to.be.false;
});
});
describe('when active', () => {
beforeEach(() => {
sinon.stub(controller, 'isActive').returns(true);
scope.$digest();
});
it('should not have a label with an access key', () => {
expect(button.attr('accesskey')).not.to.eq(controller.activeAccessKey);
});
it("should have the button class set to '-active' ", () => {
expect(button.attr('class')).to.contain('-active')
});
it('should have equal text values', () => {
expect(button.attr('title').trim()).to.eq(controller.label);
});
});
describe('when not active', () => {
it('should have a label with an access key attribute', () => {
expect(parseInt(button.attr('accesskey'))).to.eq(controller.activeAccessKey);
});
it("should have the 'activate' prefix in the text values", () => {
expect(button.attr('title').trim()).to.contain(controller.label);
});
});
});

@ -36,7 +36,7 @@ export interface ButtonControllerText {
buttonText:string;
}
export abstract class WorkPackageButtonController {
export abstract class AbstractWorkPackageButtonComponent {
public disabled:boolean;
public buttonId:string;
public iconClass:string;
@ -91,7 +91,7 @@ export abstract class WorkPackageButtonController {
public abstract performAction():void;
}
export abstract class WorkPackageNavigationButtonController extends WorkPackageButtonController {
export abstract class WorkPackageNavigationButtonComponent extends AbstractWorkPackageButtonComponent {
public activeState:string;
public accessKey:number;

@ -28,22 +28,28 @@
import {wpButtonsModule} from '../../../angular-modules';
import {StateService} from '@uirouter/angularjs';
import {downgradeComponent} from '@angular/upgrade/static'
import {Component, Inject, Input} from '@angular/core';
import {$stateToken, I18nToken} from 'core-app/angular4-transition-utils';
export default class WorkPackageCreateButtonController {
public projectIdentifier:string;
public text:any;
@Component({
template: require('!!raw-loader!./wp-create-button.html'),
selector: 'wp-create-button',
})
export class WorkPackageCreateButtonComponent {
@Input('projectIdentifier') projectIdentifier:string;
@Input('stateName') stateName:string;
@Input('allowed') allowed:boolean;
public types:any;
public stateName:string;
public allowed:boolean;
constructor(protected $state:StateService,
protected I18n:op.I18n) {
this.text = {
createWithDropdown: I18n.t('js.work_packages.create.button'),
createButton: I18n.t('js.label_work_package'),
explanation: I18n.t('js.label_create_work_package')
public text = {
createWithDropdown: this.I18n.t('js.work_packages.create.button'),
createButton: this.I18n.t('js.label_work_package'),
explanation: this.I18n.t('js.label_create_work_package')
};
constructor(@Inject($stateToken) readonly $state:StateService,
@Inject(I18nToken) readonly I18n:op.I18n) {
}
public $onInit() {
@ -59,4 +65,6 @@ export default class WorkPackageCreateButtonController {
}
}
wpButtonsModule.controller('WorkPackageCreateButtonController', WorkPackageCreateButtonController);
wpButtonsModule
.directive('wpCreateButton',
downgradeComponent({component: WorkPackageCreateButtonComponent}));

@ -1,28 +0,0 @@
<div class="wp-create-button">
<button class="button -alt-highlight add-work-package"
ng-if="$ctrl.projectIdentifier"
has-dropdown-menu
target="TypesContextMenu"
ng-init="projectIdentifier = $ctrl.projectIdentifier; stateName = $ctrl.stateName"
locals="projectIdentifier, stateName"
ng-disabled="$ctrl.isDisabled()"
aria-label="{{ ::$ctrl.text.explanation }}">
<op-icon icon-classes="button--icon icon-add"></op-icon>
<span class="button--text"
ng-bind="::$ctrl.text.createWithDropdown"
aria-hidden="true"></span>
<op-icon icon-classes="button--icon icon-small icon-pulldown"></op-icon>
</button>
<button class="button -alt-highlight add-work-package"
ng-if="!$ctrl.projectIdentifier"
ng-click="$ctrl.createWorkPackage()"
ng-disabled="$ctrl.isDisabled()"
aria-label="{{ ::$ctrl.text.explanation }}">
<op-icon icon-classes="button--icon icon-add"></op-icon>
<span class="button--text"
ng-bind="::$ctrl.text.createButton"
aria-hidden="true"></span>
</button>
</div>

@ -1,48 +0,0 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details.
// ++
import {wpButtonsModule} from '../../../angular-modules';
function wpCreateButton() {
return {
restrict: 'E',
templateUrl: '/components/wp-buttons/wp-create-button/wp-create-button.directive.html',
scope: {
projectIdentifier: '=',
allowed: '=',
stateName: '@'
},
bindToController: true,
controllerAs: '$ctrl',
controller: 'WorkPackageCreateButtonController'
}
}
wpButtonsModule.directive('wpCreateButton', wpCreateButton);

@ -0,0 +1,26 @@
<div class="wp-create-button">
<button class="button -alt-highlight add-work-package"
*ngIf="projectIdentifier"
[disabled]="isDisabled()"
[attr.aria-label]="text.explanation"
hasDropdownMenu
[hasDropdownMenu-locals]="{'projectIdentifier': projectIdentifier, 'stateName': stateName}"
[hasDropdownMenu-target]="'TypesContextMenu'">
<op-icon icon-classes="button--icon icon-add"></op-icon>
<span class="button--text"
[textContent]="text.createWithDropdown"
aria-hidden="true"></span>
<op-icon icon-classes="button--icon icon-small icon-pulldown"></op-icon>
</button>
<button class="button -alt-highlight add-work-package"
*ngIf="!projectIdentifier"
(click)="createWorkPackage()"
[disabled]="isDisabled()"
[attr.aria-label]="text.explanation">
<op-icon icon-classes="button--icon icon-add"></op-icon>
<span class="button--text"
[textContent]="text.createButton"
aria-hidden="true"></span>
</button>
</div>

@ -27,18 +27,24 @@
// ++
import {wpButtonsModule} from '../../../angular-modules';
import {WorkPackageButtonController, wpButtonDirective} from '../wp-buttons.module';
import {KeepTabService} from '../../wp-panels/keep-tab/keep-tab.service';
import {States} from '../../states.service';
import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service';
import {StateService} from '@uirouter/angularjs';
export class WorkPackageDetailsViewButtonController extends WorkPackageButtonController {
import {Component, Inject} from '@angular/core';
import {AbstractWorkPackageButtonComponent} from 'core-components/wp-buttons/wp-buttons.module';
import {$stateToken, I18nToken} from 'core-app/angular4-transition-utils';
import {downgradeComponent} from '@angular/upgrade/static';
@Component({
template: require('!!raw-loader!core-components/wp-buttons/wp-button.template.html'),
selector: 'wp-details-view-button',
})
export class WorkPackageDetailsViewButtonComponent extends AbstractWorkPackageButtonComponent {
public projectIdentifier:string;
public accessKey:number = 8;
public activeState:string = 'work-packages.list.details';
public listState: string = 'work-packages.list';
public listState:string = 'work-packages.list';
public buttonId:string = 'work-packages-details-view-button';
public buttonClass:string = 'toolbar-icon';
public iconClass:string = 'icon-info2';
@ -47,13 +53,12 @@ export class WorkPackageDetailsViewButtonController extends WorkPackageButtonCon
public deactivateLabel:string;
constructor(
public $state:StateService,
@Inject($stateToken) readonly $state:StateService,
@Inject(I18nToken) readonly I18n:op.I18n,
public states:States,
public I18n:op.I18n,
public loadingIndicator:any,
public wpTableFocus:WorkPackageTableFocusService,
public keepTab:KeepTabService) {
'ngInject';
super(I18n);
this.activateLabel = I18n.t('js.button_open_details');
@ -100,20 +105,11 @@ export class WorkPackageDetailsViewButtonController extends WorkPackageButtonCon
};
angular.extend(params, this.$state.params);
this.loadingIndicator.mainPage = this.$state.go.apply(
this.$state, [this.keepTab.currentDetailsState, params]);
this.$state.go(this.keepTab.currentDetailsState, params);
}
}
function wpDetailsViewButton() {
return wpButtonDirective({
scope: {
projectIdentifier: '=?'
},
controller: WorkPackageDetailsViewButtonController,
});
}
wpButtonsModule.directive('wpDetailsViewButton', wpDetailsViewButton);
wpButtonsModule.directive(
'wpDetailsViewButton',
downgradeComponent({ component: WorkPackageDetailsViewButtonComponent })
);

@ -1,70 +0,0 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details.
// ++
import {WorkPackageDetailsViewButtonController} from './wp-details-view-button.directive';
import {KeepTabService} from '../../wp-panels/keep-tab/keep-tab.service';
var expect = chai.expect;
describe('wpListViewButton directive', () => {
var $state:any, scope:any;
var keepTab:KeepTabService;
var controller:WorkPackageDetailsViewButtonController;
beforeEach(angular.mock.module('openproject.wpButtons', 'openproject.templates',
'openproject.config'));
beforeEach(angular.mock.inject(($compile:any, $rootScope:any, _$state_:any, _keepTab_:any) => {
var html = '<wp-details-view-button></wp-details-view-button>';
var element = angular.element(html);
$state = _$state_;
keepTab = _keepTab_;
scope = $rootScope.$new();
$compile(element)(scope);
scope.$digest();
controller = element.controller('wpDetailsViewButton');
}));
describe('when using openDetailsView()', () => {
var go:any;
beforeEach(() => {
go = sinon.stub($state, 'go');
controller.openDetailsView();
});
it("should redirect user to 'work-packages.list'", () => {
expect(go.withArgs(keepTab.currentDetailsState).calledOnce).to.be.true;
});
});
});

@ -1,12 +0,0 @@
<button id="{{ ::vm.buttonId }}"
class="button"
title="{{ vm.label }}"
ng-click="vm.performAction()"
ng-attr-accesskey="{{ ::vm.accessKey }}"
ng-disabled="vm.disabled"
ng-class="{ '-active': vm.isActive() }"
aria-label="{{ vm.label }}">
<op-icon icon-classes="{{ ::vm.iconClass }} button--icon"></op-icon>
<span class="button--text" ng-bind="::vm.buttonText"></span>
<span class="badge -secondary" ng-if="vm.initialized">{{ vm.filterCount }}</span>
</button>

@ -1,116 +0,0 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details.
// ++
import {WorkPackageFilterButtonController} from './wp-filter-button.directive';
var expect = chai.expect;
describe('wpFilterButton directive', () => {
var scope:ng.IScope;
var element:ng.IAugmentedJQuery;
var controller:WorkPackageFilterButtonController;
var state:any;
var subscribe:Function;
var compile:any;
beforeEach(angular.mock.module(
'openproject.wpButtons',
'openproject.templates'
));
let doCompile = () => {
compile(element)(scope);
scope.$apply();
controller = element.controller('wpFilterButton');
}
beforeEach(angular.mock.module('openproject.services', function($provide:any) {
var wpTableFilters = {
observeOnScope: function(scope:ng.IScope) {
return {
subscribe: subscribe
}
}
};
$provide.constant('wpTableFilters', wpTableFilters);
}));
beforeEach(angular.mock.inject(($compile:any, $rootScope:ng.IScope) => {
var html = '<wp-filter-button></wp-filter-button>';
element = angular.element(html);
scope = $rootScope.$new();
compile = $compile;
state = {
current: ['mock', 'mock', 'mock']
}
subscribe = function(callback:Function) {
callback(state);
}
}));
describe('when getting the filterCount', () => {
it('returns the length of the current array', () => {
doCompile();
expect(controller.filterCount).to.eq(state.current.length);
});
});
describe('initialized', () => {
it('is true', () => {
doCompile();
expect(controller.initialized).to.eq(true);
});
describe('when not having received a message yet', () => {
it('is false', () => {
subscribe = function(callback:Function) {
//do nothing
}
doCompile();
expect(controller.initialized).to.eq(false);
});
});
});
describe('badge element', () => {
it ('is the length of the current array', () => {
doCompile();
expect(element.find('.badge').text()).to.eq(state.current.length.toString());
});
});
});

@ -27,19 +27,26 @@
// ++
import {wpButtonsModule} from '../../../angular-modules';
import {WorkPackageButtonController, wpButtonDirective} from '../wp-buttons.module';
import WorkPackageFiltersService from "../../filters/wp-filters/wp-filters.service";
import {WorkPackageTableFiltersService} from '../../wp-fast-table/state/wp-table-filters.service';
export class WorkPackageFilterButtonController extends WorkPackageButtonController {
import {AbstractWorkPackageButtonComponent} from 'core-components/wp-buttons/wp-buttons.module';
import {I18nToken} from 'core-app/angular4-transition-utils';
import {Component, Inject, OnDestroy} from '@angular/core';
import {downgradeComponent} from '@angular/upgrade/static';
import WorkPackageFiltersService from 'core-components/filters/wp-filters/wp-filters.service';
import {componentDestroyed} from 'ng2-rx-componentdestroyed';
@Component({
template: require('!!raw-loader!./wp-filter-button.html'),
selector: 'wp-filter-button',
})
export class WorkPackageFilterButtonComponent extends AbstractWorkPackageButtonComponent implements OnDestroy {
public count:number;
public initialized:boolean = false;
public buttonId:string = 'work-packages-filter-toggle-button';
public iconClass:string = 'icon-filter';
constructor(public I18n:op.I18n,
private $scope:ng.IScope,
constructor(@Inject(I18nToken) readonly I18n:op.I18n,
protected wpFiltersService:WorkPackageFiltersService,
protected wpTableFilters:WorkPackageTableFiltersService) {
'ngInject';
@ -49,6 +56,10 @@ export class WorkPackageFilterButtonController extends WorkPackageButtonControll
this.setupObserver();
}
ngOnDestroy():void {
// Empty
}
public get labelKey():string {
return 'js.button_filter';
}
@ -70,7 +81,7 @@ export class WorkPackageFilterButtonController extends WorkPackageButtonControll
}
public performAction() {
this.toggleVisibility()
this.toggleVisibility();
}
public toggleVisibility() {
@ -78,18 +89,17 @@ export class WorkPackageFilterButtonController extends WorkPackageButtonControll
}
private setupObserver() {
this.wpTableFilters.observeOnScope(this.$scope).subscribe(state => {
this.wpTableFilters
.observeUntil(componentDestroyed(this))
.subscribe(state => {
this.count = state.current.length;
this.initialized = true;
});
}
}
function wpFilterButton():ng.IDirective {
return wpButtonDirective({
templateUrl: '/components/wp-buttons/wp-filter-button/wp-filter-button.directive.html',
controller: WorkPackageFilterButtonController
});
}
wpButtonsModule.directive(
'wpFilterButton',
downgradeComponent({ component: WorkPackageFilterButtonComponent })
);
wpButtonsModule.directive('wpFilterButton', wpFilterButton);

@ -0,0 +1,12 @@
<button class="button"
[attr.id]="buttonId"
[attr.accesskey]="accessKey"
[attr.title]="label"
[attr.aria-label]="label"
[disabled]="disabled"
(click)="performAction()"
[ngClass]="{ '-active': isActive() }">
<op-icon icon-classes="{{ iconClass }} button--icon"></op-icon>
<span class="button--text" [textContent]="buttonText"></span>
<span class="badge -secondary" *ngIf="initialized" [textContent]="filterCount"></span>
</button>

@ -27,10 +27,11 @@
// ++
import {wpButtonsModule} from '../../../angular-modules';
import {WorkPackageNavigationButtonController, wpButtonDirective} from '../wp-buttons.module';
import {wpButtonDirective} from '../wp-buttons.module';
import {StateService} from '@uirouter/angularjs';
import {WorkPackageNavigationButtonComponent} from 'core-components/wp-buttons/wp-buttons.module';
export class WorkPackageListViewButtonController extends WorkPackageNavigationButtonController {
export class WorkPackageListViewButtonController extends WorkPackageNavigationButtonComponent {
public projectIdentifier:number;
public accessKey:number = 8;

@ -29,7 +29,10 @@
import {wpButtonsModule} from '../../../angular-modules';
import {TimelineZoomLevel} from '../../api/api-v3/hal-resources/query-resource.service';
import {WorkPackageTableTimelineService} from '../../wp-fast-table/state/wp-table-timeline.service';
import {ButtonControllerText, WorkPackageButtonController, wpButtonDirective} from '../wp-buttons.module';
import {AbstractWorkPackageButtonComponent, ButtonControllerText} from '../wp-buttons.module';
import {Component, Inject} from '@angular/core';
import {I18nToken} from 'core-app/angular4-transition-utils';
import {downgradeComponent} from '@angular/upgrade/static';
interface TimelineButtonText extends ButtonControllerText {
zoomOut:string;
@ -37,7 +40,11 @@ interface TimelineButtonText extends ButtonControllerText {
zoomAuto:string;
}
export class WorkPackageTimelineButtonController extends WorkPackageButtonController {
@Component({
template: require('!!raw-loader!core-components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.html'),
selector: 'wp-timeline-toggle-button',
})
export class WorkPackageTimelineButtonComponent extends AbstractWorkPackageButtonComponent {
public buttonId:string = 'work-packages-timeline-toggle-button';
public iconClass:string = 'icon-view-timeline';
@ -49,8 +56,8 @@ export class WorkPackageTimelineButtonController extends WorkPackageButtonContro
public minZoomLevel:TimelineZoomLevel = 'days';
public maxZoomLevel:TimelineZoomLevel = 'years';
constructor(public I18n:op.I18n, public wpTableTimeline:WorkPackageTableTimelineService) {
'ngInject';
constructor(@Inject(I18nToken) readonly I18n:op.I18n,
public wpTableTimeline:WorkPackageTableTimelineService) {
super(I18n);
this.activateLabel = I18n.t('js.timelines.button_activate');
@ -105,15 +112,9 @@ export class WorkPackageTimelineButtonController extends WorkPackageButtonContro
public getAutoZoomToggleClass():string {
return this.isAutoZoomEnabled() ? '-disabled' : '';
}
}
function wpTimelineToggleButton():ng.IDirective {
return wpButtonDirective({
require: '^wpTimelineContainer',
templateUrl: '/components/wp-buttons/wp-timeline-toggle-button/wp-timeline-toggle-button.html',
controller: WorkPackageTimelineButtonController
});
}
wpButtonsModule.directive('wpTimelineToggleButton', wpTimelineToggleButton);
wpButtonsModule.directive(
'wpTimelineToggleButton',
downgradeComponent({ component: WorkPackageTimelineButtonComponent })
);

@ -1,44 +1,44 @@
<ul id="work-packages-timeline-mode-selection"
class="toolbar-button-group">
<li ng-if="vm.isActive()">
<li *ngIf="isActive()">
<button id="work-packages-timeline-zoom-auto-button"
class="button timeline-toolbar--button toolbar-icon"
ng-class="vm.getAutoZoomToggleClass()"
title="{{ vm.text.zoomAuto }}"
ng-click="vm.toggleAutoZoom()">
[ngClass]="getAutoZoomToggleClass()"
[attr.title]="text.zoomAuto"
(click)="toggleAutoZoom()">
<op-icon icon-classes="icon-zoom-auto button--icon"></op-icon>
</button>
</li>
<li ng-if="vm.isActive()">
<li *ngIf="isActive()">
<button id="work-packages-timeline-zoom-out-button"
class="button timeline-toolbar--button toolbar-icon"
title="{{ vm.text.zoomOut }}"
ng-disabled="vm.currentZoom == vm.maxZoomLevel"
ng-click="vm.updateZoomWithDelta(1)">
[attr.title]="text.zoomOut"
[disabled]="currentZoom == maxZoomLevel"
(click)="updateZoomWithDelta(1)">
<op-icon icon-classes="icon-zoom-out button--icon"></op-icon>
</button>
</li>
<li ng-if="vm.isActive()">
<li *ngIf="isActive()">
<button id="work-packages-timeline-zoom-in-button"
class="button timeline-toolbar--button toolbar-icon"
title="{{ vm.text.zoomIn }}"
ng-disabled="vm.currentZoom == vm.minZoomLevel"
ng-click="vm.updateZoomWithDelta(-1)">
[attr.title]="text.zoomIn"
[disabled]="currentZoom == minZoomLevel"
(click)="updateZoomWithDelta(-1)">
<op-icon icon-classes="icon-zoom-in button--icon"></op-icon>
</button>
</li>
<li>
<button id="{{ ::vm.buttonId }}"
class="button timeline-toolbar--button toolbar-icon"
title="{{ vm.label }}"
ng-click="vm.toggleTimeline()"
ng-disabled="vm.disabled || (!vm.isToggle() && vm.isActive())"
ng-class="{ '-active': vm.isActive() }">
<op-icon icon-classes="{{ ::vm.iconClass }} button--icon"></op-icon>
<button class="button timeline-toolbar--button toolbar-icon"
[ngClass]="{ '-active': isActive() }"
[attr.id]="buttonId"
[attr.title]="label"
[disabled]="disabled || (!isToggle() && isActive())"
(click)="toggleTimeline()">
<op-icon icon-classes="{{ iconClass }} button--icon"></op-icon>
</button>
</li>

@ -1,84 +0,0 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details.
// ++
import {WorkPackageViewButtonController} from './wp-view-button.directive';
import {StateService} from '@uirouter/angularjs';
var expect = chai.expect;
describe('wpViewButton directive', () => {
var $state:any, scope:any;
var controller:WorkPackageViewButtonController;
beforeEach(angular.mock.module(
'openproject.wpButtons', 'openproject.templates', 'openproject.config'));
beforeEach(angular.mock.inject(($compile:ng.ICompileService, $rootScope:ng.IRootScopeService,
_$state_:StateService) => {
var html = '<wp-view-button next-wp-func-="nextWp"' +
' work-package-id="workPackageId"></wp-view-button>';
var element = angular.element(html);
$state = _$state_;
scope = $rootScope.$new();
$compile(element)(scope);
scope.$digest();
controller = element.controller('wpViewButton');
}));
describe('openWorkPackageShowView()', () => {
var sGo:any, sIs:any;
beforeEach(() => {
sGo = sinon.stub($state, 'go');
sIs = sinon.stub($state, 'is');
});
it('should redirect to work-packages.show by default', () => {
scope.workPackageId = 123;
scope.$digest();
controller.openWorkPackageShowView();
expect(sGo.calledWith('work-packages.show.activity')).to.be.true;
});
it('should redirect to show create when in list create', () => {
sIs.withArgs('work-packages.list.new').returns(true);
$state.params.type = 'something';
controller.openWorkPackageShowView();
expect(sGo.calledWith('work-packages.new', $state.params)).to.be.true;
});
});
});

@ -1,90 +0,0 @@
// -- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 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-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 doc/COPYRIGHT.rdoc for more details.
// ++
import {wpButtonsModule} from '../../../angular-modules';
import {WorkPackageNavigationButtonController, wpButtonDirective} from '../wp-buttons.module';
import {KeepTabService} from '../../wp-panels/keep-tab/keep-tab.service';
import {States} from '../../states.service';
import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service';
import {StateService} from '@uirouter/angularjs';
export class WorkPackageViewButtonController extends WorkPackageNavigationButtonController {
public workPackageId:number;
public accessKey:number = 9;
public activeState:string = 'work-packages.show';
public buttonId:string = 'work-packages-show-view-button';
public iconClass:string = 'icon-view-fullscreen';
constructor(
public $state:StateService,
public states:States,
public I18n:op.I18n,
public wpTableFocus:WorkPackageTableFocusService,
public keepTab:KeepTabService) {
'ngInject';
super($state, I18n);
}
public get labelKey():string {
return 'js.button_show_view';
}
public performAction() {
this.openWorkPackageShowView();
}
public openWorkPackageShowView() {
let args:any = ['work-packages.new', this.$state.params];
let id = this.$state.params['workPackageId'] || this.workPackageId || this.wpTableFocus.focusedWorkPackage;
if (!this.$state.is('work-packages.list.new')) {
let params = {
workPackageId: id
};
args = [this.keepTab.currentShowState, params];
angular.extend(params, this.$state.params);
}
this.$state.go.apply(this.$state, args);
}
}
function wpViewButton():ng.IDirective {
return wpButtonDirective({
scope: {
workPackageId: '=?',
},
controller: WorkPackageViewButtonController,
});
}
wpButtonsModule.directive('wpViewButton', wpViewButton);

@ -27,11 +27,18 @@
// ++
import {wpButtonsModule} from '../../../angular-modules';
import {WorkPackageButtonController, wpButtonDirective} from '../wp-buttons.module';
import {AbstractWorkPackageButtonComponent,} from '../wp-buttons.module';
import {Component, Inject} from '@angular/core';
import {I18nToken} from 'core-app/angular4-transition-utils';
import {downgradeComponent} from '@angular/upgrade/static';
const screenfull:any = require('screenfull/dist/screenfull.js');
export class WorkPackageZenModeButtonController extends WorkPackageButtonController {
@Component({
template: require('!!raw-loader!core-components/wp-buttons/wp-button.template.html'),
selector: 'wp-zen-mode-toggle-button',
})
export class WorkPackageZenModeButtonComponent extends AbstractWorkPackageButtonComponent {
public buttonId:string = 'work-packages-zen-mode-toggle-button';
public buttonClass:string = 'toolbar-icon';
public iconClass:string = 'icon-zen-mode';
@ -42,9 +49,9 @@ export class WorkPackageZenModeButtonController extends WorkPackageButtonControl
private deactivateLabel:string;
private scope:ng.IScope;
constructor(public I18n:op.I18n, protected $scope:ng.IScope) {
constructor(@Inject(I18nToken) readonly I18n:op.I18n) {
super(I18n);
this.scope = $scope;
this.activateLabel = I18n.t('js.zen_mode.button_activate');
this.deactivateLabel = I18n.t('js.zen_mode.button_deactivate');
let self = this;
@ -55,9 +62,6 @@ export class WorkPackageZenModeButtonController extends WorkPackageButtonControl
// fullscreen mode.
if (!screenfull.isFullscreen) {
self.deactivateZenMode();
// The event wasn't cached from angularJS so we need to make sure
// a rendering cycle gets triggered:
self.scope.$apply();
}
});
}
@ -76,11 +80,11 @@ export class WorkPackageZenModeButtonController extends WorkPackageButtonControl
}
public isActive():boolean {
return WorkPackageZenModeButtonController.inZenMode;
return WorkPackageZenModeButtonComponent.inZenMode;
}
private deactivateZenMode():void {
WorkPackageZenModeButtonController.inZenMode = false;
WorkPackageZenModeButtonComponent.inZenMode = false;
angular.element('body').removeClass('zen-mode');
this.disabled = false;
if (screenfull.enabled && screenfull.isFullscreen) {
@ -89,7 +93,7 @@ export class WorkPackageZenModeButtonController extends WorkPackageButtonControl
}
private activateZenMode():void {
WorkPackageZenModeButtonController.inZenMode = true;
WorkPackageZenModeButtonComponent.inZenMode = true;
angular.element('body').addClass('zen-mode');
if (screenfull.enabled) {
screenfull.request();
@ -97,7 +101,7 @@ export class WorkPackageZenModeButtonController extends WorkPackageButtonControl
}
public performAction() {
if (WorkPackageZenModeButtonController.inZenMode) {
if (WorkPackageZenModeButtonComponent.inZenMode) {
this.deactivateZenMode();
} else {
this.activateZenMode();
@ -105,10 +109,7 @@ export class WorkPackageZenModeButtonController extends WorkPackageButtonControl
}
}
function wpZenModeToggleButton():ng.IDirective {
return wpButtonDirective({
controller: WorkPackageZenModeButtonController
});
}
wpButtonsModule.directive('wpZenModeToggleButton', wpZenModeToggleButton);
wpButtonsModule.directive(
'wpZenModeToggleButton',
downgradeComponent({ component: WorkPackageZenModeButtonComponent })
);

@ -195,8 +195,3 @@ export class WorkPackagesTableController implements OnInit, OnDestroy {
return [$tableSide[0], $timelineSide[0]];
}
}
angular
.module('openproject.workPackages.directives')
.directive('wpTable',
downgradeComponent({component: WorkPackagesTableController}));

@ -1,17 +0,0 @@
<div class="title-container">
<div class="text">
<h2>
<span has-dropdown-menu
target="wpQuerySelectService"
collision-container="#content"
locals="selectedTitle">
<accessible-by-keyboard
link-class="wp-table--query-menu-link"
link-title="{{ I18n.t('js.toolbar.search_query_title') }}" >
<op-icon icon-classes="icon-pulldown icon-button icon-small hide-when-print"></op-icon>
{{ selectedTitle | characters:50 }}
</accessible-by-keyboard>
</span>
</h2>
</div>
</div>
Loading…
Cancel
Save