Convert wp-details toolbar => wp-split-view toolbar

pull/6179/head
Oliver Günther 7 years ago
parent 062e6d99f0
commit a27212a424
No known key found for this signature in database
GPG Key ID: 88872239EB414F99
  1. 9
      frontend/app/angular4-modules.ts
  2. 1
      frontend/app/angular4-transition-utils.ts
  3. 2
      frontend/app/components/routing/wp-split-view/wp-split-view.html
  4. 65
      frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts
  5. 7
      frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.directive.html
  6. 11
      frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.html
  7. 30
      frontend/app/components/wp-details/wp-details-toolbar-ng1-wrapper.ts
  8. 55
      frontend/app/components/wp-details/wp-details-toolbar.component.ts
  9. 16
      frontend/app/components/wp-details/wp-details-toolbar.directive.html
  10. 2
      frontend/app/components/wp-details/wp-details-toolbar.directive.test.ts
  11. 15
      frontend/app/components/wp-details/wp-details-toolbar.html

@ -77,7 +77,7 @@ import {
NotificationsServiceToken, NotificationsServiceToken,
PathHelperToken, PathHelperToken,
upgradeService, upgradeService,
upgradeServiceWithToken upgradeServiceWithToken, wpMoreMenuServiceToken
} from './angular4-transition-utils'; } from './angular4-transition-utils';
import {WpCustomActionComponent} from 'core-components/wp-custom-actions/wp-custom-actions/wp-custom-action.component'; import {WpCustomActionComponent} from 'core-components/wp-custom-actions/wp-custom-actions/wp-custom-action.component';
import {WpCustomActionsComponent} from 'core-components/wp-custom-actions/wp-custom-actions.component'; import {WpCustomActionsComponent} from 'core-components/wp-custom-actions/wp-custom-actions.component';
@ -104,7 +104,6 @@ import {Ng1QueryFiltersComponentWrapper} from 'core-components/filters/query-fil
import {UIRouterUpgradeModule} from '@uirouter/angular-hybrid'; import {UIRouterUpgradeModule} from '@uirouter/angular-hybrid';
import {WorkPackageSplitViewComponent} from 'core-components/routing/wp-split-view/wp-split-view.component'; import {WorkPackageSplitViewComponent} from 'core-components/routing/wp-split-view/wp-split-view.component';
import {WorkPackageBreadcrumbComponent} from 'core-components/work-packages/wp-breadcrumb/wp-breadcrumb.component'; import {WorkPackageBreadcrumbComponent} from 'core-components/work-packages/wp-breadcrumb/wp-breadcrumb.component';
import {Ng1DetailsToolbarWrapper} from 'core-components/wp-details/wp-details-toolbar-ng1-wrapper';
import {WorkPackageRelationsCountComponent} from 'core-components/work-packages/wp-relations-count/wp-relations-count.component'; import {WorkPackageRelationsCountComponent} from 'core-components/work-packages/wp-relations-count/wp-relations-count.component';
import {FirstRouteService} from 'core-components/routing/first-route-service'; import {FirstRouteService} from 'core-components/routing/first-route-service';
import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; import {PathHelperService} from 'core-components/common/path-helper/path-helper.service';
@ -113,6 +112,8 @@ import {WorkPackageEditFieldGroupDirective} from 'core-components/wp-edit/wp-edi
import {ConfigurationService} from 'core-components/common/config/configuration.service'; import {ConfigurationService} from 'core-components/common/config/configuration.service';
import {WorkPackageEditFieldComponent} from 'core-components/wp-edit/wp-edit-field/wp-edit-field.component'; import {WorkPackageEditFieldComponent} from 'core-components/wp-edit/wp-edit-field/wp-edit-field.component';
import {WorkPackageCreateService} from 'core-components/wp-create/wp-create.service'; import {WorkPackageCreateService} from 'core-components/wp-create/wp-create.service';
import {WorkPackageWatcherButtonComponent} from 'core-components/work-packages/wp-watcher-button/wp-watcher-button.component';
import {WorkPackageSplitViewToolbarComponent} from 'core-components/wp-details/wp-details-toolbar.component';
@NgModule({ @NgModule({
imports: [ imports: [
@ -134,6 +135,7 @@ import {WorkPackageCreateService} from 'core-components/wp-create/wp-create.serv
upgradeServiceWithToken('FocusHelper', FocusHelperToken), upgradeServiceWithToken('FocusHelper', FocusHelperToken),
upgradeServiceWithToken('PathHelper', PathHelperToken), upgradeServiceWithToken('PathHelper', PathHelperToken),
upgradeServiceWithToken('halRequest', halRequestToken), upgradeServiceWithToken('halRequest', halRequestToken),
upgradeServiceWithToken('wpMoreMenuService', wpMoreMenuServiceToken),
upgradeService('wpRelations', WorkPackageRelationsService), upgradeService('wpRelations', WorkPackageRelationsService),
upgradeService('wpCacheService', WorkPackageCacheService), upgradeService('wpCacheService', WorkPackageCacheService),
upgradeService('wpEditing', WorkPackageEditingService), upgradeService('wpEditing', WorkPackageEditingService),
@ -202,8 +204,9 @@ import {WorkPackageCreateService} from 'core-components/wp-create/wp-create.serv
WorkPackageRelationsCountComponent, WorkPackageRelationsCountComponent,
WorkPackageBreadcrumbComponent, WorkPackageBreadcrumbComponent,
WorkPackageEditFieldGroupDirective, WorkPackageEditFieldGroupDirective,
WorkPackageSplitViewToolbarComponent,
WorkPackageWatcherButtonComponent,
WorkPackageSubjectComponent, WorkPackageSubjectComponent,
Ng1DetailsToolbarWrapper,
// WP Edit Fields // WP Edit Fields
WorkPackageEditFieldComponent, WorkPackageEditFieldComponent,

@ -42,6 +42,7 @@ export const NotificationsServiceToken = new InjectionToken<any>('NotificationsS
export const v3PathToken = new InjectionToken<any>('v3Path'); export const v3PathToken = new InjectionToken<any>('v3Path');
export const PathHelperToken = new InjectionToken<any>('PathHelper'); export const PathHelperToken = new InjectionToken<any>('PathHelper');
export const halRequestToken = new InjectionToken<any>('halRequest'); export const halRequestToken = new InjectionToken<any>('halRequest');
export const wpMoreMenuServiceToken = new InjectionToken<any>('wpMoreMenuService');
export const $httpToken = new InjectionToken<any>('$http'); export const $httpToken = new InjectionToken<any>('$http');
export const halResourceFactoryToken = new InjectionToken<any>('halResourceFactory'); export const halResourceFactoryToken = new InjectionToken<any>('halResourceFactory');

@ -54,7 +54,7 @@
</div> </div>
<div class="work-packages--details-toolbar-container" *ngIf="workPackage"> <div class="work-packages--details-toolbar-container" *ngIf="workPackage">
<ng1-wp-details-toolbar-wrapper [workPackage]="workPackage"></ng1-wp-details-toolbar-wrapper> <wp-details-toolbar [workPackage]="workPackage"></wp-details-toolbar>
</div> </div>
<div class="work-packages--details--resizer hidden-for-mobile hide-when-print"> <div class="work-packages--details--resizer hidden-for-mobile hide-when-print">

@ -26,35 +26,47 @@
// See doc/COPYRIGHT.rdoc for more details. // See doc/COPYRIGHT.rdoc for more details.
// ++ // ++
import {wpDirectivesModule} from '../../../angular-modules';
import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service';
import {WorkPackageCacheService} from '../work-package-cache.service';
import {Component, Inject, Input, OnDestroy, OnInit} from '@angular/core';
import {I18nToken} from 'core-app/angular4-transition-utils';
import {componentDestroyed} from 'ng2-rx-componentdestroyed';
import {downgradeComponent} from '@angular/upgrade/static';
@Component({
template: require('!!raw-loader!./wp-watcher-button.html'),
selector: 'wp-watcher-button',
})
export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy {
@Input('workPackage') public workPackage:WorkPackageResourceInterface;
@Input('showText') public showText:boolean = false;
@Input('disabled') public disabled:boolean = false;
import {wpDirectivesModule} from "../../../angular-modules";
import {scopedObservable} from "../../../helpers/angular-rx-utils";
import {WorkPackageResourceInterface} from "../../api/api-v3/hal-resources/work-package-resource.service";
import {WorkPackageCacheService} from "../work-package-cache.service";
export class WorkPackageWatcherButtonController {
public workPackage:WorkPackageResourceInterface;
public buttonText:string; public buttonText:string;
public buttonTitle:string; public buttonTitle:string;
public buttonClass:string; public buttonClass:string;
public buttonId:string; public buttonId:string;
public watchIconClass:string; public watchIconClass:string;
constructor(public $scope:ng.IScope, constructor(@Inject(I18nToken) readonly I18n:op.I18n,
public $rootScope:ng.IRootScopeService,
public I18n:op.I18n,
public wpCacheService:WorkPackageCacheService) { public wpCacheService:WorkPackageCacheService) {
}
scopedObservable( ngOnInit() {
$scope, this.wpCacheService.loadWorkPackage(this.workPackage.id)
wpCacheService.loadWorkPackage(this.workPackage.id).values$()) .values$()
.takeUntil(componentDestroyed(this))
.subscribe((wp: WorkPackageResourceInterface) => { .subscribe((wp: WorkPackageResourceInterface) => {
this.workPackage = wp; this.workPackage = wp;
this.setWatchStatus(); this.setWatchStatus();
}); });
} }
ngOnDestroy() {
// Nothing to do
}
public get isWatched() { public get isWatched() {
return this.workPackage.hasOwnProperty('unwatch'); return this.workPackage.hasOwnProperty('unwatch');
} }
@ -69,7 +81,7 @@ export class WorkPackageWatcherButtonController {
toggleLink(toggleLink.$link.payload).then(() => { toggleLink(toggleLink.$link.payload).then(() => {
this.wpCacheService.loadWorkPackage(this.workPackage.id, true); this.wpCacheService.loadWorkPackage(this.workPackage.id, true);
}); });
}; }
public nextStateLink() { public nextStateLink() {
const linkName = this.isWatched ? 'unwatch' : 'watch'; const linkName = this.isWatched ? 'unwatch' : 'watch';
@ -94,23 +106,6 @@ export class WorkPackageWatcherButtonController {
} }
} }
function wpWatcherButton():any { wpDirectivesModule.directive('wpWatcherButton',
return { downgradeComponent({component: WorkPackageWatcherButtonComponent})
replace: true, );
templateUrl: '/components/work-packages/wp-watcher-button/wp-watcher-button.directive.html',
scope: {
workPackage: '=',
showText: '=',
disabled: '='
},
bindToController: true,
controller: WorkPackageWatcherButtonController,
controllerAs: 'vm'
};
}
wpDirectivesModule.directive('wpWatcherButton', wpWatcherButton);

@ -1,7 +0,0 @@
<button ng-click="vm.toggleWatch()" title="{{ vm.buttonTitle }}" ng-disabled="vm.disabled"
class="button toolbar-icon" ng-class="vm.buttonClass" id="{{ vm.buttonId }}">
<op-icon icon-classes="button--icon {{vm.watchIconClass}}"></op-icon>
<span class="button--text" ng-if="vm.showText" ng-bind="vm.buttonText"></span>
</button>

@ -0,0 +1,11 @@
<button *ngIf="displayWatchButton"
(click)="toggleWatch()"
[attr.title]="buttonTitle"
[disabled]="disabled"
[ngClass]="buttonClass"
class="button toolbar-icon"
[id]="buttonId">
<op-icon icon-classes="button--icon {{watchIconClass}}"></op-icon>
<span class="button--text" *ngIf="showText" [textContent]="buttonText"></span>
</button>

@ -1,30 +0,0 @@
// This Angular directive will act as an interface to the "upgraded" AngularJS component
// query-filters
import {
Directive, DoCheck, ElementRef, Inject, Injector, Input, OnChanges, OnDestroy,
OnInit, SimpleChanges
} from '@angular/core';
import {UpgradeComponent} from '@angular/upgrade/static';
import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service';
@Directive({selector: 'ng1-wp-details-toolbar-wrapper'})
export class Ng1DetailsToolbarWrapper extends UpgradeComponent implements OnInit, OnChanges, DoCheck, OnDestroy {
@Input('workPackage') workPackage:WorkPackageResourceInterface;
constructor(@Inject(ElementRef) elementRef:ElementRef, @Inject(Injector) injector:Injector) {
// We must pass the name of the directive as used by AngularJS to the super
super('wpDetailsToolbar', elementRef, injector);
}
// For this class to work when compiled with AoT, we must implement these lifecycle hooks
// because the AoT compiler will not realise that the super class implements them
ngOnInit() { super.ngOnInit(); }
ngOnChanges(changes:SimpleChanges) { super.ngOnChanges(changes); }
ngDoCheck() { super.ngDoCheck(); }
ngOnDestroy() { super.ngOnDestroy(); }
}

@ -29,35 +29,44 @@ import {WorkPackageMoreMenuService} from '../work-packages/work-package-more-men
import {openprojectModule} from '../../angular-modules'; import {openprojectModule} from '../../angular-modules';
import {WorkPackageEditingService} from '../wp-edit-form/work-package-editing-service'; import {WorkPackageEditingService} from '../wp-edit-form/work-package-editing-service';
function wpDetailsToolbar( import {I18nToken, wpMoreMenuServiceToken} from 'core-app/angular4-transition-utils';
I18n:op.I18n, import {Component, Inject, Input, OnInit} from '@angular/core';
wpEditing:WorkPackageEditingService, import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service';
wpMoreMenuService:WorkPackageMoreMenuService):any { import {downgradeComponent} from '@angular/upgrade/static';
return {
restrict: 'E',
templateUrl: '/components/wp-details/wp-details-toolbar.directive.html',
scope: {
workPackage: '='
},
link: function(scope:any, attr:ng.IAttributes, element:ng.IAugmentedJQuery) { @Component({
template: require('!!raw-loader!./wp-details-toolbar.html'),
selector: 'wp-details-toolbar',
})
export class WorkPackageSplitViewToolbarComponent implements OnInit {
@Input('workPackage') workPackage:WorkPackageResourceInterface;
let wpMoreMenu = new (wpMoreMenuService as any)(scope.workPackage); public permittedActions:any;
public actionsAvailable:any;
public triggerMoreMenuAction:Function;
wpMoreMenu.initialize().then(() => { public text = {
scope.permittedActions = wpMoreMenu.permittedActions; button_more: this.I18n.t('js.button_more')
scope.actionsAvailable = wpMoreMenu.actionsAvailable; }
});
scope.triggerMoreMenuAction = wpMoreMenu.triggerMoreMenuAction.bind(wpMoreMenu); constructor(@Inject(I18nToken) readonly I18n:op.I18n,
public wpEditing:WorkPackageEditingService,
@Inject(wpMoreMenuServiceToken) private wpMoreMenuServiceFactory:any) {
}
scope.displayWatchButton = scope.workPackage.hasOwnProperty('unwatch') || ngOnInit() {
scope.workPackage.hasOwnProperty('watch'); let wpMoreMenu = new this.wpMoreMenuServiceFactory(this.workPackage) as WorkPackageMoreMenuService;
scope.I18n = I18n; wpMoreMenu.initialize().then(() => {
} this.permittedActions = wpMoreMenu.permittedActions;
}; this.actionsAvailable = wpMoreMenu.actionsAvailable;
});
this.triggerMoreMenuAction = wpMoreMenu.triggerMoreMenuAction.bind(wpMoreMenu);
}
} }
openprojectModule.directive('wpDetailsToolbar', wpDetailsToolbar); openprojectModule.directive('wpDetailsToolbar',
downgradeComponent({component: WorkPackageSplitViewToolbarComponent })
);

@ -1,16 +0,0 @@
<div class="work-packages--details-toolbar">
<wp-watcher-button work-package="workPackage"
show-text="true"
ng-if="displayWatchButton">
</wp-watcher-button>
<button class="button dropdown-relative"
ng-disabled="!actionsAvailable"
has-dropdown-menu
accesskey="7"
target="DetailsMoreDropdownMenu"
locals="permittedActions,actionsAvailable,triggerMoreMenuAction">
<span class="button--text" ng-bind="::I18n.t('js.button_more')"></span>
<op-icon icon-classes="button--dropdown-indicator"></op-icon>
</button>
</div>

@ -28,6 +28,8 @@
/*jshint expr: true*/ /*jshint expr: true*/
// TODO convert?
describe('workPackageDetailsToolbar', function() { describe('workPackageDetailsToolbar', function() {
var I18n:any, $q:any, HookService:any, compile:any, scope:any, element:any, stateParams:any; var I18n:any, $q:any, HookService:any, compile:any, scope:any, element:any, stateParams:any;
var html = ` var html = `

@ -0,0 +1,15 @@
<div class="work-packages--details-toolbar">
<wp-watcher-button [workPackage]="workPackage"
[showText]="true">
</wp-watcher-button>
<button class="button dropdown-relative"
[disabled]="!actionsAvailable"
[attr.accesskey]="7"
hasDropdownMenu
[hasDropdownMenu-locals]="{'permittedActions': permittedActions,'actionsAvailable': actionsAvailable, 'triggerMoreMenuAction': triggerMoreMenuAction}"
[hasDropdownMenu-target]="'DetailsMoreDropdownMenu'">
<span class="button--text" [textContent]="text.button_more"></span>
<op-icon icon-classes="button--dropdown-indicator"></op-icon>
</button>
</div>
Loading…
Cancel
Save