366 lines
21 KiB
JavaScript
366 lines
21 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Created by andey on 14-12-2016.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
angular.module('releaseModule')
|
|
.directive('releasePlanItemList', ['$q', '$filter', 'relationModel', 'metadataModel', 'relationService', 'systemAlertService', 'events', '$timeout',
|
|
function ($q, $filter, relationModel, metadataModel, relationService, systemAlertService, events, $timeout) {
|
|
return {
|
|
restrict: 'E',
|
|
replace: true,
|
|
templateUrl: 'views/release/release-plan-item-list.html',
|
|
scope: {
|
|
ticket: '=',
|
|
isNew: '=?'
|
|
},
|
|
link: function (scope) {
|
|
scope.state = {
|
|
dataIsLoading: false,
|
|
movingToOtherList: false
|
|
};
|
|
scope.releasePlanGroups = {};
|
|
scope.milestoneFilters = {};
|
|
scope.milestones = {};
|
|
//SW00523525 added check for target url for release profile page.
|
|
scope.isNew === true ? scope.target = '_blank' : scope.target = '_self';
|
|
scope.parentSortableOptions = {
|
|
placeholder: 'profile-relation__item-task-container',
|
|
connectWith: '.profile-relation__release-plan-container',
|
|
cancel: ':input,.locked',
|
|
receive: function (event, ui) {
|
|
var droptargetMilestone = ui.item.sortable.droptargetModel[0].realObject.releaseMilestone;
|
|
if (droptargetMilestone !== ui.item.sortable.model.realObject.releaseMilestone) {
|
|
scope.state.movingToOtherList = true;
|
|
ui.item.sortable.model.realObject.releaseMilestone = droptargetMilestone;
|
|
}
|
|
},
|
|
stop: function (event, ui) {
|
|
var sourceReleasePlanGroup = _.cloneDeep(ui.item.sortable.sourceModel);
|
|
if (scope.state.movingToOtherList) {
|
|
var targetReleasePlanGroup = _.cloneDeep(ui.item.sortable.droptargetModel);
|
|
sortElements(targetReleasePlanGroup);
|
|
scope.state.movingToOtherList = false;
|
|
}
|
|
if (sourceReleasePlanGroup.length) {
|
|
sortElements(sourceReleasePlanGroup);
|
|
}
|
|
else {
|
|
//Remove empty array from list
|
|
var emptyArrayIndex = _.findIndex(scope.releasePlanGroups, function (group) {
|
|
return group.length === 0;
|
|
});
|
|
if (emptyArrayIndex !== -1) {
|
|
scope.releasePlanGroups.splice(emptyArrayIndex, 1);
|
|
}
|
|
}
|
|
function sortElements(releasePlanGroup) {
|
|
var sequence = 1;
|
|
_.forEach(releasePlanGroup, function (item, idx) {
|
|
var sameOrderFlag = false, nextItem = null;
|
|
if ((idx + 1) !== releasePlanGroup.length) {
|
|
nextItem = releasePlanGroup[idx + 1];
|
|
}
|
|
if (nextItem && item.realObject.sequence === nextItem.realObject.sequence
|
|
&& ui.item.sortable.model.id !== nextItem.id) {
|
|
sameOrderFlag = true;
|
|
}
|
|
item.realObject.sequence = sequence;
|
|
sequence = sameOrderFlag ? item.realObject.sequence : (item.realObject.sequence + 1);
|
|
});
|
|
var releasePlanGroupIndex = _.findIndex(scope.releasePlanGroups, function (group) {
|
|
if (group && group.length && releasePlanGroup[0].realObject.releaseMilestone === group[0].realObject.releaseMilestone) {
|
|
return true;
|
|
}
|
|
});
|
|
scope.releasePlanGroups[releasePlanGroupIndex] = releasePlanGroup;
|
|
}
|
|
scope.dirty = true;
|
|
}
|
|
};
|
|
var allReleasePlanGroups = {};
|
|
scope.applyFilter = function (filterOption) {
|
|
if (scope.dirty) {
|
|
var modal = systemAlertService.modal({
|
|
type: 'info',
|
|
title: $filter('i18n')('common.notification.dirty.title'),
|
|
text: $filter('i18n')('common.notification.dirty.loseChanges'),
|
|
buttons: [
|
|
{
|
|
text: $filter('i18n')('common.button.yes'),
|
|
data: true
|
|
},
|
|
{
|
|
text: $filter('i18n')('common.button.no'),
|
|
data: false
|
|
}
|
|
]
|
|
});
|
|
modal.result.then(function (data) {
|
|
if (data) {
|
|
applyFilter(filterOption);
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
applyFilter(filterOption);
|
|
}
|
|
};
|
|
scope.getSelectedFiltersList = function () {
|
|
return _.filter(scope.milestoneFilters, { selected: true });
|
|
};
|
|
scope.selectAll = function (state) {
|
|
_.forEach(scope.milestoneFilters, function (filter) {
|
|
filter.selected = state;
|
|
});
|
|
scope.releasePlanGroups = angular.copy(allReleasePlanGroups);
|
|
};
|
|
scope.updateMilestone = function (selectedMilestone, releasePlanItem) {
|
|
if (releasePlanItem.realObject.releaseMilestone === selectedMilestone.name) {
|
|
return;
|
|
}
|
|
scope.$emit(events.RELEASE_PLAN_MILESTONE_CHANGE);
|
|
//Remove item from old group
|
|
var emptyArrayIndex = _.findIndex(scope.releasePlanGroups, function (group) {
|
|
if (releasePlanItem.realObject.releaseMilestone === group[0].realObject.releaseMilestone) {
|
|
_.remove(group, { id: releasePlanItem.id });
|
|
if (group.length === 0) {
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
//Remove empty array from list
|
|
if (emptyArrayIndex !== -1) {
|
|
scope.releasePlanGroups.splice(emptyArrayIndex, 1);
|
|
}
|
|
//Add item to new group
|
|
var releasePlanGroupIndex = _.findIndex(scope.releasePlanGroups, function (group) {
|
|
if (selectedMilestone.name === group[0].realObject.releaseMilestone) {
|
|
return true;
|
|
}
|
|
});
|
|
if (releasePlanGroupIndex !== -1) {
|
|
scope.releasePlanGroups[releasePlanGroupIndex].push(releasePlanItem);
|
|
}
|
|
else {
|
|
scope.releasePlanGroups.push([releasePlanItem]);
|
|
}
|
|
releasePlanItem.realObject.releaseMilestone = selectedMilestone.name;
|
|
scope.updateItemsSequence(releasePlanItem);
|
|
};
|
|
scope.updateItemsSequence = function (releasePlanItem) {
|
|
if (releasePlanItem.realObject.sequence <= 0 || isNaN(releasePlanItem.realObject.sequence) || _.isEmpty(releasePlanItem.realObject.sequence)) {
|
|
releasePlanItem.realObject.sequence = 1;
|
|
}
|
|
else {
|
|
releasePlanItem.realObject.sequence = parseInt(releasePlanItem.realObject.sequence);
|
|
}
|
|
var releasePlanGroupIndex = _.findIndex(scope.releasePlanGroups, function (group) {
|
|
if (releasePlanItem.realObject.releaseMilestone === group[0].realObject.releaseMilestone) {
|
|
return true;
|
|
}
|
|
});
|
|
var releasePlanGroup = angular.copy(scope.releasePlanGroups[releasePlanGroupIndex]), itemIndex = _.findIndex(releasePlanGroup, function (item) {
|
|
return item.id == releasePlanItem.id;
|
|
});
|
|
releasePlanGroup[itemIndex] = releasePlanItem;
|
|
// Sort items
|
|
releasePlanGroup.sort(function (item1, item2) {
|
|
return (item1.length ? item1[0].realObject.sequence : item1.realObject.sequence)
|
|
- (item2.length ? item2[0].realObject.sequence : item2.realObject.sequence);
|
|
});
|
|
$timeout(function () {
|
|
scope.releasePlanGroups[releasePlanGroupIndex] = releasePlanGroup;
|
|
}, 2000);
|
|
scope.dirty = true;
|
|
};
|
|
scope.saveSequence = function () {
|
|
var releasePlanItems = [];
|
|
_.forEach(scope.releasePlanGroups, function (releaseGroup) {
|
|
var originalReleaseGroup = _.find(allReleasePlanGroups, function (group) {
|
|
if (group.length) {
|
|
return group[0].realObject.releaseMilestone === releaseGroup[0].realObject.releaseMilestone;
|
|
}
|
|
else {
|
|
return false;
|
|
}
|
|
});
|
|
//originalReleaseGroup not found indicates a new milestone group is created.
|
|
if (!originalReleaseGroup) {
|
|
originalReleaseGroup = [];
|
|
}
|
|
_.forEach(releaseGroup, function (releaseItem) {
|
|
//originalItem not found indicates the milestone is updated.
|
|
var originalItem = _.find(originalReleaseGroup, { id: releaseItem.id });
|
|
if (!originalItem || releaseItem.realObject.sequence !== originalItem.realObject.sequence
|
|
|| releaseItem.realObject.releaseMilestone !== originalItem.realObject.releaseMilestone) {
|
|
var releasePlanItem = {
|
|
parentId: scope.ticket.id,
|
|
parentName: EntityVO.TYPE_RELEASE,
|
|
parentDisplayId: scope.ticket.displayId,
|
|
milestone: releaseItem.realObject.releaseMilestone,
|
|
sequence: releaseItem.realObject.sequence,
|
|
id: releaseItem.id,
|
|
displayId: releaseItem.displayId,
|
|
type: releaseItem.type
|
|
};
|
|
releasePlanItems.push(releasePlanItem);
|
|
}
|
|
});
|
|
});
|
|
if (releasePlanItems.length) {
|
|
relationService.updateReleasePlanItemsSequence(releasePlanItems).then(function () {
|
|
refreshList();
|
|
scope.dirty = false;
|
|
scope.$emit(events.RELEASE_PLAN_MILESTONE_NOT_DIRTY);
|
|
}, function (response) {
|
|
systemAlertService.error({
|
|
text: response.data.error,
|
|
clear: false
|
|
});
|
|
$modalInstance.dismiss();
|
|
});
|
|
}
|
|
};
|
|
scope.onRevertClick = function () {
|
|
applyFilter();
|
|
scope.dirty = false;
|
|
};
|
|
scope.removeItem = function (planData) {
|
|
var modalInstance = systemAlertService.modal({
|
|
title: $filter('i18n')('common.notification.delete.title'),
|
|
text: $filter('i18n')('common.notification.delete.message'),
|
|
buttons: [
|
|
{
|
|
text: $filter('i18n')('common.notification.delete.button1'),
|
|
data: true
|
|
},
|
|
{
|
|
text: $filter('i18n')('common.notification.delete.button2'),
|
|
data: false
|
|
}
|
|
]
|
|
});
|
|
modalInstance.result.then(function (data) {
|
|
if (data) {
|
|
if (planData.item.type === EntityVO.TYPE_ACTIVITY) {
|
|
relationModel.deleteActivity(planData.item).then(function () {
|
|
removeReleaseItem(allReleasePlanGroups);
|
|
removeReleaseItem(scope.releasePlanGroups);
|
|
}, function (response) {
|
|
systemAlertService.error({
|
|
text: response.data.error,
|
|
clear: false
|
|
});
|
|
$modalInstance.dismiss();
|
|
});
|
|
}
|
|
else {
|
|
var parent = { parentType: scope.ticket.type, parentId: scope.ticket.id }, relation = {
|
|
id: planData.item.id,
|
|
type: planData.item.type,
|
|
relationshipType: planData.item.relationshipType,
|
|
parentDisplayId: scope.ticket.displayId
|
|
};
|
|
relationModel.removeRelation(parent, [relation]).then(function () {
|
|
//TODO: Check if call returns success
|
|
removeReleaseItem(allReleasePlanGroups);
|
|
removeReleaseItem(scope.releasePlanGroups);
|
|
}, function (response) {
|
|
systemAlertService.error({
|
|
text: response.planData.error,
|
|
clear: false
|
|
});
|
|
$modalInstance.dismiss();
|
|
});
|
|
}
|
|
}
|
|
function removeReleaseItem(releasePlanGroups) {
|
|
_.forEach(releasePlanGroups, function (releaseGroup) {
|
|
if (planData.item.realObject.releaseMilestone === releaseGroup[0].realObject.releaseMilestone) {
|
|
_.remove(releaseGroup, { id: planData.item.id });
|
|
if (releaseGroup.length) {
|
|
scope.ticket.noOfRelatedItems[releaseGroup[0].realObject.releaseMilestone] = releaseGroup.length;
|
|
}
|
|
}
|
|
});
|
|
//Remove empty array from list
|
|
var emptyArrayIndex = _.findIndex(releasePlanGroups, function (group) {
|
|
return group.length === 0;
|
|
});
|
|
if (emptyArrayIndex !== -1) {
|
|
releasePlanGroups.splice(emptyArrayIndex, 1);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
function resetFilter() {
|
|
_.forEach(scope.milestoneFilters, function (item) {
|
|
item.selected = false;
|
|
});
|
|
}
|
|
function applyFilter(filterOption) {
|
|
if (filterOption) {
|
|
filterOption.selected = !filterOption.selected;
|
|
}
|
|
scope.releasePlanGroups = angular.copy(allReleasePlanGroups);
|
|
if (!_.any(scope.milestoneFilters, { selected: true })) { //No filter selected
|
|
return;
|
|
}
|
|
else {
|
|
_.remove(scope.releasePlanGroups, function (releasePlanGroup) {
|
|
//Sometimes releaseMilestone may not be set, checking the same condition using ''.
|
|
return !_.find(scope.milestoneFilters, { name: releasePlanGroup[0].realObject.releaseMilestone || '' }).selected;
|
|
});
|
|
}
|
|
scope.dirty = false;
|
|
}
|
|
function fetchReleasePlanList() {
|
|
return relationModel.getRelationsByTag(scope.ticket.id, scope.ticket.type, 'releasePlan').then(function (response) {
|
|
scope.releasePlanGroups = transformReleaseItems(response);
|
|
allReleasePlanGroups = angular.copy(scope.releasePlanGroups);
|
|
scope.ticket.noOfRelatedItems = {};
|
|
_.forEach(scope.releasePlanGroups, function (releaseGroup) {
|
|
if (releaseGroup.length) {
|
|
scope.ticket.noOfRelatedItems[releaseGroup[0].realObject.releaseMilestone] = releaseGroup.length;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
function transformReleaseItems(releaseItems) {
|
|
var releasePlanGroups = _.chain(releaseItems)
|
|
.groupBy('realObject.releaseMilestone')
|
|
.map(function (item) {
|
|
return item;
|
|
}).value();
|
|
return releasePlanGroups;
|
|
}
|
|
function refreshList() {
|
|
scope.state.dataIsLoading = true;
|
|
fetchReleasePlanList().then(function () {
|
|
resetFilter();
|
|
scope.state.dataIsLoading = false;
|
|
});
|
|
}
|
|
function init() {
|
|
scope.state.dataIsLoading = true;
|
|
var releasePlanPromise = fetchReleasePlanList(), activityMetadataPromise = metadataModel.getMetadataByType(EntityVO.TYPE_ACTIVITY), releaseMetadataPromise = metadataModel.getMetadataByType(EntityVO.TYPE_RELEASE);
|
|
$q.all([releasePlanPromise, activityMetadataPromise, releaseMetadataPromise]).then(function (response) {
|
|
var releaseMetadata = response[2];
|
|
scope.milestoneFilters = angular.copy(releaseMetadata.milestones);
|
|
scope.milestoneFilters.unshift({ name: '', label: $filter('i18n')('common.labels.noneSet') });
|
|
scope.milestones = angular.copy(releaseMetadata.milestones);
|
|
scope.state.dataIsLoading = false;
|
|
});
|
|
}
|
|
scope.$on(events.REFRESH_RELEASE_PLAN_LIST, function () {
|
|
refreshList();
|
|
});
|
|
init();
|
|
}
|
|
};
|
|
}
|
|
]);
|
|
})();
|