mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-26 16:52:41 +01:00
Workboards - make priority changes less aggressive and generally better
Summary: Fixes T4641. Test Plan: Dragged a "normal" task between "high" and "low" tasks and it stayed as "normal". Generally seems correct when playing around. Reviewers: epriestley Reviewed By: epriestley Subscribers: mbishopim3, Beltran-rubo, epriestley, Korvin Maniphest Tasks: T4641 Differential Revision: https://secure.phabricator.com/D8622
This commit is contained in:
parent
655ac9927f
commit
de2da8355b
5 changed files with 127 additions and 34 deletions
|
@ -404,7 +404,7 @@ return array(
|
||||||
'rsrc/js/application/policy/behavior-policy-control.js' => 'c01153ea',
|
'rsrc/js/application/policy/behavior-policy-control.js' => 'c01153ea',
|
||||||
'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '263aeb8c',
|
'rsrc/js/application/policy/behavior-policy-rule-editor.js' => '263aeb8c',
|
||||||
'rsrc/js/application/ponder/behavior-votebox.js' => '327dbe61',
|
'rsrc/js/application/ponder/behavior-votebox.js' => '327dbe61',
|
||||||
'rsrc/js/application/projects/behavior-project-boards.js' => '04c59172',
|
'rsrc/js/application/projects/behavior-project-boards.js' => 'd8e135db',
|
||||||
'rsrc/js/application/projects/behavior-project-create.js' => '065227cc',
|
'rsrc/js/application/projects/behavior-project-create.js' => '065227cc',
|
||||||
'rsrc/js/application/releeph/releeph-preview-branch.js' => '9eb2cedb',
|
'rsrc/js/application/releeph/releeph-preview-branch.js' => '9eb2cedb',
|
||||||
'rsrc/js/application/releeph/releeph-request-state-change.js' => 'fe7fc914',
|
'rsrc/js/application/releeph/releeph-request-state-change.js' => 'fe7fc914',
|
||||||
|
@ -614,7 +614,7 @@ return array(
|
||||||
'javelin-behavior-policy-control' => 'c01153ea',
|
'javelin-behavior-policy-control' => 'c01153ea',
|
||||||
'javelin-behavior-policy-rule-editor' => '263aeb8c',
|
'javelin-behavior-policy-rule-editor' => '263aeb8c',
|
||||||
'javelin-behavior-ponder-votebox' => '327dbe61',
|
'javelin-behavior-ponder-votebox' => '327dbe61',
|
||||||
'javelin-behavior-project-boards' => '04c59172',
|
'javelin-behavior-project-boards' => 'd8e135db',
|
||||||
'javelin-behavior-project-create' => '065227cc',
|
'javelin-behavior-project-create' => '065227cc',
|
||||||
'javelin-behavior-refresh-csrf' => 'c4b31646',
|
'javelin-behavior-refresh-csrf' => 'c4b31646',
|
||||||
'javelin-behavior-releeph-preview-branch' => '9eb2cedb',
|
'javelin-behavior-releeph-preview-branch' => '9eb2cedb',
|
||||||
|
@ -843,15 +843,6 @@ return array(
|
||||||
3 => 'javelin-vector',
|
3 => 'javelin-vector',
|
||||||
4 => 'javelin-install',
|
4 => 'javelin-install',
|
||||||
),
|
),
|
||||||
'04c59172' =>
|
|
||||||
array(
|
|
||||||
0 => 'javelin-behavior',
|
|
||||||
1 => 'javelin-dom',
|
|
||||||
2 => 'javelin-util',
|
|
||||||
3 => 'javelin-stratcom',
|
|
||||||
4 => 'javelin-workflow',
|
|
||||||
5 => 'phabricator-draggable-list',
|
|
||||||
),
|
|
||||||
'065227cc' =>
|
'065227cc' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-behavior',
|
0 => 'javelin-behavior',
|
||||||
|
@ -1752,6 +1743,15 @@ return array(
|
||||||
3 => 'javelin-dom',
|
3 => 'javelin-dom',
|
||||||
4 => 'phabricator-keyboard-shortcut',
|
4 => 'phabricator-keyboard-shortcut',
|
||||||
),
|
),
|
||||||
|
'd8e135db' =>
|
||||||
|
array(
|
||||||
|
0 => 'javelin-behavior',
|
||||||
|
1 => 'javelin-dom',
|
||||||
|
2 => 'javelin-util',
|
||||||
|
3 => 'javelin-stratcom',
|
||||||
|
4 => 'javelin-workflow',
|
||||||
|
5 => 'phabricator-draggable-list',
|
||||||
|
),
|
||||||
'd8ef8659' =>
|
'd8ef8659' =>
|
||||||
array(
|
array(
|
||||||
0 => 'javelin-behavior',
|
0 => 'javelin-behavior',
|
||||||
|
|
|
@ -45,7 +45,8 @@ final class ManiphestSubpriorityController extends ManiphestController {
|
||||||
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
|
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
|
||||||
->setNewValue(array(
|
->setNewValue(array(
|
||||||
'newPriority' => $after_pri,
|
'newPriority' => $after_pri,
|
||||||
'newSubpriorityBase' => $after_sub)));
|
'newSubpriorityBase' => $after_sub,
|
||||||
|
'direction' => '>')));
|
||||||
$editor = id(new ManiphestTransactionEditor())
|
$editor = id(new ManiphestTransactionEditor())
|
||||||
->setActor($user)
|
->setActor($user)
|
||||||
->setContinueOnMissingFields(true)
|
->setContinueOnMissingFields(true)
|
||||||
|
|
|
@ -165,7 +165,8 @@ final class ManiphestTransactionEditor
|
||||||
$data = $xaction->getNewValue();
|
$data = $xaction->getNewValue();
|
||||||
$new_sub = $this->getNextSubpriority(
|
$new_sub = $this->getNextSubpriority(
|
||||||
$data['newPriority'],
|
$data['newPriority'],
|
||||||
$data['newSubpriorityBase']);
|
$data['newSubpriorityBase'],
|
||||||
|
$data['direction']);
|
||||||
$object->setSubpriority($new_sub);
|
$object->setSubpriority($new_sub);
|
||||||
return;
|
return;
|
||||||
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
|
case ManiphestTransaction::TYPE_PROJECT_COLUMN:
|
||||||
|
@ -441,26 +442,55 @@ final class ManiphestTransactionEditor
|
||||||
return $copy;
|
return $copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getNextSubpriority($pri, $sub) {
|
private function getNextSubpriority($pri, $sub, $dir = '>') {
|
||||||
|
|
||||||
|
switch ($dir) {
|
||||||
|
case '>':
|
||||||
|
$order = 'ASC';
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
$order = 'DESC';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception('$dir must be ">" or "<".');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($sub === null) {
|
||||||
|
$base = 0;
|
||||||
|
} else {
|
||||||
|
$base = $sub;
|
||||||
|
}
|
||||||
|
|
||||||
if ($sub === null) {
|
if ($sub === null) {
|
||||||
$next = id(new ManiphestTask())->loadOneWhere(
|
$next = id(new ManiphestTask())->loadOneWhere(
|
||||||
'priority = %d ORDER BY subpriority ASC LIMIT 1',
|
'priority = %d ORDER BY subpriority %Q LIMIT 1',
|
||||||
$pri);
|
$pri,
|
||||||
|
$order);
|
||||||
if ($next) {
|
if ($next) {
|
||||||
return $next->getSubpriority() - ((double)(2 << 16));
|
if ($dir == '>') {
|
||||||
|
return $next->getSubpriority() - ((double)(2 << 16));
|
||||||
|
} else {
|
||||||
|
return $next->getSubpriority() + ((double)(2 << 16));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$next = id(new ManiphestTask())->loadOneWhere(
|
$next = id(new ManiphestTask())->loadOneWhere(
|
||||||
'priority = %d AND subpriority > %s ORDER BY subpriority ASC LIMIT 1',
|
'priority = %d AND subpriority %Q %f ORDER BY subpriority %Q LIMIT 1',
|
||||||
$pri,
|
$pri,
|
||||||
$sub);
|
$dir,
|
||||||
|
$sub,
|
||||||
|
$order);
|
||||||
if ($next) {
|
if ($next) {
|
||||||
return ($sub + $next->getSubpriority()) / 2;
|
return ($sub + $next->getSubpriority()) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (double)(2 << 32);
|
if ($dir == '>') {
|
||||||
|
return $base + (double)(2 << 32);
|
||||||
|
} else {
|
||||||
|
return $base - (double)(2 << 32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ final class PhabricatorProjectMoveController
|
||||||
$column_phid = $request->getStr('columnPHID');
|
$column_phid = $request->getStr('columnPHID');
|
||||||
$object_phid = $request->getStr('objectPHID');
|
$object_phid = $request->getStr('objectPHID');
|
||||||
$after_phid = $request->getStr('afterPHID');
|
$after_phid = $request->getStr('afterPHID');
|
||||||
|
$before_phid = $request->getStr('beforePHID');
|
||||||
|
|
||||||
$project = id(new PhabricatorProjectQuery())
|
$project = id(new PhabricatorProjectQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
|
@ -78,24 +79,58 @@ final class PhabricatorProjectMoveController
|
||||||
'columnPHIDs' => $edge_phids,
|
'columnPHIDs' => $edge_phids,
|
||||||
'projectPHID' => $column->getProjectPHID()));
|
'projectPHID' => $column->getProjectPHID()));
|
||||||
|
|
||||||
|
$task_phids = array();
|
||||||
if ($after_phid) {
|
if ($after_phid) {
|
||||||
$after_task = id(new ManiphestTaskQuery())
|
$task_phids[] = $after_phid;
|
||||||
|
}
|
||||||
|
if ($before_phid) {
|
||||||
|
$task_phids[] = $before_phid;
|
||||||
|
}
|
||||||
|
if ($task_phids) {
|
||||||
|
$tasks = id(new ManiphestTaskQuery())
|
||||||
->setViewer($viewer)
|
->setViewer($viewer)
|
||||||
->withPHIDs(array($after_phid))
|
->withPHIDs($task_phids)
|
||||||
->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT))
|
->requireCapabilities(array(PhabricatorPolicyCapability::CAN_EDIT))
|
||||||
->executeOne();
|
->execute();
|
||||||
if (!$after_task) {
|
if (count($tasks) != count($task_phids)) {
|
||||||
return new Aphront404Response();
|
return new Aphront404Response();
|
||||||
}
|
}
|
||||||
$after_pri = $after_task->getPriority();
|
$tasks = mpull($tasks, null, 'getPHID');
|
||||||
$after_sub = $after_task->getSubpriority();
|
|
||||||
|
|
||||||
$xactions[] = id(new ManiphestTransaction())
|
$a_task = idx($tasks, $after_phid);
|
||||||
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
|
$b_task = idx($tasks, $before_phid);
|
||||||
->setNewValue(array(
|
|
||||||
'newPriority' => $after_pri,
|
if ($a_task &&
|
||||||
'newSubpriorityBase' => $after_sub));
|
(($a_task->getPriority() < $object->getPriority()) ||
|
||||||
}
|
($a_task->getPriority() == $object->getPriority() &&
|
||||||
|
$a_task->getSubpriority() >= $object->getSubpriority()))) {
|
||||||
|
|
||||||
|
$after_pri = $a_task->getPriority();
|
||||||
|
$after_sub = $a_task->getSubpriority();
|
||||||
|
|
||||||
|
$xactions[] = id(new ManiphestTransaction())
|
||||||
|
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
|
||||||
|
->setNewValue(array(
|
||||||
|
'newPriority' => $after_pri,
|
||||||
|
'newSubpriorityBase' => $after_sub,
|
||||||
|
'direction' => '>'));
|
||||||
|
|
||||||
|
} else if ($b_task &&
|
||||||
|
(($b_task->getPriority() > $object->getPriority()) ||
|
||||||
|
($b_task->getPriority() == $object->getPriority() &&
|
||||||
|
$b_task->getSubpriority() <= $object->getSubpriority()))) {
|
||||||
|
|
||||||
|
$before_pri = $b_task->getPriority();
|
||||||
|
$before_sub = $b_task->getSubpriority();
|
||||||
|
|
||||||
|
$xactions[] = id(new ManiphestTransaction())
|
||||||
|
->setTransactionType(ManiphestTransaction::TYPE_SUBPRIORITY)
|
||||||
|
->setNewValue(array(
|
||||||
|
'newPriority' => $before_pri,
|
||||||
|
'newSubpriorityBase' => $before_sub,
|
||||||
|
'direction' => '<'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$editor = id(new ManiphestTransactionEditor())
|
$editor = id(new ManiphestTransactionEditor())
|
||||||
->setActor($viewer)
|
->setActor($viewer)
|
||||||
|
|
|
@ -28,13 +28,40 @@ JX.behavior('project-boards', function(config) {
|
||||||
list.lock();
|
list.lock();
|
||||||
JX.DOM.alterClass(item, 'drag-sending', true);
|
JX.DOM.alterClass(item, 'drag-sending', true);
|
||||||
|
|
||||||
|
var item_phid = JX.Stratcom.getData(item).objectPHID;
|
||||||
var data = {
|
var data = {
|
||||||
objectPHID: JX.Stratcom.getData(item).objectPHID,
|
objectPHID: item_phid,
|
||||||
columnPHID: JX.Stratcom.getData(list.getRootNode()).columnPHID
|
columnPHID: JX.Stratcom.getData(list.getRootNode()).columnPHID
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var after_phid = null;
|
||||||
|
var items = finditems(list.getRootNode());
|
||||||
if (after) {
|
if (after) {
|
||||||
data.afterPHID = JX.Stratcom.getData(after).objectPHID;
|
after_phid = JX.Stratcom.getData(after).objectPHID;
|
||||||
|
data.afterPHID = after_phid;
|
||||||
|
}
|
||||||
|
var ii;
|
||||||
|
var ii_item;
|
||||||
|
var ii_item_phid;
|
||||||
|
var ii_prev_item_phid = null;
|
||||||
|
var before_phid = null;
|
||||||
|
for (ii = 0; ii < items.length; ii++) {
|
||||||
|
ii_item = items[ii];
|
||||||
|
ii_item_phid = JX.Stratcom.getData(ii_item).objectPHID;
|
||||||
|
if (ii_item_phid == item_phid) {
|
||||||
|
// skip the item we just dropped
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// note this handles when there is no after phid - we are at the top of
|
||||||
|
// the list - quite nicely
|
||||||
|
if (ii_prev_item_phid == after_phid) {
|
||||||
|
before_phid = ii_item_phid;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ii_prev_item_phid = ii_item_phid;
|
||||||
|
}
|
||||||
|
if (before_phid) {
|
||||||
|
data.beforePHID = before_phid;
|
||||||
}
|
}
|
||||||
|
|
||||||
var workflow = new JX.Workflow(config.moveURI, data)
|
var workflow = new JX.Workflow(config.moveURI, data)
|
||||||
|
|
Loading…
Reference in a new issue