angular-gantt
Version:
Gantt chart component for AngularJS
211 lines (173 loc) • 7.29 kB
text/typescript
import moment from 'moment'
require('./taskSection.tmpl.html')
export default function ($templateCache) {
'ngInject'
return {
restrict: 'E',
requires: '^ganttTaskSections',
templateUrl: function (tElement, tAttrs) {
let templateUrl
if (tAttrs.templateUrl === undefined) {
templateUrl = 'plugins/sections/taskSection.tmpl.html'
} else {
templateUrl = tAttrs.templateUrl
}
if (tAttrs.template !== undefined) {
$templateCache.put(templateUrl, tAttrs.template)
}
return templateUrl
},
replace: true,
scope: {
section: '=',
task: '=',
index: '=',
options: '=?'
},
controller: function ($scope, $element, ganttUtils) {
'ngInject'
let fromTask = moment($scope.section.from).isSame(moment($scope.task.model.from))
let toTask = moment($scope.section.to).isSame(moment($scope.task.model.to))
let loadPreviousScope = function () {
if ($scope.task._movingTaskSections) {
// We are coming from a task row change
let sectionScopes = $scope.task._movingTaskSections
let sectionScope = sectionScopes['$$index_' + $scope.index]
$scope.section = sectionScope.section
$scope.sectionCss = sectionScope.sectionCss
fromTask = sectionScope.fromTask
toTask = sectionScope.toTask
delete sectionScopes['$$index_' + $scope.index]
}
let sectionScopesEmpty = true
for (let property in $scope.task._movingTaskSections) {
if ($scope.task._movingTaskSections.hasOwnProperty(property)) {
sectionScopesEmpty = false
break
}
}
if (sectionScopesEmpty) {
delete $scope.task._movingTaskSections
}
}
loadPreviousScope()
let getLeft = function () {
if (fromTask) {
return 0
}
let gantt = $scope.task.rowsManager.gantt
let taskLeft = $scope.task.left
let from
let disableMagnet = ganttUtils.firstProperty([$scope.section, $scope.options], 'disableMagnet', $scope.$parent.pluginScope.disableMagnet)
from = disableMagnet ? $scope.section.from : gantt.getMagnetDate($scope.section.from)
let disableDaily = ganttUtils.firstProperty([$scope.section, $scope.options], 'disableDaily', $scope.$parent.pluginScope.disableDaily)
if (!disableDaily && gantt.options.value('daily')) {
from = moment(from).startOf('day')
}
let sectionLeft = gantt.getPositionByDate(from)
return sectionLeft - taskLeft
}
let getRight = function () {
let keepProportions = ganttUtils.firstProperty([$scope.section, $scope.options], 'keepProportions', $scope.$parent.pluginScope.keepProportions)
if (toTask && keepProportions) {
return $scope.task.width
}
let gantt = $scope.task.rowsManager.gantt
let taskLeft = $scope.task.left
let disableMagnet = ganttUtils.firstProperty([$scope.section, $scope.options], 'disableMagnet', $scope.$parent.pluginScope.disableMagnet)
let to = disableMagnet ? $scope.section.to : gantt.getMagnetDate($scope.section.to)
let disableDaily = ganttUtils.firstProperty([$scope.section, $scope.options], 'disableDaily', $scope.$parent.pluginScope.disableDaily)
if (!disableDaily && gantt.options.value('daily')) {
to = moment(to).startOf('day')
}
let sectionRight = gantt.getPositionByDate(to)
return sectionRight - taskLeft
}
let getRelative = function (position) {
return position / $scope.task.width * 100
}
let updatePosition = function () {
let sectionLeft = getLeft()
let sectionWidth = getRight() - sectionLeft
let keepProportions = ganttUtils.firstProperty([$scope.section, $scope.options], 'keepProportions', $scope.$parent.pluginScope.keepProportions)
if (keepProportions) {
// Setting left and width as to keep proportions when changing task size.
// This may somewhat break the magnet feature, but it seems acceptable
$scope.sectionCss.left = getRelative(sectionLeft) + '%'
$scope.sectionCss.width = getRelative(sectionWidth) + '%'
} else {
$scope.sectionCss.left = sectionLeft + 'px'
$scope.sectionCss.width = sectionWidth + 'px'
}
}
let updateCss = function () {
if ($scope.section.color) {
$scope.sectionCss['background-color'] = $scope.section.color
} else {
$scope.sectionCss['background-color'] = undefined
}
}
if ($scope.sectionCss === undefined) {
$scope.sectionCss = {}
updatePosition()
updateCss()
}
let taskChangeHandler = function (task) {
if (task === $scope.task) {
// Update from/to section model value based on position.
let gantt = $scope.task.rowsManager.gantt
let sectionLeft = $element[0].offsetLeft
let disableMagnet = ganttUtils.firstProperty([$scope.section, $scope.options], 'disableMagnet', $scope.$parent.pluginScope.disableMagnet)
let from
if (fromTask) {
from = $scope.task.model.from
} else {
from = gantt.getDateByPosition($scope.task.modelLeft + sectionLeft, !disableMagnet)
}
let to
if (toTask) {
to = $scope.task.model.to
} else {
let sectionRight = sectionLeft + $element[0].offsetWidth
to = gantt.getDateByPosition($scope.task.modelLeft + sectionRight, !disableMagnet)
}
$scope.section.from = from
$scope.section.to = to
updatePosition()
}
}
let taskCleanHandler = function (taskModel) {
if (taskModel.id === $scope.task.model.id) {
let model = $scope.section
if (model.from !== undefined && !moment.isMoment(model.from)) {
model.from = moment(model.from)
}
if (model.to !== undefined && !moment.isMoment(model.to)) {
model.to = moment(model.to)
}
}
}
taskCleanHandler($scope.task.model)
$scope.task.rowsManager.gantt.api.tasks.on.clean($scope, taskCleanHandler)
$scope.task.rowsManager.gantt.api.tasks.on.change($scope, taskChangeHandler)
let beforeViewRowChangeHandler = function (task) {
let sectionScopes = task._movingTaskSections
if (!sectionScopes) {
sectionScopes = {}
task._movingTaskSections = sectionScopes
}
sectionScopes['$$index_' + $scope.index] = {
'section': $scope.section,
'sectionCss': $scope.sectionCss,
'fromTask': fromTask,
'toTask': toTask
}
}
$scope.task.rowsManager.gantt.api.tasks.on.beforeViewRowChange($scope, beforeViewRowChangeHandler)
$scope.task.rowsManager.gantt.api.directives.raise.new('ganttTaskSection', $scope, $element)
$scope.$on('$destroy', function () {
$scope.task.rowsManager.gantt.api.directives.raise.destroy('ganttTaskSection', $scope, $element)
})
}
}
}