mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-21 04:50:55 +01:00
Add links and diffs for text block edits to mail
Summary: Ref T7643. - When a transaction edits a text block, add a link to the changes (for HTML mail). - Also, inline the changes in the mail (for HTML mail). - Do nothing for text mail since I don't think we really have room? And I don't know how we can make the diff look any good. Test Plan: Edited a task description, generated mail, examined mail. - It contained a link leading to a prose diff. - It had a more-or-less reasonable inline text diff. Reviewers: chad Reviewed By: chad Maniphest Tasks: T7643 Differential Revision: https://secure.phabricator.com/D16063
This commit is contained in:
parent
d1999557dc
commit
fb2da8bd8b
5 changed files with 157 additions and 11 deletions
|
@ -3,11 +3,16 @@
|
||||||
final class PhabricatorApplicationTransactionDetailController
|
final class PhabricatorApplicationTransactionDetailController
|
||||||
extends PhabricatorApplicationTransactionController {
|
extends PhabricatorApplicationTransactionController {
|
||||||
|
|
||||||
|
private $objectHandle;
|
||||||
|
|
||||||
public function shouldAllowPublic() {
|
public function shouldAllowPublic() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handleRequest(AphrontRequest $request) {
|
public function handleRequest(AphrontRequest $request) {
|
||||||
|
// Users can end up on this page directly by following links in email,
|
||||||
|
// so we try to make it somewhat reasonable as a standalone page.
|
||||||
|
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
$phid = $request->getURIData('phid');
|
$phid = $request->getURIData('phid');
|
||||||
|
|
||||||
|
@ -20,13 +25,39 @@ final class PhabricatorApplicationTransactionDetailController
|
||||||
}
|
}
|
||||||
|
|
||||||
$details = $xaction->renderChangeDetails($viewer);
|
$details = $xaction->renderChangeDetails($viewer);
|
||||||
$cancel_uri = $this->guessCancelURI($viewer, $xaction);
|
|
||||||
|
$object_phid = $xaction->getObjectPHID();
|
||||||
|
$handles = $viewer->loadHandles(array($object_phid));
|
||||||
|
$handle = $handles[$object_phid];
|
||||||
|
$this->objectHandle = $handle;
|
||||||
|
|
||||||
|
$cancel_uri = $handle->getURI();
|
||||||
|
|
||||||
|
if ($request->isAjax()) {
|
||||||
|
$button_text = pht('Done');
|
||||||
|
} else {
|
||||||
|
$button_text = pht('Continue');
|
||||||
|
}
|
||||||
|
|
||||||
return $this->newDialog()
|
return $this->newDialog()
|
||||||
->setTitle(pht('Change Details'))
|
->setTitle(pht('Change Details'))
|
||||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||||
->appendChild($details)
|
->appendChild($details)
|
||||||
->addCancelButton($cancel_uri);
|
->addCancelButton($cancel_uri, $button_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function buildApplicationCrumbs() {
|
||||||
|
$crumbs = parent::buildApplicationCrumbs();
|
||||||
|
|
||||||
|
$handle = $this->objectHandle;
|
||||||
|
if ($handle) {
|
||||||
|
$crumbs->addTextCrumb(
|
||||||
|
$handle->getObjectName(),
|
||||||
|
$handle->getURI());
|
||||||
|
}
|
||||||
|
|
||||||
|
return $crumbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2704,7 +2704,9 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$object_href = null) {
|
$object_href = null) {
|
||||||
|
|
||||||
$headers = array();
|
$headers = array();
|
||||||
|
$headers_html = array();
|
||||||
$comments = array();
|
$comments = array();
|
||||||
|
$details = array();
|
||||||
|
|
||||||
foreach ($xactions as $xaction) {
|
foreach ($xactions as $xaction) {
|
||||||
if ($xaction->shouldHideForMail($xactions)) {
|
if ($xaction->shouldHideForMail($xactions)) {
|
||||||
|
@ -2716,16 +2718,25 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
$headers[] = $header;
|
$headers[] = $header;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$header_html = $xaction->getTitleForHTMLMail();
|
||||||
|
if ($header_html !== null) {
|
||||||
|
$headers_html[] = $header_html;
|
||||||
|
}
|
||||||
|
|
||||||
$comment = $xaction->getBodyForMail();
|
$comment = $xaction->getBodyForMail();
|
||||||
if ($comment !== null) {
|
if ($comment !== null) {
|
||||||
$comments[] = $comment;
|
$comments[] = $comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($xaction->hasChangeDetailsForMail()) {
|
||||||
|
$details[] = $xaction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$headers_text = implode("\n", $headers);
|
$headers_text = implode("\n", $headers);
|
||||||
$body->addRawPlaintextSection($headers_text);
|
$body->addRawPlaintextSection($headers_text);
|
||||||
|
|
||||||
$headers_html = phutil_implode_html(phutil_tag('br'), $headers);
|
$headers_html = phutil_implode_html(phutil_tag('br'), $headers_html);
|
||||||
|
|
||||||
$header_button = null;
|
$header_button = null;
|
||||||
if ($object_label !== null) {
|
if ($object_label !== null) {
|
||||||
|
@ -2765,7 +2776,13 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
array(
|
array(
|
||||||
'style' => implode(' ', $xactions_style),
|
'style' => implode(' ', $xactions_style),
|
||||||
),
|
),
|
||||||
$headers_html);
|
array(
|
||||||
|
$headers_html,
|
||||||
|
// Add an extra newline to prevent the "View Object" button from
|
||||||
|
// running into the transaction text in Mail.app text snippet
|
||||||
|
// previews.
|
||||||
|
"\n",
|
||||||
|
));
|
||||||
|
|
||||||
$headers_html = phutil_tag(
|
$headers_html = phutil_tag(
|
||||||
'table',
|
'table',
|
||||||
|
@ -2777,6 +2794,14 @@ abstract class PhabricatorApplicationTransactionEditor
|
||||||
foreach ($comments as $comment) {
|
foreach ($comments as $comment) {
|
||||||
$body->addRemarkupSection(null, $comment);
|
$body->addRemarkupSection(null, $comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($details as $xaction) {
|
||||||
|
$details = $xaction->renderChangeDetailsForMail($body->getViewer());
|
||||||
|
if ($details !== null) {
|
||||||
|
$body->addHTMLSection(pht('EDIT DETAILS'), $details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -693,6 +693,33 @@ abstract class PhabricatorApplicationTransaction
|
||||||
return id(clone $this)->setRenderingTarget('text')->getTitle();
|
return id(clone $this)->setRenderingTarget('text')->getTitle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getTitleForHTMLMail() {
|
||||||
|
$title = $this->getTitleForMail();
|
||||||
|
if ($title === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($this->hasChangeDetails()) {
|
||||||
|
$details_uri = $this->getChangeDetailsURI();
|
||||||
|
$details_uri = PhabricatorEnv::getProductionURI($details_uri);
|
||||||
|
|
||||||
|
$show_details = phutil_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $details_uri,
|
||||||
|
),
|
||||||
|
pht('(Show Details)'));
|
||||||
|
|
||||||
|
$title = array($title, ' ', $show_details);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getChangeDetailsURI() {
|
||||||
|
return '/transactions/detail/'.$this->getPHID().'/';
|
||||||
|
}
|
||||||
|
|
||||||
public function getBodyForMail() {
|
public function getBodyForMail() {
|
||||||
if ($this->isInlineCommentTransaction()) {
|
if ($this->isInlineCommentTransaction()) {
|
||||||
// We don't return inline comment content as mail body content, because
|
// We don't return inline comment content as mail body content, because
|
||||||
|
@ -1307,6 +1334,18 @@ abstract class PhabricatorApplicationTransaction
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasChangeDetailsForMail() {
|
||||||
|
return $this->hasChangeDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderChangeDetailsForMail(PhabricatorUser $viewer) {
|
||||||
|
$view = $this->renderChangeDetails($viewer);
|
||||||
|
if ($view instanceof PhabricatorApplicationTransactionTextDiffDetailView) {
|
||||||
|
return $view->renderForMail();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public function renderChangeDetails(PhabricatorUser $viewer) {
|
public function renderChangeDetails(PhabricatorUser $viewer) {
|
||||||
switch ($this->getTransactionType()) {
|
switch ($this->getTransactionType()) {
|
||||||
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
case PhabricatorTransactions::TYPE_CUSTOMFIELD:
|
||||||
|
@ -1327,15 +1366,10 @@ abstract class PhabricatorApplicationTransaction
|
||||||
PhabricatorUser $viewer,
|
PhabricatorUser $viewer,
|
||||||
$old,
|
$old,
|
||||||
$new) {
|
$new) {
|
||||||
|
return id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
||||||
require_celerity_resource('differential-changeset-view-css');
|
|
||||||
|
|
||||||
$view = id(new PhabricatorApplicationTransactionTextDiffDetailView())
|
|
||||||
->setUser($viewer)
|
->setUser($viewer)
|
||||||
->setOldText($old)
|
->setOldText($old)
|
||||||
->setNewText($new);
|
->setNewText($new);
|
||||||
|
|
||||||
return $view->render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function attachTransactionGroup(array $group) {
|
public function attachTransactionGroup(array $group) {
|
||||||
|
|
|
@ -16,6 +16,62 @@ final class PhabricatorApplicationTransactionTextDiffDetailView
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function renderForMail() {
|
||||||
|
$diff = $this->buildDiff();
|
||||||
|
|
||||||
|
$old_styles = array(
|
||||||
|
'padding: 0 2px;',
|
||||||
|
'color: #802b2b;',
|
||||||
|
'background: rgba(251, 175, 175, .7);',
|
||||||
|
);
|
||||||
|
$old_styles = implode(' ', $old_styles);
|
||||||
|
|
||||||
|
$new_styles = array(
|
||||||
|
'padding: 0 2px;',
|
||||||
|
'color: #3e6d35;',
|
||||||
|
'background: rgba(151, 234, 151, .6);',
|
||||||
|
);
|
||||||
|
$new_styles = implode(' ', $new_styles);
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
foreach ($diff->getParts() as $part) {
|
||||||
|
$type = $part['type'];
|
||||||
|
$text = $part['text'];
|
||||||
|
switch ($type) {
|
||||||
|
case '-':
|
||||||
|
$result[] = phutil_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'style' => $old_styles,
|
||||||
|
),
|
||||||
|
$text);
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
$result[] = phutil_tag(
|
||||||
|
'span',
|
||||||
|
array(
|
||||||
|
'style' => $new_styles,
|
||||||
|
),
|
||||||
|
$text);
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
$result[] = $text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$styles = array(
|
||||||
|
'white-space: pre-wrap;',
|
||||||
|
);
|
||||||
|
|
||||||
|
return phutil_tag(
|
||||||
|
'div',
|
||||||
|
array(
|
||||||
|
'style' => implode(' ', $styles),
|
||||||
|
),
|
||||||
|
$result);
|
||||||
|
}
|
||||||
|
|
||||||
public function render() {
|
public function render() {
|
||||||
$diff = $this->buildDiff();
|
$diff = $this->buildDiff();
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,7 @@ class PhabricatorApplicationTransactionView extends AphrontView {
|
||||||
return javelin_tag(
|
return javelin_tag(
|
||||||
'a',
|
'a',
|
||||||
array(
|
array(
|
||||||
'href' => '/transactions/detail/'.$xaction->getPHID().'/',
|
'href' => $xaction->getChangeDetailsURI(),
|
||||||
'sigil' => 'workflow',
|
'sigil' => 'workflow',
|
||||||
),
|
),
|
||||||
pht('(Show Details)'));
|
pht('(Show Details)'));
|
||||||
|
|
Loading…
Reference in a new issue