mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 14:00:56 +01:00
Add a quote action to Differential and Maniphest
Summary: Ref T4119. This is ugly for now, but technically works. The comment area and transaction log don't realy know about each other, so for the moment the linking is a bit manual. Differential/Maniphest are special cases anyway. Test Plan: {F149992} Reviewers: chad, btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T4119 Differential Revision: https://secure.phabricator.com/D8957
This commit is contained in:
parent
b3476af5f0
commit
707c5aec81
8 changed files with 187 additions and 2 deletions
|
@ -1164,6 +1164,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
|
'PhabricatorApplicationTransactionCommentEditor' => 'applications/transactions/editor/PhabricatorApplicationTransactionCommentEditor.php',
|
||||||
'PhabricatorApplicationTransactionCommentHistoryController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentHistoryController.php',
|
'PhabricatorApplicationTransactionCommentHistoryController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentHistoryController.php',
|
||||||
'PhabricatorApplicationTransactionCommentQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php',
|
'PhabricatorApplicationTransactionCommentQuery' => 'applications/transactions/query/PhabricatorApplicationTransactionCommentQuery.php',
|
||||||
|
'PhabricatorApplicationTransactionCommentQuoteController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentQuoteController.php',
|
||||||
'PhabricatorApplicationTransactionCommentRemoveController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentRemoveController.php',
|
'PhabricatorApplicationTransactionCommentRemoveController' => 'applications/transactions/controller/PhabricatorApplicationTransactionCommentRemoveController.php',
|
||||||
'PhabricatorApplicationTransactionCommentView' => 'applications/transactions/view/PhabricatorApplicationTransactionCommentView.php',
|
'PhabricatorApplicationTransactionCommentView' => 'applications/transactions/view/PhabricatorApplicationTransactionCommentView.php',
|
||||||
'PhabricatorApplicationTransactionController' => 'applications/transactions/controller/PhabricatorApplicationTransactionController.php',
|
'PhabricatorApplicationTransactionController' => 'applications/transactions/controller/PhabricatorApplicationTransactionController.php',
|
||||||
|
@ -3936,6 +3937,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorApplicationTransactionCommentEditor' => 'PhabricatorEditor',
|
'PhabricatorApplicationTransactionCommentEditor' => 'PhabricatorEditor',
|
||||||
'PhabricatorApplicationTransactionCommentHistoryController' => 'PhabricatorApplicationTransactionController',
|
'PhabricatorApplicationTransactionCommentHistoryController' => 'PhabricatorApplicationTransactionController',
|
||||||
'PhabricatorApplicationTransactionCommentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
'PhabricatorApplicationTransactionCommentQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
|
||||||
|
'PhabricatorApplicationTransactionCommentQuoteController' => 'PhabricatorApplicationTransactionController',
|
||||||
'PhabricatorApplicationTransactionCommentRemoveController' => 'PhabricatorApplicationTransactionController',
|
'PhabricatorApplicationTransactionCommentRemoveController' => 'PhabricatorApplicationTransactionController',
|
||||||
'PhabricatorApplicationTransactionCommentView' => 'AphrontView',
|
'PhabricatorApplicationTransactionCommentView' => 'AphrontView',
|
||||||
'PhabricatorApplicationTransactionController' => 'PhabricatorController',
|
'PhabricatorApplicationTransactionController' => 'PhabricatorController',
|
||||||
|
|
|
@ -256,6 +256,11 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$target,
|
$target,
|
||||||
$all_changesets);
|
$all_changesets);
|
||||||
|
|
||||||
|
if (!$viewer_is_anonymous) {
|
||||||
|
$comment_view->setQuoteRef('D'.$revision->getID());
|
||||||
|
$comment_view->setQuoteTargetID('comment-content');
|
||||||
|
}
|
||||||
|
|
||||||
$wrap_id = celerity_generate_unique_node_id();
|
$wrap_id = celerity_generate_unique_node_id();
|
||||||
$comment_view = phutil_tag(
|
$comment_view = phutil_tag(
|
||||||
'div',
|
'div',
|
||||||
|
@ -373,8 +378,6 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$comment_form->setErrorView($review_warnings_panel);
|
$comment_form->setErrorView($review_warnings_panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Restore the ability for fields to add accept warnings.
|
|
||||||
|
|
||||||
$comment_form->setActions($this->getRevisionCommentActions($revision));
|
$comment_form->setActions($this->getRevisionCommentActions($revision));
|
||||||
$action_uri = $this->getApplicationURI(
|
$action_uri = $this->getApplicationURI(
|
||||||
'comment/save/'.$revision->getID().'/');
|
'comment/save/'.$revision->getID().'/');
|
||||||
|
@ -415,6 +418,7 @@ final class DifferentialRevisionViewController extends DifferentialController {
|
||||||
$changeset_view,
|
$changeset_view,
|
||||||
));
|
));
|
||||||
if ($comment_form) {
|
if ($comment_form) {
|
||||||
|
|
||||||
$page_pane->appendChild($comment_form);
|
$page_pane->appendChild($comment_form);
|
||||||
} else {
|
} else {
|
||||||
// TODO: For now, just use this to get "Login to Comment".
|
// TODO: For now, just use this to get "Login to Comment".
|
||||||
|
|
|
@ -377,6 +377,8 @@ final class ManiphestTaskDetailController extends ManiphestController {
|
||||||
->setFlush(true)
|
->setFlush(true)
|
||||||
->setHeaderText($comment_header)
|
->setHeaderText($comment_header)
|
||||||
->appendChild($comment_form);
|
->appendChild($comment_form);
|
||||||
|
$timeline->setQuoteTargetID('transaction-comments');
|
||||||
|
$timeline->setQuoteRef($object_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
$object_box = id(new PHUIObjectBoxView())
|
$object_box = id(new PHUIObjectBoxView())
|
||||||
|
|
|
@ -19,6 +19,8 @@ final class PhabricatorApplicationTransactions extends PhabricatorApplication {
|
||||||
=> 'PhabricatorApplicationTransactionCommentRemoveController',
|
=> 'PhabricatorApplicationTransactionCommentRemoveController',
|
||||||
'history/(?<phid>[^/]+)/'
|
'history/(?<phid>[^/]+)/'
|
||||||
=> 'PhabricatorApplicationTransactionCommentHistoryController',
|
=> 'PhabricatorApplicationTransactionCommentHistoryController',
|
||||||
|
'quote/(?<phid>[^/]+)/'
|
||||||
|
=> 'PhabricatorApplicationTransactionCommentQuoteController',
|
||||||
'detail/(?<phid>[^/]+)/'
|
'detail/(?<phid>[^/]+)/'
|
||||||
=> 'PhabricatorApplicationTransactionDetailController',
|
=> 'PhabricatorApplicationTransactionDetailController',
|
||||||
'(?P<value>old|new)/(?<phid>[^/]+)/'
|
'(?P<value>old|new)/(?<phid>[^/]+)/'
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorApplicationTransactionCommentQuoteController
|
||||||
|
extends PhabricatorApplicationTransactionController {
|
||||||
|
|
||||||
|
private $phid;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->phid = $data['phid'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $request->getUser();
|
||||||
|
|
||||||
|
$xaction = id(new PhabricatorObjectQuery())
|
||||||
|
->withPHIDs(array($this->phid))
|
||||||
|
->setViewer($viewer)
|
||||||
|
->executeOne();
|
||||||
|
if (!$xaction) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$xaction->getComment()) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($xaction->getComment()->getIsRemoved()) {
|
||||||
|
return new Aphront400Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$xaction->hasComment()) {
|
||||||
|
return new Aphront404Response();
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = $xaction->getComment()->getContent();
|
||||||
|
$content = phutil_split_lines($content, true);
|
||||||
|
foreach ($content as $key => $line) {
|
||||||
|
if (strlen($line) && ($line[0] != '>')) {
|
||||||
|
$content[$key] = '> '.$line;
|
||||||
|
} else {
|
||||||
|
$content[$key] = '>'.$line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$content = implode('', $content);
|
||||||
|
|
||||||
|
$author = id(new PhabricatorHandleQuery())
|
||||||
|
->setViewer($viewer)
|
||||||
|
->withPHIDs(array($xaction->getComment()->getAuthorPHID()))
|
||||||
|
->executeOne();
|
||||||
|
|
||||||
|
$ref = $request->getStr('ref');
|
||||||
|
if (strlen($ref)) {
|
||||||
|
$quote = pht('In %s, %s wrote:', $ref, '@'.$author->getName());
|
||||||
|
} else {
|
||||||
|
$quote = pht('%s wrote:', '@'.$author->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = ">>! {$quote}\n{$content}";
|
||||||
|
|
||||||
|
return id(new AphrontAjaxResponse())->setContent(
|
||||||
|
array(
|
||||||
|
'quoteText' => $content,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,6 +12,26 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
private $isPreview;
|
private $isPreview;
|
||||||
private $objectPHID;
|
private $objectPHID;
|
||||||
private $shouldTerminate = false;
|
private $shouldTerminate = false;
|
||||||
|
private $quoteTargetID;
|
||||||
|
private $quoteRef;
|
||||||
|
|
||||||
|
public function setQuoteRef($quote_ref) {
|
||||||
|
$this->quoteRef = $quote_ref;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuoteRef() {
|
||||||
|
return $this->quoteRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setQuoteTargetID($quote_target_id) {
|
||||||
|
$this->quoteTargetID = $quote_target_id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuoteTargetID() {
|
||||||
|
return $this->quoteTargetID;
|
||||||
|
}
|
||||||
|
|
||||||
public function setObjectPHID($object_phid) {
|
public function setObjectPHID($object_phid) {
|
||||||
$this->objectPHID = $object_phid;
|
$this->objectPHID = $object_phid;
|
||||||
|
@ -376,6 +396,17 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
$event->setIsEdited(true);
|
$event->setIsEdited(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have a place for quoted text to go and this is a quotable
|
||||||
|
// comment, pass the quote target ID to the event view.
|
||||||
|
if ($this->getQuoteTargetID()) {
|
||||||
|
if ($xaction->hasComment()) {
|
||||||
|
if (!$has_removed_comment && !$has_deleted_comment) {
|
||||||
|
$event->setQuoteTargetID($this->getQuoteTargetID());
|
||||||
|
$event->setQuoteRef($this->getQuoteRef());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
|
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
|
||||||
|
|
||||||
if ($xaction->hasComment() || $has_deleted_comment) {
|
if ($xaction->hasComment() || $has_deleted_comment) {
|
||||||
|
|
|
@ -21,6 +21,26 @@ final class PHUITimelineEventView extends AphrontView {
|
||||||
private $hideByDefault;
|
private $hideByDefault;
|
||||||
private $token;
|
private $token;
|
||||||
private $tokenRemoved;
|
private $tokenRemoved;
|
||||||
|
private $quoteTargetID;
|
||||||
|
private $quoteRef;
|
||||||
|
|
||||||
|
public function setQuoteRef($quote_ref) {
|
||||||
|
$this->quoteRef = $quote_ref;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuoteRef() {
|
||||||
|
return $this->quoteRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setQuoteTargetID($quote_target_id) {
|
||||||
|
$this->quoteTargetID = $quote_target_id;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuoteTargetID() {
|
||||||
|
return $this->quoteTargetID;
|
||||||
|
}
|
||||||
|
|
||||||
public function setHideByDefault($hide_by_default) {
|
public function setHideByDefault($hide_by_default) {
|
||||||
$this->hideByDefault = $hide_by_default;
|
$this->hideByDefault = $hide_by_default;
|
||||||
|
@ -357,6 +377,31 @@ final class PHUITimelineEventView extends AphrontView {
|
||||||
} else {
|
} else {
|
||||||
$xaction_phid = $this->getTransactionPHID();
|
$xaction_phid = $this->getTransactionPHID();
|
||||||
|
|
||||||
|
if ($this->getQuoteTargetID()) {
|
||||||
|
|
||||||
|
$ref = null;
|
||||||
|
if ($this->getQuoteRef()) {
|
||||||
|
$ref = $this->getQuoteRef();
|
||||||
|
if ($this->anchor) {
|
||||||
|
$ref = $ref.'#'.$this->anchor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$extra[] = javelin_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '#',
|
||||||
|
'sigil' => 'transaction-quote',
|
||||||
|
'mustcapture' => true,
|
||||||
|
'meta' => array(
|
||||||
|
'targetID' => $this->getQuoteTargetID(),
|
||||||
|
'uri' => '/transactions/quote/'.$xaction_phid.'/',
|
||||||
|
'ref' => $ref,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
pht('Quote'));
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->getIsEdited()) {
|
if ($this->getIsEdited()) {
|
||||||
$extra[] = javelin_tag(
|
$extra[] = javelin_tag(
|
||||||
'a',
|
'a',
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* javelin-dom
|
* javelin-dom
|
||||||
* javelin-fx
|
* javelin-fx
|
||||||
* javelin-util
|
* javelin-util
|
||||||
|
* phabricator-textareautils
|
||||||
*/
|
*/
|
||||||
|
|
||||||
JX.behavior('phabricator-transaction-list', function(config) {
|
JX.behavior('phabricator-transaction-list', function(config) {
|
||||||
|
@ -115,6 +116,37 @@ JX.behavior('phabricator-transaction-list', function(config) {
|
||||||
e.kill();
|
e.kill();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
JX.DOM.listen(
|
||||||
|
list,
|
||||||
|
'click',
|
||||||
|
'transaction-quote',
|
||||||
|
function(e) {
|
||||||
|
e.kill();
|
||||||
|
|
||||||
|
var data = e.getNodeData('transaction-quote');
|
||||||
|
new JX.Workflow(data.uri)
|
||||||
|
.setData({ref: data.ref})
|
||||||
|
.setHandler(function(r) {
|
||||||
|
var textarea = JX.$(data.targetID);
|
||||||
|
|
||||||
|
JX.DOM.scrollTo(textarea);
|
||||||
|
|
||||||
|
var value = textarea.value;
|
||||||
|
if (value.length) {
|
||||||
|
value += "\n\n";
|
||||||
|
}
|
||||||
|
value += r.quoteText;
|
||||||
|
value += "\n\n";
|
||||||
|
textarea.value = value;
|
||||||
|
|
||||||
|
JX.TextAreaUtils.setSelectionRange(
|
||||||
|
textarea,
|
||||||
|
textarea.value.length,
|
||||||
|
textarea.value.length);
|
||||||
|
})
|
||||||
|
.start();
|
||||||
|
});
|
||||||
|
|
||||||
JX.Stratcom.listen(
|
JX.Stratcom.listen(
|
||||||
['submit', 'didSyntheticSubmit'],
|
['submit', 'didSyntheticSubmit'],
|
||||||
'transaction-append',
|
'transaction-append',
|
||||||
|
|
Loading…
Reference in a new issue