UNPKG

angular-gantt

Version:

Gantt chart component for AngularJS

283 lines (230 loc) 7.31 kB
import {IScope} from 'angular' import moment from 'moment' import {GanttTask, GanttTaskModel} from '../task/task.factory' import {IGanttFilterService} from '../../../index' import * as angular from 'angular' import {GanttRowsManager} from './rowsManager.factory' export class GanttRowModel { id: string tasks: GanttTaskModel[] } export class GanttRow { static GanttTask: {new(row: GanttRow, model: GanttTaskModel): GanttTask} static $filter: IGanttFilterService rowsManager: GanttRowsManager model: GanttRowModel from: moment.Moment to: moment.Moment tasksMap: { [id: string]: GanttTask } tasks: GanttTask[] filteredTasks: GanttTask[] visibleTasks: GanttTask[] $scope: IScope constructor (rowsManager: GanttRowsManager, model: GanttRowModel) { this.rowsManager = rowsManager this.model = model this.from = undefined this.to = undefined this.tasksMap = {} this.tasks = [] this.filteredTasks = [] this.visibleTasks = [] } addTaskImpl (task: GanttTask, viewOnly = false) { this.tasksMap[task.model.id] = task this.tasks.push(task) if (!viewOnly) { if (this.model.tasks === undefined) { this.model.tasks = [] } if (this.model.tasks.indexOf(task.model) === -1) { this.model.tasks.push(task.model) } } } // Adds a task to a specific row. Merges the task if there is already one with the same id addTask (taskModel: GanttTaskModel, viewOnly = false) { // Copy to new task (add) or merge with existing (update) let task let isUpdate = false this.rowsManager.gantt.objectModel.cleanTask(taskModel) if (taskModel.id in this.tasksMap) { task = this.tasksMap[taskModel.id] if (task.model === taskModel) { return task } task.model = taskModel isUpdate = true } else { task = new GanttRow.GanttTask(this, taskModel) this.addTaskImpl(task, viewOnly) } this.sortTasks() this.setFromToByTask(task) if (!viewOnly) { if (isUpdate) { (this.rowsManager.gantt.api as any).tasks.raise.change(task) } else { (this.rowsManager.gantt.api as any).tasks.raise.add(task) } } return task } // Removes the task from the existing row and adds it to he current one moveTaskToRow (task: GanttTask, viewOnly = false) { (this.rowsManager.gantt.api as any).tasks.raise.beforeViewRowChange(task, this) if (!viewOnly) { (this.rowsManager.gantt.api as any).tasks.raise.beforeRowChange(task, this) } let oldRow = task.row oldRow.removeTask(task.model.id, viewOnly, true) task.row = this this.addTaskImpl(task, viewOnly) this.sortTasks() this.setFromToByTask(task) task.updatePosAndSize() this.updateVisibleTasks() oldRow.$scope.$digest() task.row.$scope.$digest(); (this.rowsManager.gantt.api as any).tasks.raise.viewRowChange(task, oldRow) if (!viewOnly) { (this.rowsManager.gantt.api as any).tasks.raise.rowChange(task, oldRow) } } updateVisibleTasks () { let filterTask = this.rowsManager.gantt.options.value('filterTask') if (filterTask) { if (typeof(filterTask) === 'object') { filterTask = {model: filterTask} } let filterTaskComparator = this.rowsManager.gantt.options.value('filterTaskComparator') if (typeof(filterTaskComparator) === 'function') { filterTaskComparator = function (actual, expected) { return filterTaskComparator(actual.model, expected.model) } } this.filteredTasks = GanttRow.$filter('filter')(this.tasks, filterTask, filterTaskComparator) } else { this.filteredTasks = this.tasks.slice(0) } let limitThreshold = this.rowsManager.gantt.options.value('taskLimitThreshold') if (limitThreshold === undefined || limitThreshold > 0 && this.filteredTasks.length >= limitThreshold) { this.visibleTasks = GanttRow.$filter('ganttTaskLimit')(this.filteredTasks, this.rowsManager.gantt) } else { this.visibleTasks = this.filteredTasks } } updateTasksPosAndSize () { for (let task of this.tasks) { task.updatePosAndSize() } } /** * Remove the specified task from the row * * @param taskId * @param viewOnly * @param silent * @returns {any} */ removeTask (taskId: string, viewOnly: boolean, silent: boolean) { if (taskId in this.tasksMap) { let removedTask = this.tasksMap[taskId] let task let i for (i = this.tasks.length - 1; i >= 0; i--) { task = this.tasks[i] if (task.model.id === taskId) { this.tasks.splice(i, 1) // Remove from array // Update earliest or latest date info as this may change if (this.from && this.from.isSame(moment(task.model.from)) || this.to && this.to.isSame(moment(task.model.to))) { this.setFromTo() } break } } for (i = this.filteredTasks.length - 1; i >= 0; i--) { task = this.filteredTasks[i] if (task.model.id === taskId) { this.filteredTasks.splice(i, 1) // Remove from filtered array break } } for (i = this.visibleTasks.length - 1; i >= 0; i--) { task = this.visibleTasks[i] if (task.model.id === taskId) { this.visibleTasks.splice(i, 1) // Remove from visible array break } } if (!viewOnly) { delete this.tasksMap[taskId] // Remove from map if (this.model.tasks !== undefined) { let taskIndex = this.model.tasks.indexOf(removedTask.model) if (taskIndex > -1) { this.model.tasks.splice(taskIndex, 1) } } if (!silent) { (this.rowsManager.gantt.api as any).tasks.raise.remove(removedTask) } } return removedTask } } removeAllTasks () { this.from = undefined this.to = undefined this.tasksMap = {} this.tasks = [] this.filteredTasks = [] this.visibleTasks = [] } /** * Calculate the earliest from and latest to date of all tasks in a row */ setFromTo () { this.from = undefined this.to = undefined for (let task of this.tasks) { this.setFromToByTask(task) } } setFromToByTask (task) { this.setFromToByValues(task.model.from, task.model.to) } setFromToByValues (from, to) { if (from !== undefined) { if (this.from === undefined) { this.from = moment(from) } else if (from < this.from) { this.from = moment(from) } } if (to !== undefined) { if (this.to === undefined) { this.to = moment(to) } else if (to > this.to) { this.to = moment(to) } } } sortTasks () { this.tasks.sort((t1, t2) => { return t1.left - t2.left }) } clone () { let clone = new GanttRow(this.rowsManager, angular.copy(this.model)) for (let task of this.tasks) { clone.addTask(task.model) } return clone } } export default function (GanttTask: {new(row: GanttRow, model: GanttTaskModel): GanttTask}, $filter: IGanttFilterService) { 'ngInject' GanttRow.GanttTask = GanttTask GanttRow.$filter = $filter return GanttRow }