From 4a7e7175a8f9ea86314d38bd4a179a9bd05553fe Mon Sep 17 00:00:00 2001 From: Roman Roelofsen Date: Wed, 7 Mar 2018 13:04:56 +0100 Subject: [PATCH] Refactoring: use observable.pipe(map) instead of observable.map, etc. --- .../focus-within/focus-within.directive.ts | 21 +- .../focus-within.upgraded.directive.ts | 16 +- .../add-section-dropdown.component.ts | 27 +- .../hide-section/hide-section.component.ts | 21 +- .../settings-menu/settings-menu.controller.ts | 0 .../routing/wp-list/wp-list.component.ts | 20 +- .../wp-split-view/wp-split-view.component.ts | 17 +- .../wp-view-base/wp-view-base.controller.ts | 30 +- .../schemas/schema-cache.service.ts | 19 +- frontend/app/components/states.service.ts | 3 +- .../components/states/state-cache.service.ts | 16 +- .../app/components/states/switch-state.ts | 25 +- .../work-package-cache.service.ts | 20 +- .../wp-relations-count.component.ts | 12 +- .../wp-single-view.component.ts | 31 +- .../wp-subject/wp-subject.component.ts | 13 +- .../wp-watcher-button.component.ts | 17 +- .../components/wp-copy/wp-copy.controller.ts | 9 +- .../work-package-editing-service.ts | 38 +- .../wp-edit-field-group.directive.ts | 46 +- .../handlers/state/columns-transformer.ts | 7 +- .../handlers/state/hierarchy-transformer.ts | 9 +- .../handlers/state/rows-transformer.ts | 11 +- .../handlers/state/selection-transformer.ts | 9 +- .../handlers/state/timeline-transformer.ts | 10 +- .../state/wp-table-base.service.ts | 21 +- .../state/wp-table-focus.service.ts | 24 +- .../state/wp-table-sort-by.service.ts | 21 +- .../wp-inline-create.directive.ts | 28 +- .../components/wp-new/wp-create.controller.ts | 31 +- .../components/wp-new/wp-create.service.ts | 9 +- .../wp-query-menu/wp-query-menu.service.ts | 21 +- .../wp-relations-hierarchy.directive.ts | 13 +- .../wp-relations/wp-relations.directive.ts | 31 +- .../activity-base.controller.ts | 13 +- .../keep-tab/keep-tab.service.ts | 7 +- .../overview-tab/overview-tab.component.ts | 12 +- .../relations-tab/relations-tab.component.ts | 11 +- .../watchers-tab/watchers-tab.component.ts | 27 +- .../sort-header/sort-header.directive.ts | 13 +- .../wp-table-pagination.component.test.ts | 2 +- .../wp-table/table-state/table-state.ts | 8 +- .../wp-timeline-container.directive.ts | 45 +- .../wp-timeline-relations.directive.ts | 23 +- .../wp-table-sums-row.directive.ts | 5 +- frontend/app/helpers/angular-rx-utils.ts | 61 +- frontend/npm-shrinkwrap.json | 966 +++--------------- frontend/package.json | 1 + frontend/webpack-main-config.js | 4 +- 49 files changed, 653 insertions(+), 1191 deletions(-) create mode 100644 frontend/app/components/context-menus/settings-menu/settings-menu.controller.ts diff --git a/frontend/app/components/common/focus-within/focus-within.directive.ts b/frontend/app/components/common/focus-within/focus-within.directive.ts index 8f1ee55d3e..e14b8a42ba 100644 --- a/frontend/app/components/common/focus-within/focus-within.directive.ts +++ b/frontend/app/components/common/focus-within/focus-within.directive.ts @@ -26,9 +26,10 @@ // See doc/COPYRIGHT.rdoc for more details. //++ +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import {auditTime} from 'rxjs/operators'; import {wpDirectivesModule} from '../../../angular-modules'; import {scopedObservable} from '../../../helpers/angular-rx-utils'; -import {BehaviorSubject} from 'rxjs'; // with courtesy of http://stackoverflow.com/a/29722694/3206935 @@ -44,22 +45,24 @@ function focusWithinDirective($timeout:ng.ITimeoutService) { let focusedObservable = new BehaviorSubject(false); scopedObservable( - scope, - focusedObservable + scope, + focusedObservable + ) + .pipe( + auditTime(50) ) - .auditTime(50) .subscribe(focused => { - element.toggleClass('-focus', focused); + element.toggleClass('-focus', focused); }); - let focusListener = function () { - focusedObservable.next(true); + let focusListener = function() { + focusedObservable.next(true); }; element[0].addEventListener('focus', focusListener, true); - let blurListener = function () { - focusedObservable.next(false); + let blurListener = function() { + focusedObservable.next(false); }; element[0].addEventListener('blur', blurListener, true); diff --git a/frontend/app/components/common/focus-within/focus-within.upgraded.directive.ts b/frontend/app/components/common/focus-within/focus-within.upgraded.directive.ts index 581bc9d797..2545ab2462 100644 --- a/frontend/app/components/common/focus-within/focus-within.upgraded.directive.ts +++ b/frontend/app/components/common/focus-within/focus-within.upgraded.directive.ts @@ -26,12 +26,10 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {wpDirectivesModule} from '../../../angular-modules'; -import {scopedObservable} from '../../../helpers/angular-rx-utils'; -import {BehaviorSubject} from 'rxjs'; import {Directive, ElementRef, Input, OnDestroy, OnInit} from '@angular/core'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {downgradeComponent} from '@angular/upgrade/static'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import {auditTime, takeUntil} from 'rxjs/operators'; // with courtesy of http://stackoverflow.com/a/29722694/3206935 @@ -52,19 +50,21 @@ export class FocusWithinDirective implements OnInit, OnDestroy { let focusedObservable = new BehaviorSubject(false); focusedObservable - .auditTime(50) - .takeUntil(componentDestroyed(this)) + .pipe( + auditTime(50), + takeUntil(componentDestroyed(this)) + ) .subscribe(focused => { this.$element.toggleClass('-focus', focused); }); - let focusListener = function () { + let focusListener = function() { focusedObservable.next(true); }; this.$element[0].addEventListener('focus', focusListener, true); - let blurListener = function () { + let blurListener = function() { focusedObservable.next(false); }; this.$element[0].addEventListener('blur', blurListener, true); diff --git a/frontend/app/components/common/hide-section/add-section-dropdown/add-section-dropdown.component.ts b/frontend/app/components/common/hide-section/add-section-dropdown/add-section-dropdown.component.ts index 3e7f949a97..7b62b6b9b1 100644 --- a/frontend/app/components/common/hide-section/add-section-dropdown/add-section-dropdown.component.ts +++ b/frontend/app/components/common/hide-section/add-section-dropdown/add-section-dropdown.component.ts @@ -26,13 +26,13 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {opUiComponentsModule} from '../../../../angular-modules'; import {Component, Inject, Input, OnDestroy, OnInit} from '@angular/core'; import {downgradeComponent} from '@angular/upgrade/static'; -import {HideSectionDefinition, HideSectionService} from 'core-components/common/hide-section/hide-section.service'; import {I18nToken} from 'core-app/angular4-transition-utils'; +import {HideSectionDefinition, HideSectionService} from 'core-components/common/hide-section/hide-section.service'; +import {combineLatest} from 'rxjs/observable/combineLatest'; import {Subscription} from 'rxjs/Subscription'; -import {Observable} from 'rxjs/Observable'; +import {opUiComponentsModule} from '../../../../angular-modules'; @Component({ selector: 'add-section-dropdown', @@ -40,7 +40,7 @@ import {Observable} from 'rxjs/Observable'; }) export class AddSectionDropdownComponent implements OnInit, OnDestroy { selectable:HideSectionDefinition[] = []; - turnedActive:HideSectionDefinition|null = null; + turnedActive:HideSectionDefinition | null = null; texts:{ [key:string]:string } = {}; @Input() @@ -56,13 +56,12 @@ export class AddSectionDropdownComponent implements OnInit, OnDestroy { } ngOnInit() { - this.allSubscription = Observable.combineLatest(this.hideSections.all$, - this.hideSections.displayed$) - .subscribe(([all, displayed]) => { - this.selectable = _.filter(all, all_candidate => - !_.some(displayed, displayed_candidate => all_candidate.key === displayed_candidate.key) - ).sort((a, b) => a.label.toLowerCase().localeCompare(b.label.toLowerCase())); - }); + this.allSubscription = combineLatest(this.hideSections.all$, this.hideSections.displayed$) + .subscribe(([all, displayed]) => { + this.selectable = _.filter(all, all_candidate => + !_.some(displayed, displayed_candidate => all_candidate.key === displayed_candidate.key) + ).sort((a, b) => a.label.toLowerCase().localeCompare(b.label.toLowerCase())); + }); } ngOnDestroy() { @@ -72,12 +71,14 @@ export class AddSectionDropdownComponent implements OnInit, OnDestroy { show() { if (this.turnedActive) { this.hideSections.show(this.turnedActive); - setTimeout(() => { this.turnedActive = null; } ); + setTimeout(() => { + this.turnedActive = null; + }); } } } opUiComponentsModule.directive( 'addSectionDropdown', - downgradeComponent({component:AddSectionDropdownComponent}) + downgradeComponent({component: AddSectionDropdownComponent}) ); diff --git a/frontend/app/components/common/hide-section/hide-section.component.ts b/frontend/app/components/common/hide-section/hide-section.component.ts index b8a22728e1..d74e49a00d 100644 --- a/frontend/app/components/common/hide-section/hide-section.component.ts +++ b/frontend/app/components/common/hide-section/hide-section.component.ts @@ -26,12 +26,12 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {opUiComponentsModule} from '../../../angular-modules'; -import {Component, ElementRef, OnDestroy} from '@angular/core'; -import {OnInit, Input} from '@angular/core'; +import {Component, ElementRef, Input, OnDestroy, OnInit} from '@angular/core'; import {downgradeComponent} from '@angular/upgrade/static'; import {HideSectionService} from 'core-components/common/hide-section/hide-section.service'; +import {distinctUntilChanged, map, take} from 'rxjs/operators'; import {Subscription} from 'rxjs/Subscription'; +import {opUiComponentsModule} from '../../../angular-modules'; @Component({ selector: 'hide-section', @@ -47,20 +47,27 @@ export class HideSectionComponent implements OnInit, OnDestroy { @Input() onDisplayed:Function; constructor(protected hideSection:HideSectionService, - private elementRef:ElementRef) { } + private elementRef:ElementRef) { + } ngOnInit() { let mappedDisplayed = this.hideSection.displayed$ - .map(all_displayed => _.some(all_displayed, candidate => candidate.key === this.sectionName)); + .pipe( + map(all_displayed => _.some(all_displayed, candidate => candidate.key === this.sectionName)) + ); this.initializationSubscription = mappedDisplayed - .take(1) + .pipe( + take(1) + ) .subscribe(show => { jQuery(this.elementRef.nativeElement).addClass('-initialized'); }); this.displayedSubscription = mappedDisplayed - .distinctUntilChanged() + .pipe( + distinctUntilChanged() + ) .subscribe(show => { this.displayed = show; diff --git a/frontend/app/components/context-menus/settings-menu/settings-menu.controller.ts b/frontend/app/components/context-menus/settings-menu/settings-menu.controller.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/frontend/app/components/routing/wp-list/wp-list.component.ts b/frontend/app/components/routing/wp-list/wp-list.component.ts index cf42037657..3f9142807b 100644 --- a/frontend/app/components/routing/wp-list/wp-list.component.ts +++ b/frontend/app/components/routing/wp-list/wp-list.component.ts @@ -27,9 +27,13 @@ // ++ import {Component, Inject, OnDestroy, OnInit} from '@angular/core'; -import {StateService, StateParams, TransitionService} from '@uirouter/core'; +import {downgradeComponent} from '@angular/upgrade/static'; +import {StateService, TransitionService} from '@uirouter/core'; +import {$stateToken, I18nToken} from 'core-app/angular4-transition-utils'; +import {AuthorisationService} from 'core-components/common/model-auth/model-auth.service'; +import {TableState} from 'core-components/wp-table/table-state/table-state'; import {untilComponentDestroyed} from 'ng2-rx-componentdestroyed'; -import {auditTime, distinctUntilChanged, filter, withLatestFrom} from 'rxjs/operators'; +import {auditTime, distinctUntilChanged, filter, take, withLatestFrom} from 'rxjs/operators'; import {debugLog} from '../../../helpers/debug_output'; import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; import {LoadingIndicatorService} from '../../common/loading-indicator/loading-indicator.service'; @@ -47,10 +51,6 @@ 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 {$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'; @Component({ selector: 'wp-list', @@ -126,7 +126,7 @@ export class WorkPackagesListComponent implements OnInit, OnDestroy { this.wpTableRefresh.clear('Table controller scope destroyed.'); } - public allowed(model:string, permission:string) { + public allowed(model:string, permission:string) { return this.authorisationService.can(model, permission); } @@ -144,8 +144,10 @@ export class WorkPackagesListComponent implements OnInit, OnDestroy { } private setupQueryObservers() { - this.states.tableRendering.onQueryUpdated.values$().pipe() - .take(1) + this.states.tableRendering.onQueryUpdated.values$() + .pipe( + take(1) + ) .subscribe(() => this.tableInformationLoaded = true); // Update the title whenever the query changes diff --git a/frontend/app/components/routing/wp-split-view/wp-split-view.component.ts b/frontend/app/components/routing/wp-split-view/wp-split-view.component.ts index c46dff0fe9..39a401f1b8 100644 --- a/frontend/app/components/routing/wp-split-view/wp-split-view.component.ts +++ b/frontend/app/components/routing/wp-split-view/wp-split-view.component.ts @@ -26,16 +26,17 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {Component, Inject, Injector} from '@angular/core'; +import {StateService} from '@uirouter/core'; +import {$stateToken} from 'core-app/angular4-transition-utils'; +import {FirstRouteService} from 'core-components/routing/first-route-service'; +import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; +import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; import {States} from '../../states.service'; import {WorkPackageTableSelection} from '../../wp-fast-table/state/wp-table-selection.service'; import {KeepTabService} from '../../wp-single-view-tabs/keep-tab/keep-tab.service'; import {WorkPackageViewController} from '../wp-view-base/wp-view-base.controller'; -import {FirstRouteService} from 'core-components/routing/first-route-service'; -import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; -import {StateService} from '@uirouter/core'; -import {Component, Inject, Injector} from '@angular/core'; -import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {$stateToken} from 'core-app/angular4-transition-utils'; @Component({ template: require('!!raw-loader!./wp-split-view.html'), @@ -70,7 +71,9 @@ export class WorkPackageSplitViewComponent extends WorkPackageViewController { } this.wpTableFocus.whenChanged() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe(newId => { const idSame = wpId.toString() === newId.toString(); if (!idSame && $state.includes('work-packages.list.details')) { diff --git a/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts b/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts index faaef4f361..e748b944af 100644 --- a/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts +++ b/frontend/app/components/routing/wp-view-base/wp-view-base.controller.ts @@ -26,22 +26,18 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {wpControllersModule} from '../../../angular-modules'; -import {scopedObservable} from '../../../helpers/angular-rx-utils'; +import {Injector, OnDestroy} from '@angular/core'; +import {I18nToken} from 'core-app/angular4-transition-utils'; +import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; +import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; +import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {States} from '../../states.service'; import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; +import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; import {KeepTabService} from '../../wp-single-view-tabs/keep-tab/keep-tab.service'; import {WorkPackageTableRefreshService} from '../../wp-table/wp-table-refresh-request.service'; -import {$injectFields} from '../../angular/angular-injector-bridge.functions'; -import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; -import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; -import {StateService} from '@uirouter/core'; -import {Injector, OnDestroy} from '@angular/core'; -import {I18nToken} from 'core-app/angular4-transition-utils'; -import PathHelper = op.PathHelper; -import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; -import {componentDestroyed} from 'ng2-rx-componentdestroyed'; export class WorkPackageViewController implements OnDestroy { @@ -78,7 +74,9 @@ export class WorkPackageViewController implements OnDestroy { */ protected observeWorkPackage() { this.wpCacheService.loadWorkPackage(this.workPackageId).values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((wp:WorkPackageResourceInterface) => { this.workPackage = wp; this.init(); @@ -109,10 +107,12 @@ export class WorkPackageViewController implements OnDestroy { // Listen to tab changes to update the tab label this.keepTab.observable - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((tabs:any) => { - this.updateFocusAnchorLabel(tabs.active); - }); + this.updateFocusAnchorLabel(tabs.active); + }); } /** diff --git a/frontend/app/components/schemas/schema-cache.service.ts b/frontend/app/components/schemas/schema-cache.service.ts index b4f427f510..bfedeb64d0 100644 --- a/frontend/app/components/schemas/schema-cache.service.ts +++ b/frontend/app/components/schemas/schema-cache.service.ts @@ -25,17 +25,12 @@ // // See doc/COPYRIGHT.rdoc for more details. // ++ -import {opWorkPackagesModule} from "../../angular-modules"; -import {State} from "reactivestates"; -import {Observable, Subject} from "rxjs"; -import {WorkPackageResource} from "../api/api-v3/hal-resources/work-package-resource.service"; -import {ApiWorkPackagesService} from "../api/api-work-packages/api-work-packages.service"; -import {States} from "../states.service"; -import { WorkPackageNotificationService } from "./../wp-edit/wp-notification.service"; -import { SchemaResource } from "../api/api-v3/hal-resources/schema-resource.service"; -import IScope = angular.IScope; -import IPromise = angular.IPromise; -import {WorkPackageResourceInterface} from "core-components/api/api-v3/hal-resources/work-package-resource.service"; + +import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {State} from 'reactivestates'; +import {opWorkPackagesModule} from '../../angular-modules'; +import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; +import {States} from '../states.service'; export class SchemaCacheService { @@ -61,7 +56,7 @@ export class SchemaCacheService { /** * Get the associated schema state of the work package * without initializing a new resource. - */ + */ state(workPackage:WorkPackageResourceInterface) { const schema = workPackage.$links.schema; return this.states.schemas.get(schema.href!); diff --git a/frontend/app/components/states.service.ts b/frontend/app/components/states.service.ts index e5ba43d83c..6e912fb0b1 100644 --- a/frontend/app/components/states.service.ts +++ b/frontend/app/components/states.service.ts @@ -1,6 +1,7 @@ import {WPFocusState} from 'core-components/wp-fast-table/state/wp-table-focus.service'; import {TableState} from 'core-components/wp-table/table-state/table-state'; import {combine, derive, input, multiInput, StatesGroup} from 'reactivestates'; +import {mapTo} from 'rxjs/operators'; import {opServicesModule} from '../angular-modules'; import {QueryFormResource} from './api/api-v3/hal-resources/query-form-resource.service'; import {QueryGroupByResource} from './api/api-v3/hal-resources/query-group-by-resource.service'; @@ -84,7 +85,7 @@ export class TableRenderingStates { this.states.globalTable.additionalRequiredWorkPackages ); - onQueryUpdated = derive(this.combinedTableStates, ($, input) => $.mapTo(null)); + onQueryUpdated = derive(this.combinedTableStates, ($, input) => $.pipe(mapTo(null))); } diff --git a/frontend/app/components/states/state-cache.service.ts b/frontend/app/components/states/state-cache.service.ts index faeac3f86f..2fcd720a41 100644 --- a/frontend/app/components/states/state-cache.service.ts +++ b/frontend/app/components/states/state-cache.service.ts @@ -1,6 +1,6 @@ // -- copyright // OpenProject is a project management system. -// Copyright (C) 2012-2015 the OpenProject Foundation (OPF) +// Copyright (C) 2012-2018 the OpenProject Foundation (OPF) // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License version 3. @@ -25,20 +25,8 @@ // // See doc/COPYRIGHT.rdoc for more details. // ++ -import {SchemaCacheService} from './../schemas/schema-cache.service'; + import {InputState, MultiInputState, State} from 'reactivestates'; -import {Observable, Subject} from 'rxjs'; -import {opWorkPackagesModule} from '../../angular-modules'; -import { - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {ApiWorkPackagesService} from '../api/api-work-packages/api-work-packages.service'; -import {States} from '../states.service'; -import {WorkPackageNotificationService} from './../wp-edit/wp-notification.service'; -import IScope = angular.IScope; -import IPromise = angular.IPromise; -import {WorkPackageCollectionResourceInterface} from '../api/api-v3/hal-resources/wp-collection-resource.service'; -import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; export abstract class StateCacheService { private cacheDurationInMs:number; diff --git a/frontend/app/components/states/switch-state.ts b/frontend/app/components/states/switch-state.ts index f02a2ce648..c510f746f7 100644 --- a/frontend/app/components/states/switch-state.ts +++ b/frontend/app/components/states/switch-state.ts @@ -1,42 +1,45 @@ -import {InputState, derive, input, State, IfThen} from 'reactivestates'; -import {debugLog} from "../../helpers/debug_output"; +import {derive, IfThen, input, InputState, State} from 'reactivestates'; +import {filter} from 'rxjs/operators'; +import {debugLog} from '../../helpers/debug_output'; export class SwitchState { - private readonly contextSwitch$: InputState = input(); + private readonly contextSwitch$:InputState = input(); - public transition(context: StateName) { + public transition(context:StateName) { if (this.validTransition(context)) { debugLog(`Switching table context to ${context}`); this.contextSwitch$.putValue(context); } } - public validTransition(to: StateName) { + public validTransition(to:StateName) { return (this.contextSwitch$.value !== to); } - public get current():StateName|undefined { + public get current():StateName | undefined { return this.contextSwitch$.value; } - public reset(reason?: string) { + public reset(reason?:string) { debugLog('Resetting table context.'); this.contextSwitch$.clear(reason); } - public doAndTransition(context: StateName, callback:() => PromiseLike) { + public doAndTransition(context:StateName, callback:() => PromiseLike) { this.reset('Clearing before transitioning to ' + context); const promise = callback(); promise.then(() => this.transition(context)); } - public fireOnTransition(cb: State, ...context: StateName[]): State { + public fireOnTransition(cb:State, ...context:StateName[]):State { return IfThen(this.contextSwitch$, s => context.indexOf(s) > -1, cb); } - public fireOnStateChange(state: State, ...context: StateName[]): State { + public fireOnStateChange(state:State, ...context:StateName[]):State { return derive(state, $ => $ - .filter(() => this.contextSwitch$.hasValue() && context.indexOf(this.contextSwitch$.value!) > -1)) + .pipe( + filter(() => this.contextSwitch$.hasValue() && context.indexOf(this.contextSwitch$.value!) > -1)) + ); } } diff --git a/frontend/app/components/work-packages/work-package-cache.service.ts b/frontend/app/components/work-packages/work-package-cache.service.ts index f61a9ee9f2..912316ff41 100644 --- a/frontend/app/components/work-packages/work-package-cache.service.ts +++ b/frontend/app/components/work-packages/work-package-cache.service.ts @@ -25,24 +25,20 @@ // // See doc/COPYRIGHT.rdoc for more details. // ++ -import {SchemaCacheService} from './../schemas/schema-cache.service'; + import {State} from 'reactivestates'; -import {Observable, Subject} from 'rxjs'; import {opWorkPackagesModule} from '../../angular-modules'; -import { - WorkPackageResourceInterface -} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; +import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageCollectionResourceInterface} from '../api/api-v3/hal-resources/wp-collection-resource.service'; import {ApiWorkPackagesService} from '../api/api-work-packages/api-work-packages.service'; import {States} from '../states.service'; -import {WorkPackageNotificationService} from './../wp-edit/wp-notification.service'; -import IScope = angular.IScope; -import IPromise = angular.IPromise; -import {WorkPackageCollectionResourceInterface} from '../api/api-v3/hal-resources/wp-collection-resource.service'; -import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; import {StateCacheService} from '../states/state-cache.service'; +import {SchemaCacheService} from './../schemas/schema-cache.service'; +import {WorkPackageNotificationService} from './../wp-edit/wp-notification.service'; function getWorkPackageId(id:number | string):string { - return (id || "__new_work_package__").toString(); + return (id || '__new_work_package__').toString(); } export class WorkPackageCacheService extends StateCacheService { @@ -87,7 +83,7 @@ export class WorkPackageCacheService extends StateCacheService(null); } - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { return workPackage.save() .then(() => { this.wpNotificationsService.showSave(workPackage); diff --git a/frontend/app/components/work-packages/wp-relations-count/wp-relations-count.component.ts b/frontend/app/components/work-packages/wp-relations-count/wp-relations-count.component.ts index fe9192da8e..62610efb78 100644 --- a/frontend/app/components/work-packages/wp-relations-count/wp-relations-count.component.ts +++ b/frontend/app/components/work-packages/wp-relations-count/wp-relations-count.component.ts @@ -1,11 +1,9 @@ -import {wpControllersModule} from '../../../angular-modules'; -import { - RelationsStateValue, - WorkPackageRelationsService -} from '../../wp-relations/wp-relations.service'; import {Component, Input, OnDestroy, OnInit} from '@angular/core'; import {downgradeComponent} from '@angular/upgrade/static'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; +import {wpControllersModule} from '../../../angular-modules'; +import {RelationsStateValue, WorkPackageRelationsService} from '../../wp-relations/wp-relations.service'; @Component({ template: require('!!raw-loader!./wp-relations-count.html'), @@ -22,7 +20,9 @@ export class WorkPackageRelationsCountComponent implements OnInit, OnDestroy { this.wpRelations.require(this.wpId.toString()); this.wpRelations.state(this.wpId.toString()).values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((relations:RelationsStateValue) => { this.count = _.size(relations); }); diff --git a/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts b/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts index 2e038c47b7..041229d996 100644 --- a/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts +++ b/frontend/app/components/work-packages/wp-single-view/wp-single-view.component.ts @@ -26,19 +26,20 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {Component, Inject, Input, OnDestroy, OnInit} from '@angular/core'; +import {I18nToken} from 'core-app/angular4-transition-utils'; +import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; +import {WorkPackageEditFieldGroupComponent} from 'core-components/wp-edit/wp-edit-field/wp-edit-field-group.directive'; +import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; import {debugLog} from '../../../helpers/debug_output'; import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {CurrentProjectService} from '../../projects/current-project.service'; +import {States} from '../../states.service'; import {DisplayField} from '../../wp-display/wp-display-field/wp-display-field.module'; import {WorkPackageDisplayFieldService} from '../../wp-display/wp-display-field/wp-display-field.service'; -import {WorkPackageCacheService} from '../work-package-cache.service'; import {WorkPackageEditingService} from '../../wp-edit-form/work-package-editing-service'; -import {States} from '../../states.service'; -import {CurrentProjectService} from '../../projects/current-project.service'; -import {Component, Inject, Input, OnDestroy, OnInit} from '@angular/core'; -import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; -import {I18nToken} from 'core-app/angular4-transition-utils'; -import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {WorkPackageEditFieldGroupComponent} from 'core-components/wp-edit/wp-edit-field/wp-edit-field-group.directive'; +import {WorkPackageCacheService} from '../work-package-cache.service'; interface FieldDescriptor { name:string; @@ -58,14 +59,14 @@ interface GroupDescriptor { template: require('!!raw-loader!./wp-single-view.html'), selector: 'wp-single-view', }) -export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { +export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { @Input('workPackage') public workPackage:WorkPackageResourceInterface; // Grouped fields returned from API public groupedFields:GroupDescriptor[] = []; public projectContext:{ matches:boolean, - href:string|null, + href:string | null, field?:FieldDescriptor[] }; public text = { @@ -113,13 +114,15 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { this.wpEditing.temporaryEditResource(this.workPackage.id) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((resource:WorkPackageResourceInterface) => { // Prepare the fields that are required always const isNew = this.workPackage.isNew; if (!resource.project) { - this.projectContext = { matches: false, href: null }; + this.projectContext = {matches: false, href: null}; } else { this.projectContext = { href: this.PathHelper.projectWorkPackagePath(resource.project.idFromLink, this.workPackage.id), @@ -176,7 +179,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { * @param index * @param elem */ - public trackByName(_index:number, elem:{ name: string }) { + public trackByName(_index:number, elem:{ name:string }) { return elem.name; } @@ -191,7 +194,7 @@ export class WorkPackageSingleViewComponent implements OnInit, OnDestroy { let id = this.workPackage.project.idFromLink; let projectPath = this.PathHelper.projectPath(id); let project = `${this.workPackage.project.name}`; - return this.I18n.t('js.project.work_package_belongs_to', { projectname: project }); + return this.I18n.t('js.project.work_package_belongs_to', {projectname: project}); } /** diff --git a/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts b/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts index a4e1566969..9c474b9eca 100644 --- a/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts +++ b/frontend/app/components/work-packages/wp-subject/wp-subject.component.ts @@ -26,13 +26,14 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {Component, Input, OnDestroy, OnInit} from '@angular/core'; +import {downgradeComponent} from '@angular/upgrade/static'; +import {UIRouterGlobals} from '@uirouter/core'; +import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; import {opWorkPackagesModule} from '../../../angular-modules'; import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageCacheService} from '../work-package-cache.service'; -import {UIRouterGlobals} from '@uirouter/core'; -import {Component, Input, OnDestroy, OnInit} from '@angular/core'; -import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {downgradeComponent} from '@angular/upgrade/static'; @Component({ template: require('!!raw-loader!./wp-subject.html'), @@ -53,7 +54,9 @@ export class WorkPackageSubjectComponent implements OnInit, OnDestroy { if (!this.workPackage) { this.wpCacheService.loadWorkPackage(this.uiRouterGlobals.params['workPackageId']) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((wp:WorkPackageResourceInterface) => { this.workPackage = wp; }); diff --git a/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts b/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts index 3b3d38cccc..c197a80563 100644 --- a/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts +++ b/frontend/app/components/work-packages/wp-watcher-button/wp-watcher-button.component.ts @@ -26,19 +26,20 @@ // 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 {downgradeComponent} from '@angular/upgrade/static'; import {I18nToken} from 'core-app/angular4-transition-utils'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {downgradeComponent} from '@angular/upgrade/static'; +import {takeUntil} from 'rxjs/operators'; +import {wpDirectivesModule} from '../../../angular-modules'; +import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageCacheService} from '../work-package-cache.service'; @Component({ template: require('!!raw-loader!./wp-watcher-button.html'), selector: 'wp-watcher-button', }) -export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy { +export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy { @Input('workPackage') public workPackage:WorkPackageResourceInterface; @Input('showText') public showText:boolean = false; @Input('disabled') public disabled:boolean = false; @@ -56,8 +57,10 @@ export class WorkPackageWatcherButtonComponent implements OnInit, OnDestroy { ngOnInit() { this.wpCacheService.loadWorkPackage(this.workPackage.id) .values$() - .takeUntil(componentDestroyed(this)) - .subscribe((wp: WorkPackageResourceInterface) => { + .pipe( + takeUntil(componentDestroyed(this)) + ) + .subscribe((wp:WorkPackageResourceInterface) => { this.workPackage = wp; this.setWatchStatus(); }); diff --git a/frontend/app/components/wp-copy/wp-copy.controller.ts b/frontend/app/components/wp-copy/wp-copy.controller.ts index 3220a7e293..0f72216094 100644 --- a/frontend/app/components/wp-copy/wp-copy.controller.ts +++ b/frontend/app/components/wp-copy/wp-copy.controller.ts @@ -26,16 +26,19 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from "../api/api-v3/hal-resources/work-package-resource.service"; -import {WorkPackageCreateController} from "../wp-new/wp-create.controller"; +import {take} from 'rxjs/operators'; +import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; +import {WorkPackageCreateController} from '../wp-new/wp-create.controller'; export class WorkPackageCopyController extends WorkPackageCreateController { protected newWorkPackageFromParams(stateParams:any) { return new Promise((resolve, reject) => { this.wpCacheService.loadWorkPackage(stateParams.copiedFromWorkPackageId) .values$() - .take(1) + .pipe( + take(1) + ) .subscribe( (wp:WorkPackageResourceInterface) => this.createCopyFrom(wp).then(resolve), reject); diff --git a/frontend/app/components/wp-edit-form/work-package-editing-service.ts b/frontend/app/components/wp-edit-form/work-package-editing-service.ts index e69daa0788..a0627ba867 100644 --- a/frontend/app/components/wp-edit-form/work-package-editing-service.ts +++ b/frontend/app/components/wp-edit-form/work-package-editing-service.ts @@ -26,21 +26,15 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {combine, deriveRaw, multiInput, State, StatesGroup} from 'reactivestates'; +import {map} from 'rxjs/operators'; import {wpServicesModule} from '../../angular-modules'; -import {WorkPackageEditForm} from './work-package-edit-form'; -import { - WorkPackageResource, - WorkPackageResourceEmbedded, - WorkPackageResourceInterface, WorkPackageResourceLinks -} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {WorkPackageEditContext} from './work-package-edit-context'; -import {WorkPackageChangeset} from './work-package-changeset'; +import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; import {StateCacheService} from '../states/state-cache.service'; -import {combine, deriveRaw, multiInput, State, StatesGroup} from 'reactivestates'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; -import {Observable} from 'rxjs'; -import {SchemaResource} from '../api/api-v3/hal-resources/schema-resource.service'; -import {HalResource} from '../api/api-v3/hal-resources/hal-resource.service'; +import {WorkPackageChangeset} from './work-package-changeset'; +import {WorkPackageEditContext} from './work-package-edit-context'; +import {WorkPackageEditForm} from './work-package-edit-form'; class WPChangesetStates extends StatesGroup { name = 'WP-Changesets'; @@ -100,14 +94,16 @@ export class WorkPackageEditingService extends StateCacheService - $.map(([wp, changeset]) => { - if (wp && changeset && changeset.resource) { - return changeset.resource!; - } else { - return wp; - } - }) + ($) => $ + .pipe( + map(([wp, changeset]) => { + if (wp && changeset && changeset.resource) { + return changeset.resource!; + } else { + return wp; + } + }) + ) ); } @@ -126,7 +122,7 @@ export class WorkPackageEditingService extends StateCacheService { this.form.editMode = false; this.stopEditingAndLeave(wp, true); - }); + }); } this.states.workPackages.get(this.workPackage.id) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)), + ) .subscribe((wp) => { _.each(this.fields, (ctrl) => this.updateDisplayField(ctrl, wp)); }); @@ -148,9 +153,11 @@ export class WorkPackageEditFieldGroupComponent implements OnInit, OnDestroy { public waitForField(name:string):Promise { return this.registeredFields .values$() - .filter(keys => keys.indexOf(name) >= 0) - .take(1) - .map(() => this.fields[name]) + .pipe( + filter(keys => keys.indexOf(name) >= 0), + take(1), + map(() => this.fields[name]) + ) .toPromise(); } @@ -219,7 +226,6 @@ export class WorkPackageEditFieldGroupComponent implements OnInit, OnDestroy { } - opWorkPackagesModule.directive('wpEditFieldGroupNg1', downgradeComponent({component: WorkPackageEditFieldGroupComponent}) ); diff --git a/frontend/app/components/wp-fast-table/handlers/state/columns-transformer.ts b/frontend/app/components/wp-fast-table/handlers/state/columns-transformer.ts index a4e745ebfc..83449b578d 100644 --- a/frontend/app/components/wp-fast-table/handlers/state/columns-transformer.ts +++ b/frontend/app/components/wp-fast-table/handlers/state/columns-transformer.ts @@ -1,4 +1,5 @@ import {Injector} from '@angular/core'; +import {filter, takeUntil} from 'rxjs/operators'; import {debugLog} from '../../../../helpers/debug_output'; import {States} from '../../../states.service'; import {WorkPackageTableColumnsService} from '../../state/wp-table-columns.service'; @@ -14,8 +15,10 @@ export class ColumnsTransformer { this.states.updates.columnsUpdates .values$('Refreshing columns on user request') - .filter(() => this.wpTableColumns.hasRelationColumns() === false) - .takeUntil(this.states.globalTable.stopAllSubscriptions) + .pipe( + filter(() => this.wpTableColumns.hasRelationColumns() === false), + takeUntil(this.states.globalTable.stopAllSubscriptions) + ) .subscribe(() => { if (table.originalRows.length > 0) { diff --git a/frontend/app/components/wp-fast-table/handlers/state/hierarchy-transformer.ts b/frontend/app/components/wp-fast-table/handlers/state/hierarchy-transformer.ts index 0cbec31c10..bb65c76c79 100644 --- a/frontend/app/components/wp-fast-table/handlers/state/hierarchy-transformer.ts +++ b/frontend/app/components/wp-fast-table/handlers/state/hierarchy-transformer.ts @@ -1,5 +1,6 @@ import {Injector} from '@angular/core'; import {scrollTableRowIntoView} from 'core-components/wp-fast-table/helpers/wp-table-row-helpers'; +import {distinctUntilChanged, map, takeUntil} from 'rxjs/operators'; import {States} from '../../../states.service'; import {indicatorCollapsedClass} from '../../builders/modes/hierarchy/single-hierarchy-row-builder'; import {tableRowClassName} from '../../builders/rows/single-row-builder'; @@ -17,9 +18,11 @@ export class HierarchyTransformer { table:WorkPackageTable) { this.states.updates.hierarchyUpdates .values$('Refreshing hierarchies on user request') - .takeUntil(this.states.globalTable.stopAllSubscriptions) - .map((state) => state.isEnabled) - .distinctUntilChanged() + .pipe( + takeUntil(this.states.globalTable.stopAllSubscriptions), + map((state) => state.isEnabled), + distinctUntilChanged() + ) .subscribe(() => { // We don't have to reload all results when _disabling_ the hierarchy mode. if (!this.wpTableHierarchies.isEnabled) { diff --git a/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts b/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts index 675d65d2cb..5f217a3440 100644 --- a/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts +++ b/frontend/app/components/wp-fast-table/handlers/state/rows-transformer.ts @@ -1,4 +1,5 @@ import {Injector} from '@angular/core'; +import {filter, takeUntil} from 'rxjs/operators'; import {debugLog} from '../../../../helpers/debug_output'; import {WorkPackageResourceInterface} from '../../../api/api-v3/hal-resources/work-package-resource.service'; import {States} from '../../../states.service'; @@ -15,7 +16,9 @@ export class RowsTransformer { // Redraw table if the current row state changed this.states.query.context.fireOnTransition(this.states.globalTable.rows, 'Query loaded') .values$('Initializing table after query was initialized') - .takeUntil(this.states.globalTable.stopAllSubscriptions) + .pipe( + takeUntil(this.states.globalTable.stopAllSubscriptions) + ) .subscribe((rows:WorkPackageResourceInterface[]) => { var t0 = performance.now(); @@ -27,8 +30,10 @@ export class RowsTransformer { // Refresh a single row if it exists this.states.workPackages.observeChange() - .takeUntil(this.states.globalTable.stopAllSubscriptions.asObservable()) - .filter(() => this.states.query.context.current === 'Query loaded') + .pipe( + takeUntil(this.states.globalTable.stopAllSubscriptions.asObservable()), + filter(() => this.states.query.context.current === 'Query loaded') + ) .subscribe(([changedId, wp]) => { if (wp === undefined) { return; diff --git a/frontend/app/components/wp-fast-table/handlers/state/selection-transformer.ts b/frontend/app/components/wp-fast-table/handlers/state/selection-transformer.ts index 391ad4b45c..d33959ba02 100644 --- a/frontend/app/components/wp-fast-table/handlers/state/selection-transformer.ts +++ b/frontend/app/components/wp-fast-table/handlers/state/selection-transformer.ts @@ -1,6 +1,7 @@ import {Injector} from '@angular/core'; import {FocusHelperToken} from 'core-app/angular4-transition-utils'; import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; +import {takeUntil} from 'rxjs/operators'; import {States} from '../../../states.service'; import {tableRowClassName} from '../../builders/rows/single-row-builder'; import {checkedClassName} from '../../builders/ui-state-link-builder'; @@ -23,7 +24,9 @@ export class SelectionTransformer { // Focus a single selection when active this.states.globalTable.rendered.values$() - .takeUntil(this.states.globalTable.stopAllSubscriptions) + .pipe( + takeUntil(this.states.globalTable.stopAllSubscriptions) + ) .subscribe(() => { this.wpTableFocus.ifShouldFocus((wpId:string) => { @@ -38,7 +41,9 @@ export class SelectionTransformer { // Update selection state this.wpTableSelection.selectionState.values$() - .takeUntil(this.states.globalTable.stopAllSubscriptions) + .pipe( + takeUntil(this.states.globalTable.stopAllSubscriptions) + ) .subscribe((state:WPTableRowSelectionState) => { this.renderSelectionState(state); }); diff --git a/frontend/app/components/wp-fast-table/handlers/state/timeline-transformer.ts b/frontend/app/components/wp-fast-table/handlers/state/timeline-transformer.ts index b8ba43c20a..031a25fd4e 100644 --- a/frontend/app/components/wp-fast-table/handlers/state/timeline-transformer.ts +++ b/frontend/app/components/wp-fast-table/handlers/state/timeline-transformer.ts @@ -1,4 +1,5 @@ import {Injector} from '@angular/core'; +import {takeUntil} from 'rxjs/operators'; import {States} from '../../../states.service'; import {WorkPackageTable} from '../../wp-fast-table'; import {WorkPackageTableTimelineState} from '../../wp-table-timeline'; @@ -11,9 +12,12 @@ export class TimelineTransformer { table:WorkPackageTable) { this.states.globalTable.timelineVisible.values$() - .takeUntil(this.states.globalTable.stopAllSubscriptions).subscribe((state:WorkPackageTableTimelineState) => { - this.renderVisibility(state.isVisible); - }); + .pipe( + takeUntil(this.states.globalTable.stopAllSubscriptions) + ) + .subscribe((state:WorkPackageTableTimelineState) => { + this.renderVisibility(state.isVisible); + }); } /** diff --git a/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts index e65362de15..ab1432f45a 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-base.service.ts @@ -26,15 +26,15 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {QuerySchemaResourceInterface} from 'core-components/api/api-v3/hal-resources/query-schema-resource.service'; +import {WorkPackageCollectionResource} from 'core-components/api/api-v3/hal-resources/wp-collection-resource.service'; +import {States} from 'core-components/states.service'; +import {TableState} from 'core-components/wp-table/table-state/table-state'; import {InputState, State} from 'reactivestates'; +import {Observable} from 'rxjs/Observable'; +import {mapTo, take, takeUntil} from 'rxjs/operators'; import {scopedObservable} from '../../../helpers/angular-rx-utils'; -import {Observable} from 'rxjs'; import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; -import {TableState} from 'core-components/wp-table/table-state/table-state'; -import {QuerySchemaResourceInterface} from 'core-components/api/api-v3/hal-resources/query-schema-resource.service'; -import {States} from 'core-components/states.service'; -import {WorkPackageCollectionResource} from 'core-components/api/api-v3/hal-resources/wp-collection-resource.service'; -import {takeUntil} from 'rxjs/operators'; export abstract class WorkPackageTableBaseService { protected tableState:TableState; @@ -56,7 +56,7 @@ export abstract class WorkPackageTableBaseService { * @param {QueryResource} query * @returns {T} Instance of the state value for this type. */ - public abstract valueFromQuery(query:QueryResource, results:WorkPackageCollectionResource):T|undefined; + public abstract valueFromQuery(query:QueryResource, results:WorkPackageCollectionResource):T | undefined; /** * Initialize this table state from the given query resource, @@ -82,7 +82,12 @@ export abstract class WorkPackageTableBaseService { } public onReady(scope:ng.IScope) { - return scopedObservable(scope, this.state.values$()).take(1).mapTo(null).toPromise(); + return scopedObservable(scope, this.state.values$()) + .pipe( + take(1), + mapTo(null) + ) + .toPromise(); } } diff --git a/frontend/app/components/wp-fast-table/state/wp-table-focus.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-focus.service.ts index bfe7b2c7a5..5e4bd035f1 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-focus.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-focus.service.ts @@ -1,8 +1,8 @@ -import {States} from '../../states.service'; -import {opServicesModule} from '../../../angular-modules'; -import {WorkPackageResource} from '../../api/api-v3/hal-resources/work-package-resource.service'; -import {InputState} from 'reactivestates'; import {WorkPackageTableSelection} from 'core-components/wp-fast-table/state/wp-table-selection.service'; +import {InputState} from 'reactivestates'; +import {distinctUntilChanged, filter, map} from 'rxjs/operators'; +import {opServicesModule} from '../../../angular-modules'; +import {States} from '../../states.service'; export interface WPFocusState { workPackageId:string; @@ -33,7 +33,7 @@ export class WorkPackageTableFocusService { } } - public get focusedWorkPackage():string|null { + public get focusedWorkPackage():string | null { const value = this.state.value; if (value) { @@ -49,8 +49,10 @@ export class WorkPackageTableFocusService { public whenChanged() { return this.state.values$() - .map((val:WPFocusState) => val.workPackageId) - .distinctUntilChanged(); + .pipe( + map((val:WPFocusState) => val.workPackageId), + distinctUntilChanged() + ); } public updateFocus(workPackageId:string, setFocusAfterRender:boolean = false) { @@ -58,7 +60,7 @@ export class WorkPackageTableFocusService { if (this.wpTableSelection.isEmpty) { this.wpTableSelection.setRowState(workPackageId, true); } - this.state.putValue({ workPackageId: workPackageId, focusAfterRender: setFocusAfterRender}); + this.state.putValue({workPackageId: workPackageId, focusAfterRender: setFocusAfterRender}); } /** @@ -69,8 +71,10 @@ export class WorkPackageTableFocusService { this .states.globalTable.rendered .values$() - .map(state => _.find(state, (row:any) => row.workPackageId)) - .filter(fullRow => !!fullRow && this.wpTableSelection.isEmpty) + .pipe( + map(state => _.find(state, (row:any) => row.workPackageId)), + filter(fullRow => !!fullRow && this.wpTableSelection.isEmpty) + ) .subscribe(fullRow => { this.updateFocus(fullRow!.workPackageId!); }); diff --git a/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts index 30d833f527..66e906df28 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-sort-by.service.ts @@ -26,19 +26,20 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageQueryStateService, WorkPackageTableBaseService} from './wp-table-base.service'; +import {States} from 'core-components/states.service'; +import {combine} from 'reactivestates'; +import {Observable} from 'rxjs/Observable'; +import {mapTo} from 'rxjs/operators'; +import {opServicesModule} from '../../../angular-modules'; import {QueryResource} from '../../api/api-v3/hal-resources/query-resource.service'; import { QUERY_SORT_BY_ASC, QUERY_SORT_BY_DESC, QuerySortByResource } from '../../api/api-v3/hal-resources/query-sort-by-resource.service'; -import {opServicesModule} from '../../../angular-modules'; -import {WorkPackageTableSortBy} from '../wp-table-sort-by'; import {QueryColumn} from '../../wp-query/query-column'; -import {combine} from 'reactivestates'; -import {Observable} from 'rxjs'; -import {States} from 'core-components/states.service'; +import {WorkPackageTableSortBy} from '../wp-table-sort-by'; +import {WorkPackageQueryStateService, WorkPackageTableBaseService} from './wp-table-base.service'; export class WorkPackageTableSortByService extends WorkPackageTableBaseService implements WorkPackageQueryStateService { @@ -58,7 +59,9 @@ export class WorkPackageTableSortByService extends WorkPackageTableBaseService { return combine(this.state, this.states.query.available.sortBy) .values$() - .mapTo(null); + .pipe( + mapTo(null) + ); } public hasChanged(query:QueryResource) { @@ -98,11 +101,11 @@ export class WorkPackageTableSortByService extends WorkPackageTableBaseService (candidate.column.$href === column.$href && - candidate.direction.$href === direction) + candidate.direction.$href === direction) ); } diff --git a/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts b/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts index 8b9b8ec2e5..eb35e253f3 100644 --- a/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts +++ b/frontend/app/components/wp-inline-create/wp-inline-create.directive.ts @@ -28,13 +28,14 @@ import {Directive, ElementRef, Injector, Input} from '@angular/core'; import {UpgradeComponent} from '@angular/upgrade/static'; +import {AuthorisationService} from 'core-components/common/model-auth/model-auth.service'; import {WorkPackageTableFocusService} from 'core-components/wp-fast-table/state/wp-table-focus.service'; +import {filter, takeUntil} from 'rxjs/operators'; import {opWorkPackagesModule} from '../../angular-modules'; import {scopeDestroyed$, scopedObservable} from '../../helpers/angular-rx-utils'; import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; import {States} from '../states.service'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; -import {WorkPackageCreateService} from '../wp-new/wp-create.service'; import {TableRowEditContext} from '../wp-edit-form/table-row-edit-context'; import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; import {WorkPackageEditForm} from '../wp-edit-form/work-package-edit-form'; @@ -45,12 +46,12 @@ import {onClickOrEnter} from '../wp-fast-table/handlers/click-or-enter-handler'; import {WorkPackageTableColumnsService} from '../wp-fast-table/state/wp-table-columns.service'; import {WorkPackageTableFiltersService} from '../wp-fast-table/state/wp-table-filters.service'; import {WorkPackageTable} from '../wp-fast-table/wp-fast-table'; +import {WorkPackageCreateService} from '../wp-new/wp-create.service'; import { inlineCreateCancelClassName, InlineCreateRowBuilder, inlineCreateRowClassName } from './inline-create-row-builder'; -import {AuthorisationService} from 'core-components/common/model-auth/model-auth.service'; export class WorkPackageInlineCreateController { @@ -129,16 +130,19 @@ export class WorkPackageInlineCreateController { // Watch on this scope when the columns change and refresh this row this.states.globalTable.columns.values$() - .filter(() => this.isHidden) // Take only when row is inserted - .takeUntil(scopeDestroyed$(this.$scope)).subscribe(() => { - const rowElement = this.$element.find(`.${inlineCreateRowClassName}`); - - if (rowElement.length && this.currentWorkPackage) { - this.rowBuilder.refreshRow(this.currentWorkPackage, - this.workPackageEditForm!.changeset, - rowElement); - } - }); + .pipe( + filter(() => this.isHidden), // Take only when row is inserted + takeUntil(scopeDestroyed$(this.$scope)) + ) + .subscribe(() => { + const rowElement = this.$element.find(`.${inlineCreateRowClassName}`); + + if (rowElement.length && this.currentWorkPackage) { + this.rowBuilder.refreshRow(this.currentWorkPackage, + this.workPackageEditForm!.changeset, + rowElement); + } + }); // Cancel edition of current new row this.$element.on('click keydown', `.${inlineCreateCancelClassName}`, (evt) => { diff --git a/frontend/app/components/wp-new/wp-create.controller.ts b/frontend/app/components/wp-new/wp-create.controller.ts index f4130eea6b..68ea8abb93 100644 --- a/frontend/app/components/wp-new/wp-create.controller.ts +++ b/frontend/app/components/wp-new/wp-create.controller.ts @@ -26,22 +26,23 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; -import {States} from '../states.service'; +import {Inject, OnDestroy, OnInit} from '@angular/core'; +import {StateService, Transition} from '@uirouter/core'; +import {$stateToken, I18nToken, v3PathToken} from 'core-app/angular4-transition-utils'; +import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; +import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; import {RootDmService} from '../api/api-v3/hal-resource-dms/root-dm.service'; import {RootResource} from '../api/api-v3/hal-resources/root-resource.service'; +import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-package-resource.service'; +import {States} from '../states.service'; import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; -import {WorkPackageNotificationService} from '../wp-edit/wp-notification.service'; -import {WorkPackageCreateService} from './wp-create.service'; -import {WorkPackageEditingService} from '../wp-edit-form/work-package-editing-service'; import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; +import {WorkPackageEditingService} from '../wp-edit-form/work-package-editing-service'; import {WorkPackageFilterValues} from '../wp-edit-form/work-package-filter-values'; +import {WorkPackageNotificationService} from '../wp-edit/wp-notification.service'; import {WorkPackageTableFiltersService} from '../wp-fast-table/state/wp-table-filters.service'; -import {StateService, Transition} from '@uirouter/core'; -import {Inject, Input, OnDestroy, OnInit} from '@angular/core'; -import {$stateToken, I18nToken, v3PathToken} from 'core-app/angular4-transition-utils'; -import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {PathHelperService} from 'core-components/common/path-helper/path-helper.service'; +import {WorkPackageCreateService} from './wp-create.service'; export class WorkPackageCreateController implements OnInit, OnDestroy { public successState:string; @@ -90,10 +91,12 @@ export class WorkPackageCreateController implements OnInit, OnDestroy { if (this.stateParams['parent_id']) { this.wpCacheService.loadWorkPackage(this.stateParams['parent_id']) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe(parent => { - this.parentWorkPackage = parent; - }); + this.parentWorkPackage = parent; + }); } }) .catch((error:any) => { @@ -101,7 +104,7 @@ export class WorkPackageCreateController implements OnInit, OnDestroy { this.RootDm.load().then((root:RootResource) => { if (!root.user) { // Not logged in - let url = URI(this.PathHelper.loginPath()) + let url = URI(this.PathHelper.loginPath()); url.search({back_url: url}); window.location.href = url.toString(); } diff --git a/frontend/app/components/wp-new/wp-create.service.ts b/frontend/app/components/wp-new/wp-create.service.ts index 368797f41d..1b255781e1 100644 --- a/frontend/app/components/wp-new/wp-create.service.ts +++ b/frontend/app/components/wp-new/wp-create.service.ts @@ -26,17 +26,16 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ +import {Observable} from 'rxjs/Observable'; +import {Subject} from 'rxjs/Subject'; import {wpServicesModule} from '../../angular-modules'; -import {ApiWorkPackagesService} from '../api/api-work-packages/api-work-packages.service'; import {HalResource} from '../api/api-v3/hal-resources/hal-resource.service'; -import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; -import {Observable, Subject} from 'rxjs'; import { WorkPackageResource, WorkPackageResourceInterface } from '../api/api-v3/hal-resources/work-package-resource.service'; -import {input, State} from 'reactivestates'; -import {WorkPackageEditingService} from '../wp-edit-form/work-package-editing-service'; +import {ApiWorkPackagesService} from '../api/api-work-packages/api-work-packages.service'; +import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {WorkPackageChangeset} from '../wp-edit-form/work-package-changeset'; export class WorkPackageCreateService { diff --git a/frontend/app/components/wp-query-menu/wp-query-menu.service.ts b/frontend/app/components/wp-query-menu/wp-query-menu.service.ts index d371aea095..7c88fcb561 100644 --- a/frontend/app/components/wp-query-menu/wp-query-menu.service.ts +++ b/frontend/app/components/wp-query-menu/wp-query-menu.service.ts @@ -26,11 +26,12 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {wpServicesModule} from '../../angular-modules'; import {input} from 'reactivestates'; +import {distinctUntilChanged, filter} from 'rxjs/operators'; +import {wpServicesModule} from '../../angular-modules'; export type QueryMenuEvent = { - event:'add'|'remove'|'rename'; + event:'add' | 'remove' | 'rename'; queryId:string; path?:string; label?:string; @@ -41,27 +42,27 @@ export class QueryMenuService { /** * Add a query menu item - * @param {string} queryId - * @param {string} name */ public add(name:string, path:string, queryId:string) { - this.events.putValue({ event: 'add', queryId: queryId, path: path, label: name }); + this.events.putValue({event: 'add', queryId: queryId, path: path, label: name}); } public rename(queryId:string, name:string) { - this.events.putValue({ event: 'rename', queryId: queryId, label: name }); + this.events.putValue({event: 'rename', queryId: queryId, label: name}); } public remove(queryId:string) { - this.events.putValue({ event: 'remove', queryId: queryId, label: queryId }); + this.events.putValue({event: 'remove', queryId: queryId, label: queryId}); } public on(type:string) { return this.events .values$() - .filter((e:QueryMenuEvent) => e.event === type) - .distinctUntilChanged(); + .pipe( + filter((e:QueryMenuEvent) => e.event === type), + distinctUntilChanged() + ); } } -wpServicesModule.service('queryMenu', QueryMenuService) +wpServicesModule.service('queryMenu', QueryMenuService); diff --git a/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts b/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts index 5ac8fec4b3..c33b265bb2 100644 --- a/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations-hierarchy/wp-relations-hierarchy.directive.ts @@ -26,10 +26,11 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -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-packages/work-package-cache.service"; +import {take} from 'rxjs/operators'; +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-packages/work-package-cache.service'; export class WorkPackageRelationsHierarchyController { public workPackage:WorkPackageResourceInterface; @@ -60,7 +61,9 @@ export class WorkPackageRelationsHierarchyController { scopedObservable( this.$scope, this.wpCacheService.loadWorkPackage(this.workPackage.parent.id).values$()) - .take(1) + .pipe( + take(1) + ) .subscribe((parent:WorkPackageResourceInterface) => { this.workPackage.parent = parent; }); diff --git a/frontend/app/components/wp-relations/wp-relations.directive.ts b/frontend/app/components/wp-relations/wp-relations.directive.ts index 92c5d135e6..b5aa84aae7 100644 --- a/frontend/app/components/wp-relations/wp-relations.directive.ts +++ b/frontend/app/components/wp-relations/wp-relations.directive.ts @@ -26,7 +26,10 @@ // See doc/COPYRIGHT.rdoc for more details. //++ -import {Observable} from 'rxjs'; +import {StateService} from '@uirouter/core'; +import {Observable} from 'rxjs/Observable'; +import {zip} from 'rxjs/observable/zip'; +import {take} from 'rxjs/operators'; import {wpDirectivesModule} from '../../angular-modules'; import {scopedObservable} from '../../helpers/angular-rx-utils'; import {RelationResourceInterface} from '../api/api-v3/hal-resources/relation-resource.service'; @@ -34,7 +37,7 @@ import {WorkPackageResourceInterface} from '../api/api-v3/hal-resources/work-pac import {WorkPackageCacheService} from '../work-packages/work-package-cache.service'; import {RelatedWorkPackagesGroup} from './wp-relations.interfaces'; import {RelationsStateValue, WorkPackageRelationsService} from './wp-relations.service'; -import {StateService} from '@uirouter/core'; + export class WorkPackageRelationsController { public relationGroups:RelatedWorkPackagesGroup; @@ -43,7 +46,7 @@ export class WorkPackageRelationsController { // By default, group by relation type public groupByWorkPackageType = false; - public currentRelations:RelationResourceInterface[] = []; + public currentRelations:WorkPackageResourceInterface[] = []; constructor(protected $scope:ng.IScope, protected $q:ng.IQService, @@ -70,18 +73,12 @@ export class WorkPackageRelationsController { }); } - protected getRelatedWorkPackages(workPackageIds:string[]) { - let observablesToGetZipped = workPackageIds.map(wpId => { + private getRelatedWorkPackages(workPackageIds:string[]):Observable { + let observablesToGetZipped:Observable[] = workPackageIds.map(wpId => { return scopedObservable(this.$scope, this.wpCacheService.loadWorkPackage(wpId).values$()); }); - if (observablesToGetZipped.length > 1) { - return Observable - .zip - .apply(Observable, observablesToGetZipped); - } - - return observablesToGetZipped[0]; + return zip(observablesToGetZipped); } protected getRelatedWorkPackageId(relation:RelationResourceInterface):string { @@ -126,12 +123,10 @@ export class WorkPackageRelationsController { }); this.getRelatedWorkPackages(relatedWpIds) - .take(1) - .subscribe((relatedWorkPackages:any) => { - if (!angular.isArray(relatedWorkPackages)) { - relatedWorkPackages = [relatedWorkPackages]; - } - + .pipe( + take(1) + ) + .subscribe((relatedWorkPackages:WorkPackageResourceInterface[]) => { this.currentRelations = relatedWorkPackages.map((wp:WorkPackageResourceInterface) => { wp.relatedBy = relations[wp.id]; return wp; diff --git a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts index c86fc9cd40..d71ebe1096 100644 --- a/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts +++ b/frontend/app/components/wp-single-view-tabs/activity-panel/activity-base.controller.ts @@ -26,13 +26,14 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; -import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; import {OnDestroy, OnInit} from '@angular/core'; -import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {WorkPackagesActivityService} from 'core-components/wp-single-view-tabs/activity-panel/wp-activity.service'; import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; import {ActivityEntryInfo} from 'core-components/wp-single-view-tabs/activity-panel/activity-entry-info'; +import {WorkPackagesActivityService} from 'core-components/wp-single-view-tabs/activity-panel/wp-activity.service'; +import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; +import {WorkPackageResourceInterface} from '../../api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageCacheService} from '../../work-packages/work-package-cache.service'; export class ActivityPanelBaseController implements OnInit, OnDestroy { public workPackage:WorkPackageResourceInterface; @@ -65,7 +66,9 @@ export class ActivityPanelBaseController implements OnInit, OnDestroy { ngOnInit() { this.wpCacheService.loadWorkPackage(this.workPackageId) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((wp:WorkPackageResourceInterface) => { this.workPackage = wp; this.wpActivity.aggregateActivities(this.workPackage).then((activities:any) => { diff --git a/frontend/app/components/wp-single-view-tabs/keep-tab/keep-tab.service.ts b/frontend/app/components/wp-single-view-tabs/keep-tab/keep-tab.service.ts index febe4db7f5..b4733e224e 100644 --- a/frontend/app/components/wp-single-view-tabs/keep-tab/keep-tab.service.ts +++ b/frontend/app/components/wp-single-view-tabs/keep-tab/keep-tab.service.ts @@ -26,12 +26,13 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {ReplaySubject} from "rxjs"; -import {Transition, StateService, TransitionService} from '@uirouter/core'; +import {StateService, Transition, TransitionService} from '@uirouter/core'; +import {ReplaySubject} from 'rxjs/ReplaySubject'; + export class KeepTabService { protected currentTab:string = 'overview'; - protected subject = new ReplaySubject<{ [tab: string]: string; }>(1); + protected subject = new ReplaySubject<{ [tab:string]:string; }>(1); constructor(public $state:StateService, protected $transitions:TransitionService) { diff --git a/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts b/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts index 401e10ed10..def4d03661 100644 --- a/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts +++ b/frontend/app/components/wp-single-view-tabs/overview-tab/overview-tab.component.ts @@ -26,12 +26,14 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {Component, Inject, Input, OnDestroy} from '@angular/core'; +import {Component, Inject, OnDestroy} from '@angular/core'; import {Transition} from '@uirouter/core'; -import {I18nToken} from '../../../angular4-transition-utils'; -import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; +import {I18nToken} from '../../../angular4-transition-utils'; + @Component({ template: require('!!raw-loader!./overview-tab.html'), selector: 'wp-overview-tab', @@ -48,7 +50,9 @@ export class WorkPackageOverviewTabComponent implements OnDestroy { this.workPackageId = this.$transition.params('to').workPackageId; wpCacheService.loadWorkPackage(this.workPackageId) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((wp) => this.workPackage = wp); } diff --git a/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts b/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts index 826846dbaf..89721b7605 100644 --- a/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts +++ b/frontend/app/components/wp-single-view-tabs/relations-tab/relations-tab.component.ts @@ -26,12 +26,13 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {Transition} from '@uirouter/core'; -import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {Component, Inject, OnDestroy} from '@angular/core'; -import {I18nToken} from '../../../angular4-transition-utils'; +import {Transition} from '@uirouter/core'; import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; +import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; +import {I18nToken} from '../../../angular4-transition-utils'; @Component({ template: require('!!raw-loader!./relations-tab.html'), @@ -48,7 +49,9 @@ export class WorkPackageRelationsTabComponent implements OnDestroy { this.workPackageId = this.$transition.params('to').workPackageId; wpCacheService.loadWorkPackage(this.workPackageId) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((wp) => this.workPackage = wp); } diff --git a/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts b/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts index dab5f3deff..9da0a20e88 100644 --- a/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts +++ b/frontend/app/components/wp-single-view-tabs/watchers-tab/watchers-tab.component.ts @@ -26,17 +26,18 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {Transition} from '@uirouter/core'; -import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; import {Component, ElementRef, Inject, OnDestroy, OnInit} from '@angular/core'; -import {I18nToken} from '../../../angular4-transition-utils'; -import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; -import {componentDestroyed} from 'ng2-rx-componentdestroyed'; -import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; +import {Transition} from '@uirouter/core'; import {CollectionResource} from 'core-components/api/api-v3/hal-resources/collection-resource.service'; +import {HalResource} from 'core-components/api/api-v3/hal-resources/hal-resource.service'; import {UserResource} from 'core-components/api/api-v3/hal-resources/user-resource.service'; -import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notification.service'; +import {WorkPackageResourceInterface} from 'core-components/api/api-v3/hal-resources/work-package-resource.service'; import {LoadingIndicatorService} from 'core-components/common/loading-indicator/loading-indicator.service'; +import {WorkPackageCacheService} from 'core-components/work-packages/work-package-cache.service'; +import {WorkPackageNotificationService} from 'core-components/wp-edit/wp-notification.service'; +import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; +import {I18nToken} from '../../../angular4-transition-utils'; @Component({ template: require('!!raw-loader!./watchers-tab.html'), @@ -77,7 +78,9 @@ export class WorkPackageWatchersTabComponent implements OnInit, OnDestroy { this.workPackageId = this.$transition.params('to').workPackageId; this.wpCacheService.loadWorkPackage(this.workPackageId) .values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe((wp) => { this.workPackage = wp; this.loadCurrentWatchers(); @@ -127,7 +130,7 @@ export class WorkPackageWatchersTabComponent implements OnInit, OnDestroy { } as any); input.focus(() => input.autocomplete('search', input.val())); - (input.autocomplete("instance")as any)._renderItem = (ul:any, item:any) => this.renderWatcherItem( + (input.autocomplete('instance')as any)._renderItem = (ul:any, item:any) => this.renderWatcherItem( ul, item); } @@ -155,7 +158,7 @@ export class WorkPackageWatchersTabComponent implements OnInit, OnDestroy { if (item.watcher.avatar) { const img = document.createElement('img'); - img.src = item.watcher.avatar + img.src = item.watcher.avatar; img.alt = item.watcher.name; img.classList.add('avatar-mini'); @@ -174,7 +177,7 @@ export class WorkPackageWatchersTabComponent implements OnInit, OnDestroy { } public autocompleteWatchers(query:string):Promise { - let payload:any = {sortBy: JSON.stringify([["name", "asc"]])} + let payload:any = {sortBy: JSON.stringify([['name', 'asc']])}; if (query && query.length > 0) { let filter = { @@ -182,7 +185,7 @@ export class WorkPackageWatchersTabComponent implements OnInit, OnDestroy { operator: '~', values: query, } - } + }; payload['filters'] = JSON.stringify([filter]); } diff --git a/frontend/app/components/wp-table/sort-header/sort-header.directive.ts b/frontend/app/components/wp-table/sort-header/sort-header.directive.ts index abf6a9b2dc..6bd14d5c90 100644 --- a/frontend/app/components/wp-table/sort-header/sort-header.directive.ts +++ b/frontend/app/components/wp-table/sort-header/sort-header.directive.ts @@ -34,6 +34,7 @@ import { } from 'core-components/api/api-v3/hal-resources/query-sort-by-resource.service'; import {RelationQueryColumn, TypeRelationQueryColumn} from 'core-components/wp-query/query-column'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {takeUntil} from 'rxjs/operators'; import {WorkPackageTableHierarchiesService} from '../../wp-fast-table/state/wp-table-hierarchy.service'; import {WorkPackageTableRelationColumnsService} from '../../wp-fast-table/state/wp-table-relation-columns.service'; import {WorkPackageTableSortByService} from '../../wp-fast-table/state/wp-table-sort-by.service'; @@ -89,7 +90,9 @@ export class SortHeaderDirective implements OnDestroy, AfterViewInit { this.element = jQuery(this.elementRef.nativeElement); this.wpTableSortBy.onReadyWithAvailable() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe(() => { let latestSortElement = this.wpTableSortBy.currentSortBys[0]; @@ -132,14 +135,18 @@ export class SortHeaderDirective implements OnDestroy, AfterViewInit { // Disable hierarchy mode when group by is active this.wpTableGroupBy.state.values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe(() => { this.isHierarchyDisabled = this.wpTableGroupBy.isEnabled; }); // Update hierarchy icon when updated elsewhere this.wpTableHierarchies.state.values$() - .takeUntil(componentDestroyed(this)) + .pipe( + takeUntil(componentDestroyed(this)) + ) .subscribe(() => { this.setHierarchyIcon(); }); diff --git a/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.test.ts b/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.test.ts index 77f890762c..055bb7d9ff 100644 --- a/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.test.ts +++ b/frontend/app/components/wp-table/table-pagination/wp-table-pagination.component.test.ts @@ -26,8 +26,8 @@ // See doc/COPYRIGHT.rdoc for more details. // ++ -import {BehaviorSubject} from 'rxjs'; import {PaginationService} from 'core-components/table-pagination/pagination-service'; +import {BehaviorSubject} from 'rxjs/BehaviorSubject'; describe.skip('wpTablePagination Directive', function () { var compile:any, element:any, rootScope:any, scope:any, paginationService:PaginationService, paginationOptions:any; diff --git a/frontend/app/components/wp-table/table-state/table-state.ts b/frontend/app/components/wp-table/table-state/table-state.ts index fb16bc7f01..7b6a5ab2d0 100644 --- a/frontend/app/components/wp-table/table-state/table-state.ts +++ b/frontend/app/components/wp-table/table-state/table-state.ts @@ -15,7 +15,8 @@ import {WorkPackageTableSum} from 'app/components/wp-fast-table/wp-table-sum'; import {WorkPackageTableTimelineState} from 'app/components/wp-fast-table/wp-table-timeline'; import {WPTableRowSelectionState} from 'app/components/wp-fast-table/wp-table.interfaces'; import {derive, input, State, StatesGroup} from 'reactivestates'; -import {Subject} from 'rxjs/Rx'; +import {map} from 'rxjs/operators'; +import {Subject} from 'rxjs/Subject'; export class TableState extends StatesGroup { @@ -49,8 +50,9 @@ export class TableState extends StatesGroup { // State to be updated when the table is up to date rendered = input(); - renderedWorkPackages:State = derive(this.rendered, $ => $ - .map(rows => rows.filter(row => !!row.workPackageId))); + renderedWorkPackages:State = derive(this.rendered, $ => $.pipe( + map(rows => rows.filter(row => !!row.workPackageId))) + ); // State to determine timeline visibility timelineVisible = input(); diff --git a/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts b/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts index 9bb99fecda..3b5272f2a9 100644 --- a/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts +++ b/frontend/app/components/wp-table/timeline/container/wp-timeline-container.directive.ts @@ -30,6 +30,7 @@ import {AfterViewInit, Component, ElementRef, Inject, Injector, OnDestroy} from import {TableStateHolder} from 'core-components/wp-table/table-state/table-state'; import {Moment} from 'moment'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; +import {filter, map, take, takeUntil, withLatestFrom} from 'rxjs/operators'; import {I18nToken, NotificationsServiceToken} from '../../../../angular4-transition-utils'; import {debugLog, timeOutput} from '../../../../helpers/debug_output'; import {TypeResource} from '../../../api/api-v3/hal-resources/type-resource.service'; @@ -136,8 +137,10 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest // Refresh timeline view after table rendered this.tableState.get().rendered.values$() - .takeUntil(this.tableState.get().stopAllSubscriptions) - .filter(() => this.initialized) + .pipe( + takeUntil(this.tableState.get().stopAllSubscriptions), + filter(() => this.initialized) + ) .subscribe((orderedRows) => { // Remember all visible rows in their order of appearance. this.workPackageIdOrder = orderedRows.filter(row => !row.hidden); @@ -145,17 +148,21 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest }); this.tableState.get().timelineAutoZoom.values$() - .takeUntil(this.tableState.get().stopAllSubscriptions) - .filter(() => this.initialized) - .filter((enabled:boolean) => enabled) + .pipe( + takeUntil(this.tableState.get().stopAllSubscriptions), + filter(() => this.initialized), + filter((enabled:boolean) => enabled) + ) .subscribe(() => { this.refreshView(); }); // Refresh timeline view when becoming visible this.tableState.get().timelineVisible.values$() - .filter((timelineState:WorkPackageTableTimelineState) => timelineState.isVisible) - .takeUntil(componentDestroyed(this)) + .pipe( + filter((timelineState:WorkPackageTableTimelineState) => timelineState.isVisible), + takeUntil(componentDestroyed(this)) + ) .subscribe((timelineState:WorkPackageTableTimelineState) => { this.viewParameters.settings.zoomLevel = timelineState.zoomLevel; this.debouncedRefresh(); @@ -164,8 +171,10 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest // Load the types whenever the timeline is first visible // TODO: Load only necessary types from API this.tableState.get().timelineVisible.values$() - .filter((timelineState) => timelineState.isVisible) - .take(1) + .pipe( + filter((timelineState) => timelineState.isVisible), + take(1) + ) .subscribe(() => { TypeResource.loadAll().then(() => { this.debouncedRefresh(); @@ -249,11 +258,13 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest updateOnWorkPackageChanges() { this.states.workPackages.observeChange() - .withLatestFrom(this.tableState.get().timelineVisible.values$()) - .takeUntil(componentDestroyed(this)) - .filter(([, timelineState]) => this.initialized && timelineState.isVisible) - .map(([[wpId]]) => wpId) - .filter((wpId) => this.cellsRenderer.hasCell(wpId)) + .pipe( + withLatestFrom(this.tableState.get().timelineVisible.values$()), + takeUntil(componentDestroyed(this)), + filter(([, timelineState]) => this.initialized && timelineState.isVisible), + map(([[wpId]]) => wpId), + filter((wpId) => this.cellsRenderer.hasCell(wpId)) + ) .subscribe((wpId) => { const viewParamsChanged = this.calculateViewParams(this._viewParameters); if (viewParamsChanged) { @@ -361,9 +372,9 @@ export class WorkPackageTimelineTableController implements AfterViewInit, OnDest // We may still have a reference to a row that, e.g., just got deleted const workPackage = this.states.workPackages.get(wpId).value!; - const startDate = workPackage.startDate ? moment(workPackage.startDate) :currentParams.now; - const dueDate = workPackage.dueDate ? moment(workPackage.dueDate) :currentParams.now; - const date = workPackage.date ? moment(workPackage.date) :currentParams.now; + const startDate = workPackage.startDate ? moment(workPackage.startDate) : currentParams.now; + const dueDate = workPackage.dueDate ? moment(workPackage.dueDate) : currentParams.now; + const date = workPackage.date ? moment(workPackage.date) : currentParams.now; // start date newParams.dateDisplayStart = moment.min( diff --git a/frontend/app/components/wp-table/timeline/global-elements/wp-timeline-relations.directive.ts b/frontend/app/components/wp-table/timeline/global-elements/wp-timeline-relations.directive.ts index 31b07a10dd..a94f6a9fbb 100644 --- a/frontend/app/components/wp-table/timeline/global-elements/wp-timeline-relations.directive.ts +++ b/frontend/app/components/wp-table/timeline/global-elements/wp-timeline-relations.directive.ts @@ -30,7 +30,8 @@ import {Component, ElementRef, Injector, OnDestroy, OnInit} from '@angular/core' import {TableStateHolder} from 'core-components/wp-table/table-state/table-state'; import {componentDestroyed} from 'ng2-rx-componentdestroyed'; import {State} from 'reactivestates'; -import {Observable} from 'rxjs/Observable'; +import {combineLatest} from 'rxjs/observable/combineLatest'; +import {filter, map, take, takeUntil} from 'rxjs/operators'; import {States} from '../../../states.service'; import {RelationsStateValue, WorkPackageRelationsService} from '../../../wp-relations/wp-relations.service'; import {WorkPackageTimelineCell} from '../cells/wp-timeline-cell'; @@ -119,13 +120,15 @@ export class WorkPackageTableTimelineRelations implements OnInit, OnDestroy { */ private setupRelationSubscription() { // for all visible WorkPackage rows... - Observable.combineLatest( + combineLatest( this.tableState.get().renderedWorkPackages.values$(), this.tableState.get().timelineVisible.values$() ) - .filter(([rendered, timeline]) => timeline.isVisible) - .takeUntil(componentDestroyed(this)) - .map(([rendered, _]) => rendered) + .pipe( + filter(([rendered, timeline]) => timeline.isVisible), + takeUntil(componentDestroyed(this)), + map(([rendered, _]) => rendered) + ) .subscribe(list => { // ... make sure that the corresponding relations are loaded ... const wps = _.compact(list.map(row => row.workPackageId) as string[]); @@ -137,7 +140,9 @@ export class WorkPackageTableTimelineRelations implements OnInit, OnDestroy { // ... once they are loaded, display them. relationsForWorkPackage.values$() - .take(1) + .pipe( + take(1) + ) .subscribe(() => { this.renderWorkPackagesRelations([wpId]); }); @@ -146,8 +151,10 @@ export class WorkPackageTableTimelineRelations implements OnInit, OnDestroy { // When a WorkPackage changes, redraw the corresponding relations this.states.workPackages.observeChange() - .takeUntil(componentDestroyed(this)) - .filter(() => this.tableState.get().timelineVisible.mapOr(v => v.visible, false)) + .pipe( + takeUntil(componentDestroyed(this)), + filter(() => this.tableState.get().timelineVisible.mapOr(v => v.visible, false)) + ) .subscribe(([workPackageId]) => { this.renderWorkPackagesRelations([workPackageId]); }); diff --git a/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts b/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts index adce061f0c..7bc91645a3 100644 --- a/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts +++ b/frontend/app/components/wp-table/wp-table-sums-row/wp-table-sums-row.directive.ts @@ -29,6 +29,7 @@ import {AfterViewInit, Directive, ElementRef, Inject, Injector} from '@angular/core'; import {TableStateHolder} from 'core-components/wp-table/table-state/table-state'; import {combine} from 'reactivestates'; +import {takeUntil} from 'rxjs/operators'; import {I18nToken} from '../../../angular4-transition-utils'; import {SchemaResource} from '../../api/api-v3/hal-resources/schema-resource.service'; import {WorkPackageCollectionResourceInterface} from '../../api/api-v3/hal-resources/wp-collection-resource.service'; @@ -69,7 +70,9 @@ export class WorkPackageTableSumsRowController implements AfterViewInit { this.tableState.get().sum ) .values$() - .takeUntil(this.tableState.get().stopAllSubscriptions) + .pipe( + takeUntil(this.tableState.get().stopAllSubscriptions) + ) .subscribe(([columns, resource, sum]) => { if (sum.isEnabled && resource.sumsSchema) { resource.sumsSchema.$load().then((schema:SchemaResource) => { diff --git a/frontend/app/helpers/angular-rx-utils.ts b/frontend/app/helpers/angular-rx-utils.ts index 860b9848e1..a24eb9796f 100644 --- a/frontend/app/helpers/angular-rx-utils.ts +++ b/frontend/app/helpers/angular-rx-utils.ts @@ -1,28 +1,45 @@ -import IScope = angular.IScope; -import {Observable, Observer, Subscriber} from "rxjs"; -import {TeardownLogic} from "rxjs/Subscription"; - -// export class ScopedOperator { +// -- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2018 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-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. // -// constructor(public readonly scope: IScope) { -// } +// 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. // -// call(subscriber: Subscriber, source: any): TeardownLogic { -// const scoped = scopedObservable(this.scope, source); -// return scoped.subscribe(); -// } -// } +// 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 IScope = angular.IScope; +import {Observable} from 'rxjs/Observable'; +import {Observer} from 'rxjs/Observer'; -export function runInScopeDigest(scope: IScope, fn: () => void) { - if (scope.$root.$$phase !== "$apply" && scope.$root.$$phase !== "$digest") { +export function runInScopeDigest(scope:IScope, fn:() => void) { + if (scope.$root.$$phase !== '$apply' && scope.$root.$$phase !== '$digest') { scope.$apply(fn); } else { fn(); } } -export function scopedObservable(scope: IScope, observable: Observable): Observable { - return Observable.create((observer: Observer) => { +export function scopedObservable(scope:IScope, observable:Observable):Observable { + return Observable.create((observer:Observer) => { var disposable = observable.subscribe( value => { runInScopeDigest(scope, () => observer.next(value)); @@ -35,27 +52,27 @@ export function scopedObservable(scope: IScope, observable: Observable): O } ); - scope.$on("$destroy", () => { + scope.$on('$destroy', () => { return disposable.unsubscribe(); }); }); } -export function asyncTest(done: (error?: any) => void, fn: (value: T) => any): (T:any) => any { - return (value: T) => { +export function asyncTest(done:(error?:any) => void, fn:(value:T) => any):(T:any) => any { + return (value:T) => { try { fn(value); done(); } catch (err) { done(err); } - } + }; } -export function scopeDestroyed$(scope: IScope): Observable { +export function scopeDestroyed$(scope:IScope):Observable { return Observable.create((s:Observer) => { - scope.$on("$destroy", () => { + scope.$on('$destroy', () => { s.next(scope); s.complete(); }); diff --git a/frontend/npm-shrinkwrap.json b/frontend/npm-shrinkwrap.json index 7cac78a656..8288d9e843 100644 --- a/frontend/npm-shrinkwrap.json +++ b/frontend/npm-shrinkwrap.json @@ -244,11 +244,6 @@ "rollup-plugin-visualizer": "0.2.1" } }, - "URIjs": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/URIjs/-/URIjs-1.16.1.tgz", - "integrity": "sha1-7evGeLi3SyawXStIHhI4P1rgS4s=" - }, "accepts": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz", @@ -502,6 +497,12 @@ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -615,6 +616,17 @@ "callsite": "1.0.0" } }, + "bfj-node4": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bfj-node4/-/bfj-node4-5.2.1.tgz", + "integrity": "sha512-w+OTPD/R0AvDVR/sy/uVUVeoCpEgUoYj9/1P2zB6mR1yx7F/ADzLX4nlvZ/91WWzGgdZnuLxWP/J89D7ZDt0DA==", + "dev": true, + "requires": { + "bluebird": "3.5.1", + "check-types": "7.3.0", + "tryer": "1.0.0" + } + }, "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", @@ -894,6 +906,12 @@ "integrity": "sha1-VThNavz4xrndSD6DR2RqeQ5FRec=", "dev": true }, + "check-types": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-7.3.0.tgz", + "integrity": "sha1-Ro9XGkQ1wkJI9f0MsOjYfDw0Hn0=", + "dev": true + }, "chokidar": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", @@ -901,7 +919,6 @@ "requires": { "anymatch": "1.3.2", "async-each": "1.0.1", - "fsevents": "1.1.3", "glob-parent": "2.0.0", "inherits": "2.0.3", "is-binary-path": "1.0.1", @@ -1458,6 +1475,12 @@ } } }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, "ecc-jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", @@ -1473,6 +1496,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "ejs": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz", + "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=", + "dev": true + }, "electron-to-chromium": { "version": "1.3.33", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.33.tgz", @@ -2168,6 +2197,12 @@ "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" }, + "filesize": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.0.tgz", + "integrity": "sha512-g5OWtoZWcPI56js1DFhIEqyG9tnu/7sG3foHwgS9KGYFMfsYguI3E+PRVCmtmE96VajQIEMRU2OhN+ME589Gdw==", + "dev": true + }, "fill-range": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", @@ -2318,795 +2353,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", - "optional": true, - "requires": { - "nan": "2.8.0", - "node-pre-gyp": "0.6.39" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true, - "optional": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "aproba": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "optional": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.39", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "1.0.2", - "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" - } - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true - }, - "semver": { - "version": "5.3.0", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "optional": true - } - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - } - } - }, "fuse.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-3.2.0.tgz", @@ -3186,6 +2432,24 @@ "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", "dev": true }, + "gzip-size": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-4.1.0.tgz", + "integrity": "sha1-iuCWJX6r59acRb4rZ8RIEk/7UXw=", + "dev": true, + "requires": { + "duplexer": "0.1.1", + "pify": "3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, "happypack": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/happypack/-/happypack-4.0.1.tgz", @@ -4396,12 +3660,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "nan": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz", - "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=", - "optional": true - }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", @@ -4624,6 +3882,12 @@ "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=", "dev": true }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -5911,6 +5175,14 @@ "xtend": "4.0.1" } }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -5940,14 +5212,6 @@ } } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - }, "stringmap": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/stringmap/-/stringmap-0.2.2.tgz", @@ -6082,6 +5346,12 @@ "promise": "2.0.0" } }, + "tryer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.0.tgz", + "integrity": "sha1-Antp+oIyJeVRys4+8DsR9qs3wdc=", + "dev": true + }, "tryor": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/tryor/-/tryor-0.1.2.tgz", @@ -6299,6 +5569,11 @@ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "URIjs": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/URIjs/-/URIjs-1.16.1.tgz", + "integrity": "sha1-7evGeLi3SyawXStIHhI4P1rgS4s=" + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -6589,6 +5864,79 @@ } } }, + "webpack-bundle-analyzer": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-2.11.1.tgz", + "integrity": "sha512-VKUVkVMc6TWVXmF1OxsBXoiRjYiDRA4XT0KqtbLMDK+891VX7FCuklYwzldND8J2upUcHHnuXYNTP+4mSFi4Kg==", + "dev": true, + "requires": { + "acorn": "5.4.1", + "bfj-node4": "5.2.1", + "chalk": "2.3.1", + "commander": "2.14.1", + "ejs": "2.5.7", + "express": "4.16.2", + "filesize": "3.6.0", + "gzip-size": "4.1.0", + "lodash": "4.17.5", + "mkdirp": "0.5.1", + "opener": "1.4.3", + "ws": "4.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "1.9.1" + } + }, + "chalk": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.1.tgz", + "integrity": "sha512-QUU4ofkDoMIVO7hcx1iPTISs88wsO8jA92RQIm4JAwZvFGGAV2hSAA1NX7oVj2Ej2Q6NDTcRDjPTFrMCRZoJ6g==", + "dev": true, + "requires": { + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.3.0" + } + }, + "commander": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.14.1.tgz", + "integrity": "sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", + "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, + "requires": { + "has-flag": "3.0.0" + } + }, + "ws": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", + "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", + "dev": true, + "requires": { + "async-limiter": "1.0.0", + "safe-buffer": "5.1.1" + } + } + } + }, "webpack-dev-middleware": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", diff --git a/frontend/package.json b/frontend/package.json index 2136829c33..ac6ac6c430 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -24,6 +24,7 @@ "sinon": "^1.17.5", "sinon-chai": "^2.8.0", "sorted-object": "^1.0.0", + "webpack-bundle-analyzer": "2.11.1", "webpack-dev-server": "^1.6.5" }, "dependencies": { diff --git a/frontend/webpack-main-config.js b/frontend/webpack-main-config.js index 8253684626..fd52463256 100644 --- a/frontend/webpack-main-config.js +++ b/frontend/webpack-main-config.js @@ -39,6 +39,7 @@ var ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); var HappyPack = require('happypack'); var ExtractTextPlugin = require('extract-text-webpack-plugin'); var CleanWebpackPlugin = require('clean-webpack-plugin'); +var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; var mode = (process.env['RAILS_ENV'] || 'production').toLowerCase(); var production = (mode !== 'development'); @@ -288,7 +289,8 @@ function getWebpackMainConfig() { ), // Restrict loaded moment locales to the ones we load from translations - new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, new RegExp('(' + localeIds.join('|') + ')\.js$', 'i')) + new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, new RegExp('(' + localeIds.join('|') + ')\.js$', 'i')), + new BundleAnalyzerPlugin() ] };