-
Notifications
You must be signed in to change notification settings - Fork 78
/
index.js
126 lines (109 loc) · 3.51 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import Ember from 'ember';
const {
computed: { alias, sort },
Controller,
get,
inject: { service },
RSVP,
setProperties
} = Ember;
export default Controller.extend({
store: service(),
project: alias('model'),
members: alias('project.organization.organizationMembers'),
sorting: ['order:asc'],
orderedTaskLists: sort('project.taskLists', 'sorting'),
dragulaconfig: {
options: {
moves(el) {
return el.dataset.canReposition == 'true';
},
copy: false,
revertOnSpill: false,
removeOnSpill: false
// Other options from the dragula source page.
},
enabledEvents: ['drag', 'drop']
},
actions: {
onDrop(droppedTaskEl, listDropTargetEl, source, siblingTaskEl) {
// Get the necessary attributes from the dropped card and drop target
let listId = listDropTargetEl.dataset.modelId;
let position = $(droppedTaskEl).index();
let taskId = droppedTaskEl.dataset.modelId;
let store = get(this, 'store');
let taskList = store.findRecord('taskList', listId);
let task = store.findRecord('task', taskId);
if (siblingTaskEl) {
let siblingTaskId = siblingTaskEl.dataset.modelId;
this._moveTaskAboveTask(taskList, task, siblingTaskId, position, droppedTaskEl);
} else {
this._moveTaskMaybeBelowTask(taskList, task, position, droppedTaskEl);
}
}
},
_isFloat(n) {
return Number(n) === n && n % 1 !== 0;
},
_moveTaskAboveTask(taskList, task, siblingTaskId, position, droppedTaskEl) {
let store = get(this, 'store');
let siblingTask = store.findRecord('task', siblingTaskId);
RSVP.hash({
siblingTask,
task,
taskList
}).then(({ siblingTask, task, taskList }) => {
let originalListId = get(task, 'taskList.id');
let newListId = get(taskList, 'id');
if (originalListId !== newListId) {
droppedTaskEl.remove();
}
let siblingOrder = get(siblingTask, 'order');
let order = this._newOrder(siblingOrder, -1);
this._saveTask(task, order, position, taskList);
});
},
_moveTaskMaybeBelowTask(taskList, task, position, droppedTaskEl) {
RSVP.hash({
task,
taskList
}).then(({ task, taskList }) => {
let originalListId = get(task, 'taskList.id');
let newListId = get(taskList, 'id');
let tempOrder = 0;
let lastTask = get(taskList, 'orderedTasks.lastObject');
if (lastTask) {
tempOrder = get(lastTask, 'order');
}
let order = this._newOrder(tempOrder, 1);
if (originalListId !== newListId) {
droppedTaskEl.remove();
}
this._saveTask(task, order, position, taskList);
});
},
_newOrder(number, sign) {
let decimal = this._isFloat(number) ? this._toFraction(number) : 0.5;
if (sign === -1) {
return number - decimal;
} else if (sign === 1) {
return number + decimal;
}
},
_saveTask(task, order, position, taskList) {
let tasks = get(taskList, 'tasks');
setProperties(task, { order, position });
// We do pushObject because sorting does not work correctly unless
// the task is pushed onto the task list array.
tasks.pushObject(task);
task.save();
// TODO: If save() fails then we have a task pushed onto a task
// list that is not actually in that task list
// We should consider error handling here
},
_toFraction(number) {
let numberString = number.toString();
let [, decimalPortion] = numberString.split('.');
return Number(decimalPortion);
}
});