Page MenuHomePhabricator

D8590.diff
No OneTemporary

D8590.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -7,8 +7,8 @@
return array(
'names' =>
array(
- 'core.pkg.css' => '5e574aa1',
- 'core.pkg.js' => '264721e1',
+ 'core.pkg.css' => '6d16f22a',
+ 'core.pkg.js' => 'd3fecc57',
'darkconsole.pkg.js' => 'ca8671ce',
'differential.pkg.css' => 'cb97e095',
'differential.pkg.js' => '11a5b750',
@@ -132,7 +132,7 @@
'rsrc/css/phui/phui-document.css' => '10f59385',
'rsrc/css/phui/phui-feed-story.css' => '3a59c2cf',
'rsrc/css/phui/phui-fontkit.css' => 'de84aa4a',
- 'rsrc/css/phui/phui-form-view.css' => '0efd3326',
+ 'rsrc/css/phui/phui-form-view.css' => '867463b4',
'rsrc/css/phui/phui-form.css' => 'b78ec020',
'rsrc/css/phui/phui-header-view.css' => '5b79f0ef',
'rsrc/css/phui/phui-icon.css' => '7a5771a9',
@@ -475,7 +475,7 @@
'rsrc/js/core/behavior-tokenizer.js' => 'b3a4b884',
'rsrc/js/core/behavior-tooltip.js' => '48db4145',
'rsrc/js/core/behavior-watch-anchor.js' => '06e05112',
- 'rsrc/js/core/behavior-workflow.js' => '82947dda',
+ 'rsrc/js/core/behavior-workflow.js' => 'fee00761',
'rsrc/js/core/phtize.js' => 'd254d646',
'rsrc/js/phui/behavior-phui-object-box-tabs.js' => 'a3e2244e',
'rsrc/swf/aphlict.swf' => 'abac967d',
@@ -627,7 +627,7 @@
'javelin-behavior-test-payment-form' => 'b3e5ee60',
'javelin-behavior-toggle-class' => 'a82a7769',
'javelin-behavior-view-placeholder' => '2fa810fc',
- 'javelin-behavior-workflow' => '82947dda',
+ 'javelin-behavior-workflow' => 'fee00761',
'javelin-color' => '7e41274a',
'javelin-cookie' => '6b3dcf44',
'javelin-dom' => '5054855f',
@@ -748,7 +748,7 @@
'phui-feed-story-css' => '3a59c2cf',
'phui-fontkit-css' => 'de84aa4a',
'phui-form-css' => 'b78ec020',
- 'phui-form-view-css' => '0efd3326',
+ 'phui-form-view-css' => '867463b4',
'phui-header-view-css' => '5b79f0ef',
'phui-icon-view-css' => '7a5771a9',
'phui-info-panel-css' => '27ea50a1',
@@ -1330,13 +1330,6 @@
0 => 'javelin-behavior',
1 => 'javelin-history',
),
- '82947dda' =>
- array(
- 0 => 'javelin-behavior',
- 1 => 'javelin-stratcom',
- 2 => 'javelin-workflow',
- 3 => 'javelin-dom',
- ),
'82f568cd' =>
array(
0 => 'javelin-install',
@@ -1972,6 +1965,13 @@
4 => 'multirow-row-manager',
5 => 'javelin-json',
),
+ 'fee00761' =>
+ array(
+ 0 => 'javelin-behavior',
+ 1 => 'javelin-stratcom',
+ 2 => 'javelin-workflow',
+ 3 => 'javelin-dom',
+ ),
28497740 =>
array(
0 => 'javelin-behavior',
diff --git a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
--- a/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
+++ b/src/applications/maniphest/config/PhabricatorManiphestConfigOptions.php
@@ -149,8 +149,9 @@
- `default` This is the default status for newly created tasks. You must
designate one status as default, and it must be an open status.
- `closed` This is the default status for closed tasks (for example, tasks
- closed via the "!close" action in email). You must designate one status
- as the default closed status, and it must be a closed status.
+ closed via the "!close" action in email or via the quick close button in
+ Maniphest). You must designate one status as the default closed status,
+ and it must be a closed status.
- `duplicate` This is the status used when tasks are merged into one
another as duplicates. You must designate one status for duplicates,
and it must be a closed status.
diff --git a/src/applications/maniphest/controller/ManiphestTaskDetailController.php b/src/applications/maniphest/controller/ManiphestTaskDetailController.php
--- a/src/applications/maniphest/controller/ManiphestTaskDetailController.php
+++ b/src/applications/maniphest/controller/ManiphestTaskDetailController.php
@@ -208,6 +208,29 @@
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
+ $submit_text = $is_serious
+ ? pht('Submit')
+ : pht('Avast!');
+
+ $close_text = $is_serious
+ ? pht('Close Task')
+ : pht('Scuttle Task');
+
+ $submit_control = id(new PHUIFormMultiSubmitControl());
+ if (!$task->isClosed()) {
+ $close_image = id(new PHUIIconView())
+ ->setSpriteSheet(PHUIIconView::SPRITE_ICONS)
+ ->setSpriteIcon('check');
+ $submit_control->addButtonView(
+ id(new PHUIButtonView())
+ ->setColor(PHUIButtonView::GREY)
+ ->setIcon($close_image)
+ ->setText($close_text)
+ ->setName('scuttle')
+ ->addSigil('alternate-submit-button'));
+ }
+ $submit_control->addSubmitButton($submit_text);
+
$comment_form = new AphrontFormView();
$comment_form
->setUser($user)
@@ -273,9 +296,7 @@
->setValue($draft_text)
->setID('transaction-comments')
->setUser($user))
- ->appendChild(
- id(new AphrontFormSubmitControl())
- ->setValue($is_serious ? pht('Submit') : pht('Avast!')));
+ ->appendChild($submit_control);
$control_map = array(
ManiphestTransaction::TYPE_STATUS => 'resolution',
diff --git a/src/applications/maniphest/controller/ManiphestTransactionSaveController.php b/src/applications/maniphest/controller/ManiphestTransactionSaveController.php
--- a/src/applications/maniphest/controller/ManiphestTransactionSaveController.php
+++ b/src/applications/maniphest/controller/ManiphestTransactionSaveController.php
@@ -130,6 +130,18 @@
$transactions[] = $transaction;
}
+ $resolution = $request->getStr('resolution');
+ $did_scuttle = false;
+ if ($action !== ManiphestTransaction::TYPE_STATUS) {
+ if ($request->getStr('scuttle')) {
+ $transactions[] = id(new ManiphestTransaction())
+ ->setTransactionType(ManiphestTransaction::TYPE_STATUS)
+ ->setNewValue(ManiphestTaskStatus::getDefaultClosedStatus());
+ $did_scuttle = true;
+ $resolution = ManiphestTaskStatus::getDefaultClosedStatus();
+ }
+ }
+
// When you interact with a task, we add you to the CC list so you get
// further updates, and possibly assign the task to you if you took an
// ownership action (closing it) but it's currently unowned. We also move
@@ -137,31 +149,28 @@
// and create side-effect transactions for them.
$implicitly_claimed = false;
- switch ($action) {
- case ManiphestTransaction::TYPE_OWNER:
- if ($task->getOwnerPHID() == $transaction->getNewValue()) {
- // If this is actually no-op, don't generate the side effect.
- break;
- }
- // Otherwise, when a task is reassigned, move the previous owner to CC.
- $added_ccs[] = $task->getOwnerPHID();
- break;
- case ManiphestTransaction::TYPE_STATUS:
- $resolution = $request->getStr('resolution');
- if (!$task->getOwnerPHID() &&
- ManiphestTaskStatus::isClosedStatus($resolution)) {
- // Closing an unassigned task. Assign the user as the owner of
- // this task.
- $assign = new ManiphestTransaction();
- $assign->setTransactionType(ManiphestTransaction::TYPE_OWNER);
- $assign->setNewValue($user->getPHID());
- $transactions[] = $assign;
-
- $implicitly_claimed = true;
- }
+ if ($action == ManiphestTransaction::TYPE_OWNER) {
+ if ($task->getOwnerPHID() == $transaction->getNewValue()) {
+ // If this is actually no-op, don't generate the side effect.
break;
+ }
+ // Otherwise, when a task is reassigned, move the previous owner to CC.
+ $added_ccs[] = $task->getOwnerPHID();
}
+ if ($did_scuttle || ($action == ManiphestTransaction::TYPE_STATUS)) {
+ if (!$task->getOwnerPHID() &&
+ ManiphestTaskStatus::isClosedStatus($resolution)) {
+ // Closing an unassigned task. Assign the user as the owner of
+ // this task.
+ $assign = new ManiphestTransaction();
+ $assign->setTransactionType(ManiphestTransaction::TYPE_OWNER);
+ $assign->setNewValue($user->getPHID());
+ $transactions[] = $assign;
+
+ $implicitly_claimed = true;
+ }
+ }
$user_owns_task = false;
if ($implicitly_claimed) {
diff --git a/src/view/form/control/AphrontFormSubmitControl.php b/src/view/form/control/AphrontFormSubmitControl.php
--- a/src/view/form/control/AphrontFormSubmitControl.php
+++ b/src/view/form/control/AphrontFormSubmitControl.php
@@ -2,7 +2,7 @@
final class AphrontFormSubmitControl extends AphrontFormControl {
- protected $cancelButton;
+ private $cancelButton;
public function addCancelButton($href, $label = null) {
if (!$label) {
@@ -35,7 +35,11 @@
),
$this->getValue());
}
- return hsprintf('%s%s', $submit_button, $this->cancelButton);
+
+ return array(
+ $submit_button,
+ $this->cancelButton,
+ );
}
}
diff --git a/src/view/form/control/PHUIFormMultiSubmitControl.php b/src/view/form/control/PHUIFormMultiSubmitControl.php
--- a/src/view/form/control/PHUIFormMultiSubmitControl.php
+++ b/src/view/form/control/PHUIFormMultiSubmitControl.php
@@ -31,14 +31,20 @@
return $this;
}
+ public function addButtonView(PHUIButtonView $button) {
+ $this->buttons[] = $button;
+ return $this;
+ }
+
public function addButton($name, $label, $class = null) {
- $this->buttons[] = phutil_tag(
+ $this->buttons[] = javelin_tag(
'input',
array(
'type' => 'submit',
'name' => $name,
'value' => $label,
'class' => $class,
+ 'sigil' => 'alternate-submit-button',
'disabled' => $this->getDisabled() ? 'disabled' : null,
));
return $this;
diff --git a/src/view/phui/PHUIButtonView.php b/src/view/phui/PHUIButtonView.php
--- a/src/view/phui/PHUIButtonView.php
+++ b/src/view/phui/PHUIButtonView.php
@@ -21,6 +21,16 @@
private $href = null;
private $title = null;
private $disabled;
+ private $name;
+
+ public function setName($name) {
+ $this->name = $name;
+ return $this;
+ }
+
+ public function getName() {
+ return $this->name;
+ }
public function setText($text) {
$this->text = $text;
@@ -103,9 +113,12 @@
$classes[] = 'disabled';
}
- return array('class' => $classes,
- 'href' => $this->href,
- 'title' => $this->title);
+ return array(
+ 'class' => $classes,
+ 'href' => $this->href,
+ 'name' => $this->name,
+ 'title' => $this->title,
+ );
}
protected function getTagContent() {
diff --git a/webroot/rsrc/css/phui/phui-form-view.css b/webroot/rsrc/css/phui/phui-form-view.css
--- a/webroot/rsrc/css/phui/phui-form-view.css
+++ b/webroot/rsrc/css/phui/phui-form-view.css
@@ -108,9 +108,10 @@
}
.phui-form-control-multi-submit input,
+.phui-form-control-multi-submit button,
.phui-form-control-multi-submit a {
float: right;
- margin: 0.5em 0 0em 2%;
+ margin: 4px 0 0 8px;
width: auto;
}
diff --git a/webroot/rsrc/js/core/behavior-workflow.js b/webroot/rsrc/js/core/behavior-workflow.js
--- a/webroot/rsrc/js/core/behavior-workflow.js
+++ b/webroot/rsrc/js/core/behavior-workflow.js
@@ -8,6 +8,22 @@
JX.behavior('workflow', function() {
+ // If a user clicks an alternate submit button, make sure it gets marshalled
+ // into the workflow.
+ JX.Stratcom.listen(
+ 'click',
+ ['workflow', 'tag:form', 'alternate-submit-button'],
+ function(e) {
+ e.prevent();
+
+ var target = e.getNode('alternate-submit-button');
+ var form = e.getNode('tag:form');
+ var button = {};
+ button[target.name] = target.value || true;
+
+ JX.DOM.invoke(form, 'didSyntheticSubmit', {extra: button});
+ });
+
// Listen for both real and synthetic submit events.
JX.Stratcom.listen(
['submit', 'didSyntheticSubmit'],
@@ -17,11 +33,14 @@
return;
}
+ var data = e.getData();
+ var extra = (data && data.extra) || {};
+
// NOTE: We activate workflow if any parent node has the "workflow" sigil,
// not just the <form /> itself.
e.prevent();
- JX.Workflow.newFromForm(e.getNode('tag:form')).start();
+ JX.Workflow.newFromForm(e.getNode('tag:form'), extra).start();
});
JX.Stratcom.listen(

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 10, 6:31 AM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7408693
Default Alt Text
D8590.diff (12 KB)

Event Timeline