my-test123
Version:
A planner front-end for Fabric8.
981 lines • 59.3 kB
JavaScript
import { EventService } from './../../services/event.service';
import { AreaService } from '../../services/area.service';
import { FilterService } from '../../services/filter.service';
import { Observable } from 'rxjs/Observable';
import { IterationService } from '../../services/iteration.service';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Component, ElementRef, ViewChild, ViewChildren, ViewEncapsulation, Renderer2, HostListener } from '@angular/core';
import { Router, NavigationStart, ActivatedRoute } from '@angular/router';
import { cloneDeep, sortBy } from 'lodash';
import { Broadcaster, Logger, NotificationType, Notifications } from 'ngx-base';
import { AuthenticationService, UserService } from 'ngx-login-client';
import { Spaces } from 'ngx-fabric8-wit';
// import for column
import { datatableColumn } from './datatable-config';
import { GroupTypesService } from '../../services/group-types.service';
import { WorkItemService } from '../../services/work-item.service';
import { WorkItemDataService } from './../../services/work-item-data.service';
import { CollaboratorService } from '../../services/collaborator.service';
import { LabelService } from '../../services/label.service';
import { UrlService } from './../../services/url.service';
import { CookieService } from './../../services/cookie.service';
// ngrx stuff
import { Store } from '@ngrx/store';
var PlannerListComponent = /** @class */ (function () {
function PlannerListComponent(labelService, cookieService, areaService, auth, broadcaster, collaboratorService, eventService, filterService, groupTypesService, iterationService, logger, notifications, user, workItemService, workItemDataService, route, router, spaces, userService, urlService, renderer, store) {
this.labelService = labelService;
this.cookieService = cookieService;
this.areaService = areaService;
this.auth = auth;
this.broadcaster = broadcaster;
this.collaboratorService = collaboratorService;
this.eventService = eventService;
this.filterService = filterService;
this.groupTypesService = groupTypesService;
this.iterationService = iterationService;
this.logger = logger;
this.notifications = notifications;
this.user = user;
this.workItemService = workItemService;
this.workItemDataService = workItemDataService;
this.route = route;
this.router = router;
this.spaces = spaces;
this.userService = userService;
this.urlService = urlService;
this.renderer = renderer;
this.store = store;
this.selectType = 'checkbox';
this.showTree = true;
this.resolvedWorkItems = [];
this.wiParentIds = [];
this.selectedRows = [];
this.detailExpandedRows = [];
this.expanded = {};
this.datatableWorkitems = [];
this.isTableConfigOpen = false;
this.emptyStateConfig = {};
this.workItems = [];
this.prevWorkItemLength = 0;
this.workItemTypes = [];
this.currentWorkItem = null;
this.addingWorkItem = false;
this.loggedIn = false;
this.contentItemHeight = 50;
this.pageSize = 20;
this.filters = [];
this.allUsers = [];
this.authUser = null;
this.eventListeners = [];
this.showHierarchyList = true;
this.sidePanelOpen = true;
this.spaceSubscription = null;
this.iterations = [];
this.areas = [];
this.nextLink = '';
this.wiSubscriber = null;
this.allowedFilterParams = ['iteration'];
this.loggedInUser = {};
this.originalList = [];
this.labels = [];
this.uiLockedAll = false;
this.uiLockedList = true;
this.uiLockedSidebar = false;
this.children = [];
this.currentExpandedChildren = [];
this.expandedNode = null;
this.selectedWI = null;
this.groupTypes = [];
this.quickAddContext = [];
this.initialGroup = [];
this._lastTagetContentHeight = 0;
this._scrollTrigger = 5;
this._lastCheckedScrollHeight = 0;
}
PlannerListComponent.prototype.ngOnInit = function () {
this.store.subscribe(function (val) {
console.log('####-1', val);
});
// If there is an iteration on the URL
// Setting the value to currentIteration
// BehaviorSubject so that we can compare
// on update the value on URL
var queryParams = this.route.snapshot.queryParams;
if (Object.keys(queryParams).length === 0 || process.env.ENV == 'inmemory') {
this.setDefaultUrl();
}
else {
if (Object.keys(queryParams).indexOf('iteration') > -1) {
this.currentIteration = new BehaviorSubject(queryParams['iteration']);
}
else {
this.currentIteration = new BehaviorSubject(null);
}
}
this.listenToEvents();
this.loggedIn = this.auth.isLoggedIn();
// Cookie for datatableColumn config
if (!this.cookieService.getCookie(datatableColumn.length).status) {
this.cookieService.setCookie('datatableColumn', datatableColumn);
this.columns = datatableColumn;
}
else {
var temp = this.cookieService.getCookie(datatableColumn.length);
this.columns = temp.array;
}
this.emptyStateConfig = {
info: 'There are no Work Items for your selected criteria',
title: 'No Work Items Available'
};
};
PlannerListComponent.prototype.ngAfterViewChecked = function () {
var oldHeight = 0;
this.authUser = cloneDeep(this.route.snapshot.data['authuser']);
if (this.workItems.length != this.prevWorkItemLength) {
//this.treeList.update();
this.prevWorkItemLength = this.workItems.length;
}
if (this.toolbarHeight) {
var toolbarHt = this.toolbarHeight.nativeElement.offsetHeight;
var quickaddHt = 0;
if (document.getElementsByClassName('f8-wi-list__quick-add-wrapper').length > 0) {
quickaddHt = document.getElementsByClassName('f8-wi-list__quick-add-wrapper')[0].offsetHeight;
}
var hdrHeight = 0;
if (document.getElementsByClassName('navbar-pf').length > 0) {
hdrHeight = document.getElementsByClassName('navbar-pf')[0].offsetHeight;
}
var expHeight = 0;
var targetHeight = void 0;
var targetContHeight = void 0;
if (document.getElementsByClassName('experimental-bar').length > 0) {
expHeight = document.getElementsByClassName('experimental-bar')[0].offsetHeight;
}
else if (document.getElementsByClassName('system-error-bar').length > 0) {
expHeight = document.getElementsByClassName('system-error-bar')[0].offsetHeight;
}
targetHeight = window.innerHeight - (toolbarHt + quickaddHt + hdrHeight + expHeight);
this.renderer.setStyle(this.listContainer.nativeElement, 'height', targetHeight + "px");
targetContHeight = window.innerHeight - (hdrHeight + expHeight);
this.renderer.setStyle(this.containerHeight.nativeElement, 'height', targetContHeight - 3 + "px");
if (document.getElementsByClassName('experimental-bar').length > 0 &&
!document.getElementsByClassName('experimental-bar')[0].classList.contains('experimental-bar-minimal')) {
expHeight = document.getElementsByClassName('experimental-bar')[0].offsetHeight;
targetHeight = window.innerHeight - (toolbarHt + quickaddHt + hdrHeight + expHeight);
this.renderer.setStyle(this.listContainer.nativeElement, 'height', targetHeight + "px");
targetContHeight = window.innerHeight - (hdrHeight + expHeight);
this.renderer.setStyle(this.containerHeight.nativeElement, 'height', targetContHeight - 3 + "px");
}
else if (document.getElementsByClassName('experimental-bar').length > 0 &&
document.getElementsByClassName('experimental-bar')[0].classList.contains('experimental-bar-minimal')) {
targetHeight = window.innerHeight - (toolbarHt + quickaddHt + hdrHeight);
this.renderer.setStyle(this.listContainer.nativeElement, 'height', targetHeight - 25 + "px");
}
if (this._lastTagetContentHeight !== targetContHeight) {
this._lastTagetContentHeight = targetContHeight;
this.initWiItems(Math.ceil(targetContHeight / this.contentItemHeight) + 20); // +20 is for demo purpose
}
}
if (document.getElementsByClassName('planner-hack-title-truncate').length) {
var arr = document.getElementsByClassName('planner-hack-title-truncate');
for (var i = 0; i < arr.length; i++) {
arr[i].parentElement.style.display = 'flex';
}
}
if (document.getElementsByTagName('body')) {
document.getElementsByTagName('body')[0].style.overflow = "hidden";
}
};
PlannerListComponent.prototype.onResize = function (event) {
};
PlannerListComponent.prototype.ngOnDestroy = function () {
console.log('Destroying all the listeners in list component');
this.iterationService.resetIterations();
this.eventListeners.forEach(function (subscriber) { return subscriber.unsubscribe(); });
if (this.spaceSubscription) {
this.spaceSubscription.unsubscribe();
}
document.getElementsByTagName('body')[0].style.overflow = "auto";
};
PlannerListComponent.prototype.setDefaultUrl = function () {
var _this = this;
//redirect to default type group
//get space id
this.spaces.current.subscribe(function (space) {
if (space) {
var spaceId_1 = space.id;
//get groupsgroups
_this.groupTypesService.getGroupTypes().subscribe(function (groupTypes) {
var defaultGroupName = groupTypes[0].attributes.name;
_this.groupTypesService.setCurrentGroupType(groupTypes[0].relationships.typeList, groupTypes[0].attributes.bucket);
//Query for work item type group
var type_query = _this.filterService.queryBuilder('typegroup.name', _this.filterService.equal_notation, defaultGroupName);
//Query for space
var space_query = _this.filterService.queryBuilder('space', _this.filterService.equal_notation, spaceId_1);
//Join type and space query
var first_join = _this.filterService.queryJoiner({}, _this.filterService.and_notation, space_query);
var second_join = _this.filterService.queryJoiner(first_join, _this.filterService.and_notation, type_query);
var query = _this.filterService.jsonToQuery(second_join);
_this.router.navigate([], {
relativeTo: _this.route,
queryParams: { q: query }
});
});
}
});
};
// model handlers
PlannerListComponent.prototype.initWiItems = function (pageSize) {
var _this = this;
this.pageSize = pageSize;
// Space subscription should only listen to changes
// till the page is changed to something else.
// Unsubscribe in ngOnDestroy acts way after the new page inits
// So using takeUntill to watch over the routes in case of any change
var takeUntilObserver = this.router.events
.filter(function (event) { return event instanceof NavigationStart; })
.filter(function (event) {
return event.url.indexOf('plan/board') > -1 ||
event.url.indexOf('plan/detail') > -1 ||
event.url.indexOf('plan') == -1;
});
this.spaceSubscription =
// On any of these event inside combineLatest
// We load the work items
Observable.combineLatest(this.spaces.current, this.filterService.filterChange,
//this.currentIteration,
this.route.queryParams, this.eventService.showHierarchyListSubject,
// only emits workItemReload when hierarchy view is on
this.eventService.workItemListReloadOnLink.filter(function () { return _this.showHierarchyList; }))
.takeUntil(takeUntilObserver)
.subscribe(function (_a) {
var space = _a[0], activeFilter = _a[1],
//iteration,
queryParams = _a[2], showHierarchyList = _a[3], workItemListReload = _a[4];
if (showHierarchyList) {
_this.logger.log('Switching to hierarchy list mode.');
}
else {
_this.logger.log('Switching to flat list mode.');
}
_this.showHierarchyList = showHierarchyList;
if (space) {
console.log('[WorkItemListComponent] New Space selected: ' + space.attributes.name);
_this.currentSpace = space;
_this.loadWorkItems();
}
else {
console.log('[WorkItemListComponent] Space deselected');
_this.workItems = [];
_this.datatableWorkitems = [];
}
});
this.filterService.getFilters().subscribe(function (filters) {
return filters.forEach(function (f) { return _this.filters.push(f.attributes.key); });
});
};
PlannerListComponent.prototype.getCurrentGroupType = function () {
//if initialGroup is undefined, the page has been refreshed - find group context based on URL
if (this.route.snapshot.queryParams['q']) {
var urlArray = this.route.snapshot.queryParams['q'].split('typegroup.name:');
if (urlArray.length > 1) {
//If wit group is one of the parameters
var ind = urlArray[1].indexOf(' $AND ');
var witGroupName_1 = '';
if (ind >= 0) {
witGroupName_1 = urlArray[1].substring(0, ind);
}
else {
//if wit group is the last query
witGroupName_1 = urlArray[1].replace(')', '');
}
var witGroupList = this.groupTypesService.getWitGroupList();
if (witGroupList.length > 0) {
var selectedWitGroup = witGroupList.find(function (witg) { return witg.attributes.name === witGroupName_1; });
this.groupTypesService.setCurrentGroupType(selectedWitGroup.relationships.typeList.data, witGroupName_1);
}
}
else {
this.initialGroup = this.groupTypesService.getCurrentGroupType();
}
}
else {
//redirect to the first group type hierachy
this.initialGroup = this.groupTypesService.getCurrentGroupType();
//set the url
}
};
PlannerListComponent.prototype.loadWorkItems = function () {
var _this = this;
var queryParams = this.route.snapshot.queryParams;
if (Object.keys(queryParams).length === 0)
this.setDefaultUrl();
this.uiLockedList = true;
if (this.wiSubscriber) {
this.wiSubscriber.unsubscribe();
}
this.children = [];
var t1 = performance.now();
this.wiSubscriber = Observable.combineLatest(this.iterationService.getIterations(),
// this.collaboratorService.getCollaborators(),
this.workItemService.getWorkItemTypes(), this.areaService.getAreas(), this.userService.getUser().catch(function (err) { return Observable.of({}); }), this.labelService.getLabels(), this.groupTypesService.getGroupTypes()).take(1).do(function (items) {
var iterations = _this.iterations = items[0];
_this.workItemTypes = items[1];
_this.areas = items[2];
_this.loggedInUser = items[3];
_this.labels = items[4];
_this.groupTypes = items[5];
_this.getCurrentGroupType();
//set the context for the quick add based on which type group is selected
_this.quickAddContext = _this.groupTypesService.getCurrentGroupType();
})
.switchMap(function (items) {
var appliedFilters = _this.filterService.getAppliedFilters(true);
// remove the filter item from the filters
for (var f = 0; f < appliedFilters.length; f++) {
if (appliedFilters[f].paramKey == 'filter[parentexists]') {
appliedFilters.splice(f, 1);
}
}
_this.logger.log('Requesting work items with filters: ' + JSON.stringify(appliedFilters));
var newFilterObj = {};
appliedFilters.forEach(function (item) {
newFilterObj[item.id] = item.value;
});
var payload = {};
if (_this.route.snapshot.queryParams['q']) {
var urlString = _this.route.snapshot.queryParams['q']
.replace(' ', '')
.replace('$AND', ' ')
.replace('$OR', ' ')
.replace('(', '')
.replace(')', '');
var temp_arr = urlString.split(' ');
for (var i = 0; i < temp_arr.length; i++) {
var arr = temp_arr[i].split(':');
//check if it belongs in filter array
if (_this.filters.indexOf(arr[0]) < 0 && arr[1] !== undefined)
newFilterObj[arr[0]] = arr[1];
}
var exp = _this.filterService.queryToJson(_this.filterService.constructQueryURL('', newFilterObj));
exp['$OPTS'] = { 'tree-view': true };
Object.assign(payload, {
expression: exp
});
}
else {
var exp = _this.filterService.queryToJson(_this.filterService.constructQueryURL('', newFilterObj));
exp['$OPTS'] = { 'tree-view': true };
Object.assign(payload, {
expression: exp
});
}
return Observable.forkJoin(Observable.of(_this.iterations), Observable.of(_this.workItemTypes),
// TODO implement search API mock for inmemory
process.env.ENV == 'inmemory' ? _this.workItemService.getWorkItems(_this.pageSize, appliedFilters) :
_this.workItemService.getWorkItems2(_this.pageSize, payload));
})
.subscribe(function (_a) {
var iterations = _a[0], wiTypes = _a[1], workItemResp = _a[2];
var t2 = performance.now();
console.log('Performance :: Fetching the initial list - ' + (t2 - t1) + ' milliseconds.');
_this.logger.log('Got work item list.');
_this.logger.log(workItemResp.workItems);
var workItems = workItemResp.workItems;
_this.nextLink = workItemResp.nextLink;
_this.nonMatchingParentIds = workItemResp.ancestorIDs;
var included = workItemResp.included;
_this.wiLength = 0;
_this.resolvedWorkItems = _this.workItemService.resolveWorkItems(workItems, _this.iterations, [], // We don't want to static resolve user at this point
_this.workItemTypes, _this.labels);
_this.included = _this.workItemService.resolveWorkItems(included, _this.iterations, [], // We don't want to static resolve user at this point
_this.workItemTypes, _this.labels);
_this.wiParentIds = _this.getParentIdsAll(_this.resolvedWorkItems).concat(_this.getParentIdsAll(_this.included));
_this.resolvedIncludedAC = false;
_this.updateTableWorkitems();
_this.workItemDataService.setItems(_this.workItems);
// Resolve assignees and creator
if (!_this.workItems || _this.workItems.length == 0) {
// if there are no work items, unlock the ui here
_this.uiLockedList = false;
}
if (!_this.resolvedIncludedAC)
_this.resolveCreatorAssignee();
// this.originalList = cloneDeep(this.workItems);
}, function (err) {
console.log('Error in Work Item list', err);
_this.uiLockedList = false;
});
};
PlannerListComponent.prototype.fetchMoreWiItems = function () {
var _this = this;
var t1 = performance.now();
this.workItemService
.getMoreWorkItems(this.nextLink)
.subscribe(function (newWiItemResp) {
var t2 = performance.now();
var workItems = newWiItemResp.workItems;
_this.nextLink = newWiItemResp.nextLink;
_this.wiLength = _this.workItems.length;
var ancestorIDs = newWiItemResp.ancestorIDs;
var newItems = _this.workItemService.resolveWorkItems(workItems, _this.iterations, [], _this.workItemTypes, _this.labels).filter(function (item) {
return _this.workItems.findIndex(function (i) { return i.id === item.id; }) === -1;
});
_this.resolvedWorkItems = _this.resolvedWorkItems.concat(newItems);
var newIncluded = _this.workItemService.resolveWorkItems(newWiItemResp.included, _this.iterations, [], _this.workItemTypes, _this.labels).filter(function (item) {
return _this.included.findIndex(function (i) { return i.id === item.id; }) === -1;
});
_this.wiParentIds = _this.wiParentIds.concat(_this.getParentIdsAll(newItems), _this.getParentIdsAll(newIncluded));
_this.nonMatchingParentIds = _this.nonMatchingParentIds.concat(ancestorIDs);
_this.included = _this.included.concat(newIncluded);
_this.resolvedIncludedAC = false;
_this.updateTableWorkitems();
_this.workItemDataService.setItems(_this.workItems);
console.log('Performance :: Fetching more list items - ' + (t2 - t1) + ' milliseconds.');
// Resolve assignees and creator
if (!_this.resolvedIncludedAC) {
_this.resolveCreatorAssignee(_this.wiLength);
}
}, function (e) { return console.log(e); });
};
PlannerListComponent.prototype.resolveCreatorAssignee = function (wiLength) {
var _this = this;
if (wiLength === void 0) { wiLength = 0; }
// resolve assignees
var t3 = performance.now();
this.workItems.slice(wiLength).forEach(function (item, index) {
_this.workItemService.resolveAssignees(item.relationships.assignees).take(1)
.subscribe(function (assignees) {
item.relationships.assignees.data = assignees;
// After the assignees is resolved
// We should add it to the datatableWorkitems
_this.datatableWorkitems[wiLength + index].assignees = assignees;
if (index == _this.workItems.length - 1) {
var t4 = performance.now();
console.log('Performance :: Resolved all the users - ' + (t4 - t3) + ' milliseconds.');
_this.uiLockedList = false;
}
});
});
// Resolve creators
var t5 = performance.now();
var allCreatorURLs = this.workItems.slice(wiLength).reduce(function (uniqueItems, workItem) {
if (!uniqueItems.find(function (item) {
return item.relationships.creator.data.id ===
workItem.relationships.creator.data.id;
})) {
return uniqueItems.concat([workItem]);
}
else {
return uniqueItems;
}
}, [])
.map(function (item) {
return item.relationships.creator.data.links.self;
});
this.workItemService.getUsersByURLs(allCreatorURLs)
.subscribe(function (creators) {
_this.workItems.slice(wiLength).forEach(function (item, index) {
item.relationships.creator.data = creators.find(function (creator) {
if (item.relationships.creator.data.id === creator.id) {
// After the assignees is resolved
// We should add it to the datatableWorkitems
_this.datatableWorkitems[wiLength + index].creator = creator;
return true;
}
else {
return false;
}
});
});
var t6 = performance.now();
console.log('Performance :: Resolved all the creators - ' + (t6 - t5) + ' milliseconds.');
});
};
PlannerListComponent.prototype.updateTableWorkitems = function () {
if (this.showTree) {
this.datatableWorkitems = this.tableWorkitem(this.resolvedWorkItems, null, true).concat(this.tableWorkitem(this.included, null, false));
this.workItems = this.resolvedWorkItems.concat(this.included);
if (!this.resolvedIncludedAC) {
this.resolveCreatorAssignee(this.wiLength);
this.resolvedIncludedAC = true;
}
}
else {
this.datatableWorkitems = this.tableWorkitem(this.resolvedWorkItems).slice();
this.workItems = this.resolvedWorkItems.slice();
}
};
PlannerListComponent.prototype.loadChildren = function (workItem) {
var _this = this;
return this.workItemService.getChildren(workItem)
.map(function (workItems) {
workItems.map(function (wi) {
wi.relationships.parent = { data: {} };
wi.relationships.parent.data = workItem;
});
return workItems;
})
.map(function (workItems) { return _this.workItemService.resolveWorkItems(workItems, _this.iterations, [], // We don't want to static resolve user at this point
_this.workItemTypes, _this.labels); })
.do(function (workItems) {
// filter out childrens are not loaded yet
var childrenItems = workItems
.filter(function (i) {
return _this.datatableWorkitems
.findIndex(function (item) { return item.id === i.id; }) === -1;
});
_this.datatableWorkitems = _this.datatableWorkitems.concat(_this.tableWorkitem(childrenItems, workItem.id));
return workItems;
})
.map(function (workItems) {
var startIndex = _this.workItems.length;
_this.workItems = _this.workItems.concat(workItems);
_this.workItemDataService.setItems(_this.workItems);
return { workItems: workItems, startIndex: startIndex };
})
.map(function (values) {
// Resolve creator
var allCreatorURLs = _this.workItems.slice(values.startIndex).reduce(function (uniqueItems, workItem) {
if (!uniqueItems.find(function (item) {
return item.relationships.creator.data.id ===
workItem.relationships.creator.data.id;
})) {
return uniqueItems.concat([workItem]);
}
else {
return uniqueItems;
}
}, [])
.map(function (item) {
return item.relationships.creator.data.links.self;
});
_this.workItemService.getUsersByURLs(allCreatorURLs)
.subscribe(function (creators) {
_this.workItems.slice(values.startIndex).forEach(function (item, index) {
item.relationships.creator.data = creators.find(function (creator) {
if (item.relationships.creator.data.id === creator.id) {
// After the assignees is resolved
// We should add it to the datatableWorkitems
_this.datatableWorkitems[values.startIndex + index].creator = creator;
return true;
}
else {
return false;
}
});
});
});
// Resolve assignees
var allAssigneeURLs = _this.workItems.slice(values.startIndex).reduce(function (urls, workItem) {
var assigneeURLs = workItem.relationships.assignees.data ?
workItem.relationships.assignees.data.map(function (assignee) {
return assignee.links.self;
}) : [];
return urls.concat(assigneeURLs);
}, []).reduce(function (uniqueURLs, url) {
if (!uniqueURLs.find(function (item) { return item === url; })) {
return uniqueURLs.concat([url]);
}
else {
return uniqueURLs;
}
}, []);
_this.workItemService.getUsersByURLs(allAssigneeURLs)
.subscribe(function (assignees) {
_this.workItems.slice(values.startIndex).forEach(function (item, index) {
item.relationships.assignees.data = assignees.filter(function (assignee) {
return item.relationships.assignees.data
.findIndex(function (a) { return a.id === assignee.id; }) > -1;
});
_this.datatableWorkitems[values.startIndex + index].assignees =
item.relationships.assignees.data;
});
});
return values.workItems;
});
};
PlannerListComponent.prototype.getParentIdsAll = function (items) {
return items.reduce(function (parentIds, item) {
var parentid = item.relationships.parent && item.relationships.parent.data ?
item.relationships.parent.data.id : null;
if (parentid && parentIds.findIndex(function (i) { return i === parentid; }) === -1) {
return parentIds.concat([parentid]);
}
return parentIds;
}, []);
};
PlannerListComponent.prototype.onPreview = function (id) {
var _this = this;
this.workItemDataService.getItem(id).subscribe(function (workItem) {
_this.detailPreview.openPreview(workItem);
});
};
PlannerListComponent.prototype.onCreateWorkItemStart = function (event) {
var parentId = event.parentId;
if (parentId) {
var index = this.datatableWorkitems.findIndex(function (i) { return i.id === parentId; });
if (index > -1) {
this.datatableWorkitems[index].treeStatus = 'loading';
this.table.rowDetail.collapseAllRows();
this.detailExpandedRows = [];
}
}
};
PlannerListComponent.prototype.onCreateWorkItem = function (workItem) {
this.workItems = [workItem].concat(this.workItems);
this.resolvedWorkItems = [workItem].concat(this.resolvedWorkItems);
this.datatableWorkitems = this.tableWorkitem([this.workItems[0]]).concat(this.datatableWorkitems);
this.workItemDataService.setItems([this.workItems[0]]);
};
PlannerListComponent.prototype.onMoveToTop = function (id) {
var _this = this;
this.workItemDataService.getItem(id).subscribe(function (workItem) {
_this.workItemDetail = workItem;
_this.workItemService.reOrderWorkItem(_this.workItemDetail, null, 'top')
.subscribe(function (updatedWorkItem) {
var currentIndex = _this.workItems.findIndex(function (item) { return item.id === updatedWorkItem.id; });
// Putting on top of the list
_this.workItems.splice(0, 0, _this.workItems[currentIndex]);
// Removing duplicate old item
_this.workItems.splice(currentIndex + 1, 1);
// Remove duplicate from datatable workitems
_this.datatableWorkitems.splice(currentIndex, 1);
_this.workItems[0].attributes['version'] = updatedWorkItem.attributes['version'];
// Update datatable WorkItems
_this.datatableWorkitems = _this.tableWorkitem([_this.workItems[0]]).concat(_this.datatableWorkitems);
});
});
};
PlannerListComponent.prototype.onMoveToBottom = function (id) {
var _this = this;
this.workItemDataService.getItem(id).subscribe(function (workItem) {
_this.workItemDetail = workItem;
_this.workItemService.reOrderWorkItem(_this.workItemDetail, null, 'bottom')
.subscribe(function (updatedWorkItem) {
var currentIndex = _this.workItems.findIndex(function (item) { return item.id === updatedWorkItem.id; });
//move the item as the last of the loaded list
_this.workItems.splice((_this.workItems.length), 0, _this.workItems[currentIndex]);
//remove the duplicate element
_this.workItems.splice(currentIndex, 1);
// remove duplicate from datatable
_this.datatableWorkitems.splice(currentIndex, 1);
_this.workItems[_this.workItems.length - 1].attributes['version'] = updatedWorkItem.attributes['version'];
// Update datatable WorkItems
_this.datatableWorkitems = _this.datatableWorkitems.concat(_this.tableWorkitem([_this.workItems[_this.workItems.length - 1]]));
_this.listContainer.nativeElement.scrollTop = _this.workItems.length * _this.contentItemHeight;
});
});
};
PlannerListComponent.prototype.onAssociateIteration = function (id) {
var _this = this;
this.workItemDataService.getItem(id).subscribe(function (item) {
_this.currentWorkItem = item;
_this.associateIterationModal.workItem = item;
_this.associateIterationModal.open();
});
};
PlannerListComponent.prototype.onOpen = function (id) {
var _this = this;
this.workItemDataService.getItem(id).subscribe(function (item) {
var link = _this.router.url.split('/list')[0] + '/detail/' + item.id;
_this.router.navigateByUrl(link, { relativeTo: _this.route });
});
};
PlannerListComponent.prototype.onMoveToBacklog = function (id) {
var _this = this;
this.workItemDataService.getItem(id).subscribe(function (item) {
item.relationships.iteration = {};
_this.workItemService
.update(item)
.switchMap(function (item) {
return _this.iterationService.getIteration(item.relationships.iteration)
.map(function (iteration) {
item.relationships.iteration.data = iteration;
return item;
});
})
.subscribe(function (workItem) {
//update only the relevant fields
var index = _this.workItems.findIndex(function (wi) { return wi.id === item.id; });
_this.workItems[index].relationships.iteration.data = workItem.relationships.iteration.data;
_this.workItems[index].attributes['version'] = workItem.attributes['version'];
try {
_this.notifications.message({
message: workItem.attributes['system.title'] + ' has been moved to the Backlog.',
type: NotificationType.SUCCESS
});
}
catch (e) {
console.log('Error displaying notification. Iteration was moved to Backlog.');
}
}, function (err) {
try {
_this.notifications.message({
message: item.attributes['system.title'] + ' could not be moved to the Backlog.',
type: NotificationType.DANGER
});
}
catch (e) {
console.log('Error displaying notification. Error moving Iteration to Backlog.');
}
});
});
};
// This opens the create new work item dialog. It parses the query string
// first to get iterationId and areaId for pre-selection in the new work item
// dialog. Note that this only works for the current capabilities of the query
// toolbar for now. If we extend that, we also need to extend this method.
PlannerListComponent.prototype.onCreateFromContext = function () {
console.log('Activated create work item from a list view.');
var query = this.route.snapshot.queryParams['q'];
if (query) {
var contextIteration = this.filterService.getConditionFromQuery(query, "iteration");
var contextArea = this.filterService.getConditionFromQuery(query, "area");
this.typeSelectPanel.openPanel(contextIteration, contextArea);
}
else {
console.log('No current query for add from empty list');
// use standard non-context create dialog
this.typeSelectPanel.openPanel();
}
};
PlannerListComponent.prototype.listenToEvents = function () {
var _this = this;
this.eventListeners.push(this.broadcaster.on('logout')
.subscribe(function (message) {
_this.loggedIn = false;
_this.authUser = null;
//this.treeListOptions['allowDrag'] = false;
}));
this.eventListeners.push(this.broadcaster.on('detail_close')
.subscribe(function () {
// this.selectedWorkItemEntryComponent.deselect();
}));
this.eventListeners.push(this.workItemService.addWIObservable
.subscribe(function (item) {
var resolvedworkItem = _this.workItemService.resolveWorkItems([item.wi], _this.iterations, [], _this.workItemTypes, _this.labels)[0];
// Resolve creator
resolvedworkItem.relationships.creator.data = _this.loggedInUser;
_this.onCreateWorkItem(resolvedworkItem);
if (_this.filterService.doesMatchCurrentFilter(resolvedworkItem)) {
try {
_this.notifications.message({
message: resolvedworkItem.attributes['system.title'] + ' created.',
type: NotificationType.SUCCESS
});
}
catch (e) {
console.log('Error displaying notification. Added WI matches the applied filters.');
}
}
else {
try {
_this.notifications.message({
message: resolvedworkItem.attributes['system.title'] + ' created. Added WI does not match the applied filters',
type: NotificationType.SUCCESS
});
}
catch (e) {
console.log('Error displaying notification. Added WI does not match the applied filters.');
}
}
if (item.status) {
_this.onDetailPreview(resolvedworkItem.id);
}
}));
this.eventListeners.push(this.workItemService.addWIChildObservable
.subscribe(function (workitemDetail) {
var parentIndex = _this.datatableWorkitems.findIndex(function (i) { return i.id === workitemDetail.pwid; });
if (parentIndex > -1) {
_this.datatableWorkitems[parentIndex].treeStatus = 'collapsed';
_this.datatableWorkitems[parentIndex].childrenLoaded = false;
_this.onTreeAction({
rowIndex: parentIndex,
row: _this.datatableWorkitems[parentIndex]
});
}
if (workitemDetail.status) {
_this.onDetailPreview(workitemDetail.wid);
}
}));
this.eventListeners.push(this.workItemService.editWIObservable.subscribe(function (updatedItem) {
var index = _this.workItems.findIndex(function (item) { return item.id === updatedItem.id; });
var bold = _this.datatableWorkitems.filter(function (item) { return item.id === updatedItem.id; })[0].bold;
if (_this.filterService.doesMatchCurrentFilter(updatedItem)) {
updatedItem.hasChildren = updatedItem.relationships.children.meta.hasChildren;
updatedItem.relationships['parent'] = _this.workItems[index].relationships.parent;
if (index > -1) {
_this.workItems[index] = updatedItem;
var resolvedWorkItemsIndex = _this.resolvedWorkItems.findIndex(function (item) { return item.id === updatedItem.id; });
var includedIndex = _this.included.findIndex(function (item) { return item.id === updatedItem.id; });
if (resolvedWorkItemsIndex > -1)
_this.resolvedWorkItems[resolvedWorkItemsIndex] = updatedItem;
if (includedIndex > -1)
_this.included[includedIndex] = updatedItem;
var updatedTableItem = _this.tableWorkitem([updatedItem], _this.datatableWorkitems[index].parentId, bold)[0];
updatedTableItem.treeStatus = _this.datatableWorkitems[index].treeStatus;
updatedTableItem.childrenLoaded = _this.datatableWorkitems[index].childrenLoaded;
_this.datatableWorkitems = _this.datatableWorkitems.slice(0, index).concat([
updatedTableItem
], _this.datatableWorkitems.slice(index + 1));
}
else {
//Scenario: work item detail panel is open.
//Change a value so that it does not match the applied filter and gets removed from the list
//The panel is still open - set back the value(s) so that the work item matches the applied
//filters
//add the WI at the top of the list
if (!_this.children.find(function (c) { return c === updatedItem.id; })) {
// If the item is not a child of any other item
_this.workItems.splice(0, 0, updatedItem);
_this.datatableWorkitems = _this.tableWorkitem([updatedItem]).concat(_this.datatableWorkitems);
}
}
try {
_this.notifications.message({
message: updatedItem.attributes['system.title'] + ' updated.',
type: NotificationType.SUCCESS
});
}
catch (e) {
console.log('Error displaying notification. Updated WI matches the applied filters.');
}
}
else {
//Remove the work item from the current displayed list
if (index > -1) {
try {
_this.notifications.message({
message: updatedItem.attributes['system.title'] + ' updated. This work item no longer matches the applied filters.',
type: NotificationType.SUCCESS
});
}
catch (e) {
console.log('Error displaying notification. Updated WI does not match the applied filters.');
}
_this.workItems.splice(index, 1);
}
}
}));
this.eventListeners.push(this.router.events
.filter(function (event) { return event instanceof NavigationStart; })
.subscribe(function (event) {
if (event.url.indexOf('/plan/detail/') > -1) {
// It's going to the detail page
var url = location.pathname;
var query = location.href.split('?');
if (query.length == 2) {
url = url + '?' + query[1];
}
_this.urlService.recordLastListOrBoard(url);
}
}));
// lock the ui when a complex query is starting in the background
this.eventListeners.push(this.broadcaster.on('backend_query_start')
.subscribe(function (context) {
switch (context) {
case 'workitems':
_this.uiLockedList = true;
break;
case 'iterations':
_this.uiLockedSidebar = true;
break;
case 'mixed':
_this.uiLockedAll = true;
break;
default:
break;
}
}));
// unlock the ui when a complex query is completed in the background
this.eventListeners.push(this.broadcaster.on('backend_query_end')
.subscribe(function (context) {
switch (context) {
case 'workitems':
_this.uiLockedList = false;
break;
case 'iterations':
_this.uiLockedSidebar = false;
break;
case 'mixed':
_this.uiLockedAll = false;
break;
default:
break;
}
}));
this.eventListeners.push(this.iterationService.createIterationObservable.subscribe(function (iteration) {
var index = _this.iterations.findIndex(function (i) { return i.id === iteration.id; });
if (index > -1) {
_this.iterations[index] = iteration;
}
else {
_this.iterations.push(iteration);
}
}));
this.eventListeners.push(this.workItemService.showTree.subscribe(function (status) {
_this.showTree = status;
_this.detailExpandedRows = [];
_this.updateTableWorkitems();
}));
};
//ngx-datatable methods
PlannerListComponent.prototype.handleReorder = function (event) {
if (event.newValue !== 0) {
this.columns[event.prevValue - 1].index = event.newValue;
this.columns[event.newValue - 1].index = event.prevValue;
this.columns = sortBy(this.columns, 'index');
this.cookieService.setCookie('datatableColumn', this.columns);
}
};
PlannerListComponent.prototype.onSelect = function (_a) {
var _this = this;
var selected = _a.selected;
if (this.detailExpandedRows.length > 0 && this.detailExpandedRows[0].id !== selected[0].id) {
this.table.rowDetail.collapseAllRows();
this.detailExpandedRows = [];
}
this.workItemDataService.getItem(selected[0].id).subscribe(function (workItem) {
_this.workItemService.emitSelectedWI(workItem);
});
};
PlannerListComponent.prototype.toggleExpandRow = function (row, quickAddEnabled) {
var _this = this;
if (quickAddEnabled === void 0) { quickAddEnabled = true; }
if (quickAddEnabled && this.loggedIn && this.showTree) {
var index = this.detailExpandedRows.findIndex(function (r) { return r.id === row.id; });
if (index > -1) {
// For collapsing
this.table.rowDetail.toggleExpandRow(this.detailExpandedRows[index]);
this.detailExpandedRows.splice(index, 1);
}
else {
// For expanding
this.detailExpandedRows.forEach(function (r) {
_this.table.rowDetail.toggleExpandRow(r);
});
this.detailExpandedRows = [];
this.table.rowDetail.toggleExpandRow(row);
this.detailExpandedRows.push(row);
}
}
};
PlannerListComponent.prototype.onDetailToggle = function (event) {
// console.log('Detail Toggled ####-2', event);
};
PlannerListComponent.prototype.onDetailPreview = function (id) {
event.stopPropagation();
this.router.navigateByUrl(this.router.url.split('plan')[0] + 'plan/detail/' + id, { relativeTo: this.route });
};
PlannerListComponent.prototype.tableWorkitem = function (workItems, parentId, matchingQuery) {
var _this = this;
if (parentId === void 0) { parentId = null; }
if (matchingQuery === void 0) { matchingQuery = false; }
return workItems.map(function (element) {
if (_this.showTree) {
var treeStatus = _this.setTreeStatus(element, matchingQuery);
return {
id: element.id,
number: element.attributes['system.number'],
type: element.relationships.baseType ? ele