From 281d10214ef333e9c34329bd985002668e791f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Wed, 8 Feb 2017 12:53:20 +0100 Subject: [PATCH] observeUntil to scope rx state listeners --- .../routing/wp-list/wp-list.controller.ts | 4 ++-- frontend/app/components/states.service.ts | 18 ++++++------------ .../work-package-cache.service.test.ts | 2 +- .../handlers/cell/edit-cell-handler.ts | 4 ++-- .../handlers/row/click-handler.ts | 4 ++-- .../handlers/row/context-menu-handler.ts | 4 ++-- .../handlers/row/double-click-handler.ts | 4 ++-- .../handlers/row/group-row-handler.ts | 4 ++-- .../handlers/state/columns-transformer.ts | 8 +++++--- .../handlers/state/rows-transformer.ts | 12 ++++++------ .../handlers/state/selection-transformer.ts | 6 ++++-- .../state/wp-table-selection.service.ts | 8 -------- .../components/wp-fast-table/table-helper.ts | 3 --- .../components/wp-table/wp-table.directive.ts | 7 +++++-- frontend/app/helpers/debug_output.ts | 8 ++++---- frontend/app/helpers/reactive-fassade.ts | 10 ++++++++++ 16 files changed, 53 insertions(+), 53 deletions(-) delete mode 100644 frontend/app/components/wp-fast-table/table-helper.ts diff --git a/frontend/app/components/routing/wp-list/wp-list.controller.ts b/frontend/app/components/routing/wp-list/wp-list.controller.ts index f66b86e046..2ed5e67c31 100644 --- a/frontend/app/components/routing/wp-list/wp-list.controller.ts +++ b/frontend/app/components/routing/wp-list/wp-list.controller.ts @@ -158,8 +158,8 @@ function WorkPackagesListController($scope, // yield updatable data to scope Observable.combineLatest( - states.table.columns.observe(null), - states.query.availableColumns.observe(null) + states.table.columns.observeUntil(states.table.stopAllSubscriptions), + states.query.availableColumns.observeUntil(states.table.stopAllSubscriptions) ).subscribe(() => { $scope.columns = wpTableColumns.getColumns(); }); diff --git a/frontend/app/components/states.service.ts b/frontend/app/components/states.service.ts index 0f748ef007..d121b22a65 100644 --- a/frontend/app/components/states.service.ts +++ b/frontend/app/components/states.service.ts @@ -1,4 +1,4 @@ -import {when_debugging} from '../helpers/debug_output'; +import {whenDebugging} from '../helpers/debug_output'; import {WorkPackageTable} from './wp-fast-table/wp-fast-table'; import {WPTableRowSelectionState, WorkPackageTableRow} from './wp-fast-table/wp-table.interfaces'; import {MultiState, initStates, State} from "../helpers/reactive-fassade"; @@ -7,7 +7,7 @@ import {opServicesModule} from "../angular-modules"; import {SchemaResource} from './api/api-v3/hal-resources/schema-resource.service'; import {WorkPackageEditForm} from './wp-edit-form/work-package-edit-form'; import {WorkPackageTableMetadata} from './wp-fast-table/wp-table-metadata'; - +import {Subject} from 'rxjs'; export class States { @@ -28,7 +28,9 @@ export class States { // Current state of collapsed groups (if any) collapsedGroups: new State<{[identifier:string]: boolean}>(), // State to be updated when the table is up to date - rendered:new State() + rendered:new State(), + // Subject used to unregister all listeners of states above. + stopAllSubscriptions:new Subject() }; // Query states @@ -45,7 +47,7 @@ export class States { constructor() { initStates(this, function (msg: any) { - when_debugging(() => { + whenDebugging(() => { console.trace(msg); }); }); @@ -54,11 +56,3 @@ export class States { } opServicesModule.service('states', States); - - - - - - - - diff --git a/frontend/app/components/work-packages/work-package-cache.service.test.ts b/frontend/app/components/work-packages/work-package-cache.service.test.ts index 99f17010da..d6e13e5ea5 100644 --- a/frontend/app/components/work-packages/work-package-cache.service.test.ts +++ b/frontend/app/components/work-packages/work-package-cache.service.test.ts @@ -77,7 +77,7 @@ describe('WorkPackageCacheService', () => { // it('should return a work package once the list gets initialized', () => { // let workPackage: WorkPackageResource = null; // - // wpCacheService.loadWorkPackage(1).observe(null).subscribe(wp => { + // wpCacheService.loadWorkPackage(1).observe($rootScope).subscribe(wp => { // workPackage = wp; // }); // diff --git a/frontend/app/components/wp-fast-table/handlers/cell/edit-cell-handler.ts b/frontend/app/components/wp-fast-table/handlers/cell/edit-cell-handler.ts index c19cb9f320..76699b3d20 100644 --- a/frontend/app/components/wp-fast-table/handlers/cell/edit-cell-handler.ts +++ b/frontend/app/components/wp-fast-table/handlers/cell/edit-cell-handler.ts @@ -1,4 +1,4 @@ -import {debug_log} from '../../../../helpers/debug_output'; +import {debugLog} from '../../../../helpers/debug_output'; import {WorkPackageTable} from '../../wp-fast-table'; import {States} from '../../../states.service'; import {cellClassName, editableClassName} from '../../builders/cell-builder'; @@ -28,7 +28,7 @@ export class EditCellHandler extends ClickOrEnterHandler implements TableEventHa } protected processEvent(table: WorkPackageTable, evt:JQueryEventObject) { - debug_log('Starting editing on cell: ', evt.target); + debugLog('Starting editing on cell: ', evt.target); evt.preventDefault(); // Locate the cell from event diff --git a/frontend/app/components/wp-fast-table/handlers/row/click-handler.ts b/frontend/app/components/wp-fast-table/handlers/row/click-handler.ts index 6db01ce319..c28617b86d 100644 --- a/frontend/app/components/wp-fast-table/handlers/row/click-handler.ts +++ b/frontend/app/components/wp-fast-table/handlers/row/click-handler.ts @@ -1,4 +1,4 @@ -import {debug_log} from '../../../../helpers/debug_output'; +import {debugLog} from '../../../../helpers/debug_output'; import {injectorBridge} from '../../../angular/angular-injector-bridge.functions'; import {WorkPackageTable} from '../../wp-fast-table'; import {States} from '../../../states.service'; @@ -30,7 +30,7 @@ export class RowClickHandler implements TableEventHandler { // Shortcut to any clicks within a cell // We don't want to handle these. if (target.parents(`.${tdClassName}`).length) { - debug_log('Skipping click on inner cell'); + debugLog('Skipping click on inner cell'); return; } diff --git a/frontend/app/components/wp-fast-table/handlers/row/context-menu-handler.ts b/frontend/app/components/wp-fast-table/handlers/row/context-menu-handler.ts index 2e1000c625..a7a202624e 100644 --- a/frontend/app/components/wp-fast-table/handlers/row/context-menu-handler.ts +++ b/frontend/app/components/wp-fast-table/handlers/row/context-menu-handler.ts @@ -1,4 +1,4 @@ -import {debug_log} from '../../../../helpers/debug_output'; +import {debugLog} from '../../../../helpers/debug_output'; import {injectorBridge} from '../../../angular/angular-injector-bridge.functions'; import {WorkPackageTable} from '../../wp-fast-table'; import {States} from '../../../states.service'; @@ -31,7 +31,7 @@ export class ContextMenuHandler implements TableEventHandler { // We want to keep the original context menu on hrefs // (currently, this is only the id if (target.closest(`.${uiStateLinkClass}`).length) { - debug_log('Allowing original context menu on state link'); + debugLog('Allowing original context menu on state link'); return; } evt.preventDefault(); diff --git a/frontend/app/components/wp-fast-table/handlers/row/double-click-handler.ts b/frontend/app/components/wp-fast-table/handlers/row/double-click-handler.ts index 7573454f74..a5ff4447fe 100644 --- a/frontend/app/components/wp-fast-table/handlers/row/double-click-handler.ts +++ b/frontend/app/components/wp-fast-table/handlers/row/double-click-handler.ts @@ -1,4 +1,4 @@ -import {debug_log} from '../../../../helpers/debug_output'; +import {debugLog} from '../../../../helpers/debug_output'; import {injectorBridge} from '../../../angular/angular-injector-bridge.functions'; import {WorkPackageTable} from '../../wp-fast-table'; import {States} from '../../../states.service'; @@ -31,7 +31,7 @@ export class RowDoubleClickHandler implements TableEventHandler { // Shortcut to any clicks within a cell // We don't want to handle these. if (target.parents(`.${tdClassName}`).length) { - debug_log('Skipping click on inner cell'); + debugLog('Skipping click on inner cell'); return; } diff --git a/frontend/app/components/wp-fast-table/handlers/row/group-row-handler.ts b/frontend/app/components/wp-fast-table/handlers/row/group-row-handler.ts index 3c671428f9..38026fa460 100644 --- a/frontend/app/components/wp-fast-table/handlers/row/group-row-handler.ts +++ b/frontend/app/components/wp-fast-table/handlers/row/group-row-handler.ts @@ -1,4 +1,4 @@ -import {debug_log} from '../../../../helpers/debug_output'; +import {debugLog} from '../../../../helpers/debug_output'; import {injectorBridge} from '../../../angular/angular-injector-bridge.functions'; import {WorkPackageTable} from '../../wp-fast-table'; import {States} from '../../../states.service'; @@ -43,7 +43,7 @@ export class GroupRowHandler implements TableEventHandler { var t0 = performance.now(); this.builder.refreshExpansionState(table); var t1 = performance.now(); - debug_log("Group redraw took " + (t1 - t0) + " milliseconds."); + debugLog("Group redraw took " + (t1 - t0) + " milliseconds."); }); } 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 4fd5014fdc..317e109802 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,4 @@ -import {debug_log} from '../../../../helpers/debug_output'; +import {debugLog} from '../../../../helpers/debug_output'; import {States} from '../../../states.service'; import {injectorBridge} from '../../../angular/angular-injector-bridge.functions'; import {WorkPackageTable} from '../../wp-fast-table'; @@ -10,7 +10,9 @@ export class ColumnsTransformer { constructor(public table: WorkPackageTable) { injectorBridge(this); - this.states.table.columns.observe(null).subscribe(() => { + // observeOnScope + // observeUntil + this.states.table.columns.observeUntil(this.states.table.stopAllSubscriptions).subscribe(() => { if (table.rows.length > 0) { var t0 = performance.now(); @@ -22,7 +24,7 @@ export class ColumnsTransformer { table.postRender(); var t1 = performance.now(); - debug_log("column redraw took " + (t1 - t0) + " milliseconds."); + debugLog("column redraw took " + (t1 - t0) + " milliseconds."); } }); } 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 7d17f0f0e8..1872ee2530 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,4 @@ -import {debug_log} from '../../../../helpers/debug_output'; +import {debugLog} from '../../../../helpers/debug_output'; import {locateRow} from '../../helpers/wp-table-row-helpers'; import {States} from '../../../states.service'; import {injectorBridge} from '../../../angular/angular-injector-bridge.functions'; @@ -12,7 +12,7 @@ export class RowsTransformer { injectorBridge(this); // Redraw table if the current row state changed - this.states.table.rows.observe(null) + this.states.table.rows.observeUntil(this.states.table.stopAllSubscriptions) .subscribe((rows:WorkPackageResource[]) => { var t0 = performance.now(); @@ -20,12 +20,12 @@ export class RowsTransformer { table.postRender(); var t1 = performance.now(); - debug_log("[RowTransformer] Reinitialized in " + (t1 - t0) + " milliseconds."); + debugLog("[RowTransformer] Reinitialized in " + (t1 - t0) + " milliseconds."); }); // Refresh a single row if it exists - this.states.workPackages.observe(null) + this.states.workPackages.observeUntil(this.states.table.stopAllSubscriptions) .subscribe((nextVal:[string, WorkPackageResource]) => { if (!nextVal) { return; @@ -48,7 +48,7 @@ export class RowsTransformer { private refreshWorkPackage(table, row) { // If the work package is dirty, we're working on it if (row.object.dirty) { - debug_log("Skipping row " + row.workPackageId + " since its dirty"); + debugLog("Skipping row " + row.workPackageId + " since its dirty"); return; } @@ -56,7 +56,7 @@ export class RowsTransformer { let oldRow = row.element || locateRow(row.workPackageId); if (oldRow.dataset['lockVersion'] === row.object.lockVersion.toString()) { - debug_log("Skipping row " + row.workPackageId + " since its fresh"); + debugLog("Skipping row " + row.workPackageId + " since its fresh"); 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 410470554d..fc3286cca4 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,4 +1,3 @@ - import {WorkPackageTableSelection} from '../../state/wp-table-selection.service'; import {injectorBridge} from '../../../angular/angular-injector-bridge.functions'; import {WPTableRowSelectionState} from '../../wp-table.interfaces'; @@ -6,14 +5,17 @@ import {WorkPackageTable} from '../../wp-fast-table'; import {rowId} from '../../helpers/wp-table-row-helpers'; import {checkedClassName} from '../../builders/ui-state-link-builder'; import {rowClassName} from '../../builders/rows/single-row-builder'; +import {States} from '../../../states.service'; + export class SelectionTransformer { public wpTableSelection:WorkPackageTableSelection; + public states:States; constructor(table:WorkPackageTable) { injectorBridge(this); this.wpTableSelection.selectionState - .observe(null).subscribe((state:WPTableRowSelectionState) => { + .observeUntil(this.states.table.stopAllSubscriptions).subscribe((state:WPTableRowSelectionState) => { this.renderSelectionState(state); }); diff --git a/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts b/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts index 3badddf872..8c8228640d 100644 --- a/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts +++ b/frontend/app/components/wp-fast-table/state/wp-table-selection.service.ts @@ -154,11 +154,3 @@ export class WorkPackageTableSelection { } opServicesModule.service('wpTableSelection', WorkPackageTableSelection); - - - - - - - - diff --git a/frontend/app/components/wp-fast-table/table-helper.ts b/frontend/app/components/wp-fast-table/table-helper.ts deleted file mode 100644 index 2795fc631f..0000000000 --- a/frontend/app/components/wp-fast-table/table-helper.ts +++ /dev/null @@ -1,3 +0,0 @@ -export class TableHelper { - -} \ No newline at end of file diff --git a/frontend/app/components/wp-table/wp-table.directive.ts b/frontend/app/components/wp-table/wp-table.directive.ts index c91b59e746..3f2c116d3e 100644 --- a/frontend/app/components/wp-table/wp-table.directive.ts +++ b/frontend/app/components/wp-table/wp-table.directive.ts @@ -34,7 +34,7 @@ import { WorkPackageCacheService } from '../work-packages/work-package-cache.ser import {WorkPackageDisplayFieldService} from './../wp-display/wp-display-field/wp-display-field.service'; import {WorkPackageTable} from './../wp-fast-table/wp-fast-table'; import {ContextMenuService} from '../context-menus/context-menu.service'; -import {debug_log} from '../../helpers/debug_output'; +import {debugLog} from '../../helpers/debug_output'; angular .module('openproject.workPackages.directives') @@ -78,12 +78,15 @@ function wpTable( link: function(scope, element) { var activeSelectionBorderIndex; + // Clear any old table subscribers + states.table.stopAllSubscriptions.next(); + var t0 = performance.now(); scope.tbody = element.find('.work-package--results-tbody'); scope.table = new WorkPackageTable(scope.tbody[0]); var t1 = performance.now(); - debug_log("Render took " + (t1 - t0) + " milliseconds.") + debugLog("Render took " + (t1 - t0) + " milliseconds.") // Total columns = all available columns + id + checkbox scope.numTableColumns = scope.columns.length + 2; diff --git a/frontend/app/helpers/debug_output.ts b/frontend/app/helpers/debug_output.ts index 9620864141..b842182e98 100644 --- a/frontend/app/helpers/debug_output.ts +++ b/frontend/app/helpers/debug_output.ts @@ -2,8 +2,8 @@ * Execute the callback when DEBUG is defined * through webpack. */ -export function when_debugging(cb) { - if (DEBUG) { +export function whenDebugging(cb) { + if (true) { cb(); } } @@ -12,6 +12,6 @@ export function when_debugging(cb) { * Log with console.log when DEBUG is defined * through webpack. */ -export function debug_log(...args) { - when_debugging(() => console.log('[DEBUG] ', args)); +export function debugLog(...args) { + whenDebugging(() => console.log('[DEBUG] ', args)); } \ No newline at end of file diff --git a/frontend/app/helpers/reactive-fassade.ts b/frontend/app/helpers/reactive-fassade.ts index b0caa0aaf9..31853b67d9 100644 --- a/frontend/app/helpers/reactive-fassade.ts +++ b/frontend/app/helpers/reactive-fassade.ts @@ -187,6 +187,16 @@ export class MultiState extends StoreElement { return scope ? scopedObservable(scope, this.memberSubject) : this.memberSubject; } + /** + * Observe changes on this multistate until another subject is triggered. + * + * @param scope An optional scope + * @returns {Observable} Observable on the changed ids + */ + public observeUntil(subject: Subject): Observable<[string, T]> { + return this.memberSubject.takeUntil(subject); + } + /** * Notify MultiState of a change in member {id}. * @param id The id of the changed member