@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

When users submit "editing" inlines, warn them that their inlines will be saved

Summary: Ref T13513. This slightly expands the existing-but-hacky "warning" workflow to cover both "mentions on draft" and "submitting inlines being edited".

Test Plan:
- Submitted changes to a revision with mentions on a draft, inlines being edited, both, and neither.
- Got sensible warnings in the cases where warnings were appropriate.

Maniphest Tasks: T13513

Differential Revision: https://secure.phabricator.com/D21191

+228 -19
+3 -3
resources/celerity/map.php
··· 9 9 'names' => array( 10 10 'conpherence.pkg.css' => '0e3cf785', 11 11 'conpherence.pkg.js' => '020aebcf', 12 - 'core.pkg.css' => 'f5ebbd7d', 12 + 'core.pkg.css' => '1b80c45d', 13 13 'core.pkg.js' => '632fb8f5', 14 14 'dark-console.pkg.js' => '187792c2', 15 15 'differential.pkg.css' => '2d70b7b9', ··· 25 25 'rsrc/audio/basic/ting.mp3' => 'a6b6540e', 26 26 'rsrc/css/aphront/aphront-bars.css' => '4a327b4a', 27 27 'rsrc/css/aphront/dark-console.css' => '7f06cda2', 28 - 'rsrc/css/aphront/dialog-view.css' => '874f5c06', 28 + 'rsrc/css/aphront/dialog-view.css' => '6f4ea703', 29 29 'rsrc/css/aphront/list-filter-view.css' => 'feb64255', 30 30 'rsrc/css/aphront/multi-column.css' => 'fbc00ba3', 31 31 'rsrc/css/aphront/notification.css' => '30240bd2', ··· 536 536 'almanac-css' => '2e050f4f', 537 537 'aphront-bars' => '4a327b4a', 538 538 'aphront-dark-console-css' => '7f06cda2', 539 - 'aphront-dialog-view-css' => '874f5c06', 539 + 'aphront-dialog-view-css' => '6f4ea703', 540 540 'aphront-list-filter-view-css' => 'feb64255', 541 541 'aphront-multi-column-view-css' => 'fbc00ba3', 542 542 'aphront-panel-view-css' => '46923d46',
+2
src/__phutil_library_map__.php
··· 4994 4994 'PhabricatorTransactionChange' => 'applications/transactions/data/PhabricatorTransactionChange.php', 4995 4995 'PhabricatorTransactionFactEngine' => 'applications/fact/engine/PhabricatorTransactionFactEngine.php', 4996 4996 'PhabricatorTransactionRemarkupChange' => 'applications/transactions/data/PhabricatorTransactionRemarkupChange.php', 4997 + 'PhabricatorTransactionWarning' => 'applications/transactions/data/PhabricatorTransactionWarning.php', 4997 4998 'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php', 4998 4999 'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php', 4999 5000 'PhabricatorTransactionsDestructionEngineExtension' => 'applications/transactions/engineextension/PhabricatorTransactionsDestructionEngineExtension.php', ··· 11768 11769 'PhabricatorTransactionChange' => 'Phobject', 11769 11770 'PhabricatorTransactionFactEngine' => 'PhabricatorFactEngine', 11770 11771 'PhabricatorTransactionRemarkupChange' => 'PhabricatorTransactionChange', 11772 + 'PhabricatorTransactionWarning' => 'Phobject', 11771 11773 'PhabricatorTransactions' => 'Phobject', 11772 11774 'PhabricatorTransactionsApplication' => 'PhabricatorApplication', 11773 11775 'PhabricatorTransactionsDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension',
+40
src/applications/differential/storage/DifferentialTransaction.php
··· 578 578 return $body; 579 579 } 580 580 581 + public function newWarningForTransactions($object, array $xactions) { 582 + $warning = new PhabricatorTransactionWarning(); 583 + 584 + switch ($this->getTransactionType()) { 585 + case self::TYPE_INLINE: 586 + $warning->setTitleText(pht('Warning: Editing Inlines')); 587 + $warning->setContinueActionText(pht('Save Inlines and Continue')); 588 + 589 + $count = phutil_count($xactions); 590 + 591 + $body = array(); 592 + $body[] = pht( 593 + 'You are currently editing %s inline comment(s) on this '. 594 + 'revision.', 595 + $count); 596 + $body[] = pht( 597 + 'These %s inline comment(s) will be saved and published.', 598 + $count); 599 + 600 + $warning->setWarningParagraphs($body); 601 + break; 602 + case PhabricatorTransactions::TYPE_SUBSCRIBERS: 603 + $warning->setTitleText(pht('Warning: Draft Revision')); 604 + $warning->setContinueActionText(pht('Tell No One')); 605 + 606 + $body = array(); 607 + 608 + $body[] = pht( 609 + 'This is a draft revision that will not publish any '. 610 + 'notifications until the author requests review.'); 611 + 612 + $body[] = pht('Mentioned or subscribed users will not be notified.'); 613 + 614 + $warning->setWarningParagraphs($body); 615 + break; 616 + } 617 + 618 + return $warning; 619 + } 620 + 581 621 582 622 }
+47
src/applications/transactions/data/PhabricatorTransactionWarning.php
··· 1 + <?php 2 + 3 + final class PhabricatorTransactionWarning 4 + extends Phobject { 5 + 6 + private $titleText; 7 + private $continueActionText; 8 + private $cancelActionText; 9 + private $warningParagraphs = array(); 10 + 11 + public function setTitleText($title_text) { 12 + $this->titleText = $title_text; 13 + return $this; 14 + } 15 + 16 + public function getTitleText() { 17 + return $this->titleText; 18 + } 19 + 20 + public function setContinueActionText($continue_action_text) { 21 + $this->continueActionText = $continue_action_text; 22 + return $this; 23 + } 24 + 25 + public function getContinueActionText() { 26 + return $this->continueActionText; 27 + } 28 + 29 + public function setCancelActionText($cancel_action_text) { 30 + $this->cancelActionText = $cancel_action_text; 31 + return $this; 32 + } 33 + 34 + public function getCancelActionText() { 35 + return $this->cancelActionText; 36 + } 37 + 38 + public function setWarningParagraphs(array $warning_paragraphs) { 39 + $this->warningParagraphs = $warning_paragraphs; 40 + return $this; 41 + } 42 + 43 + public function getWarningParagraphs() { 44 + return $this->warningParagraphs; 45 + } 46 + 47 + }
+1
src/applications/transactions/editengine/PhabricatorEditEngine.php
··· 2032 2032 ->setException($ex); 2033 2033 } catch (PhabricatorApplicationTransactionWarningException $ex) { 2034 2034 return id(new PhabricatorApplicationTransactionWarningResponse()) 2035 + ->setObject($object) 2035 2036 ->setCancelURI($view_uri) 2036 2037 ->setException($ex); 2037 2038 }
+8 -1
src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
··· 4975 4975 return false; 4976 4976 } 4977 4977 4978 + $type = $xaction->getTransactionType(); 4979 + 4980 + // TODO: This doesn't warn for inlines in Audit, even though they have 4981 + // the same overall workflow. 4982 + if ($type === DifferentialTransaction::TYPE_INLINE) { 4983 + return (bool)$xaction->getComment()->getAttribute('editing', false); 4984 + } 4985 + 4978 4986 if (!$object->isDraft()) { 4979 4987 return false; 4980 4988 } 4981 4989 4982 - $type = $xaction->getTransactionType(); 4983 4990 if ($type != PhabricatorTransactions::TYPE_SUBSCRIBERS) { 4984 4991 return false; 4985 4992 }
+4
src/applications/transactions/exception/PhabricatorApplicationTransactionWarningException.php
··· 10 10 parent::__construct(); 11 11 } 12 12 13 + public function getTransactions() { 14 + return $this->xactions; 15 + } 16 + 13 17 }
+101 -15
src/applications/transactions/response/PhabricatorApplicationTransactionWarningResponse.php
··· 4 4 extends AphrontProxyResponse { 5 5 6 6 private $viewer; 7 + private $object; 7 8 private $exception; 8 9 private $cancelURI; 9 10 11 + public function setObject($object) { 12 + $this->object = $object; 13 + return $this; 14 + } 15 + 16 + public function getObject() { 17 + return $this->object; 18 + } 19 + 10 20 public function setCancelURI($cancel_uri) { 11 21 $this->cancelURI = $cancel_uri; 12 22 return $this; ··· 18 28 return $this; 19 29 } 20 30 31 + public function getException() { 32 + return $this->exception; 33 + } 34 + 21 35 protected function buildProxy() { 22 36 return new AphrontDialogResponse(); 23 37 } 24 38 25 39 public function reduceProxyResponse() { 26 40 $request = $this->getRequest(); 41 + $viewer = $request->getViewer(); 42 + $object = $this->getObject(); 27 43 28 - $title = pht('Warning: Unexpected Effects'); 44 + $xactions = $this->getException()->getTransactions(); 45 + $xaction_groups = mgroup($xactions, 'getTransactionType'); 29 46 30 - $head = pht( 31 - 'This is a draft revision that will not publish any notifications '. 32 - 'until the author requests review.'); 33 - $tail = pht( 34 - 'Mentioned or subscribed users will not be notified.'); 47 + $warnings = array(); 48 + foreach ($xaction_groups as $xaction_group) { 49 + $xaction = head($xaction_group); 35 50 36 - $continue = pht('Tell No One'); 51 + $warning = $xaction->newWarningForTransactions( 52 + $object, 53 + $xaction_group); 54 + 55 + if (!($warning instanceof PhabricatorTransactionWarning)) { 56 + throw new Exception( 57 + pht( 58 + 'Expected "newTransactionWarning()" to return an object of '. 59 + 'class "PhabricatorTransactionWarning", got something else '. 60 + '("%s") from transaction of class "%s".', 61 + phutil_describe_type($warning), 62 + get_class($xaction))); 63 + } 64 + 65 + $warnings[] = $warning; 66 + } 37 67 38 68 $dialog = id(new AphrontDialogView()) 39 - ->setViewer($request->getViewer()) 40 - ->setTitle($title); 69 + ->setViewer($viewer); 41 70 42 - $dialog->appendParagraph($head); 43 - $dialog->appendParagraph($tail); 71 + $last_key = last_key($warnings); 72 + foreach ($warnings as $warning_key => $warning) { 73 + $paragraphs = $warning->getWarningParagraphs(); 74 + foreach ($paragraphs as $paragraph) { 75 + $dialog->appendParagraph($paragraph); 76 + } 77 + 78 + if ($warning_key !== $last_key) { 79 + $dialog->appendChild(phutil_tag('hr')); 80 + } 81 + } 82 + 83 + $title_texts = array(); 84 + $continue_texts = array(); 85 + $cancel_texts = array(); 86 + foreach ($warnings as $warning) { 87 + $title_text = $warning->getTitleText(); 88 + if ($title_text !== null) { 89 + $title_texts[] = $title_text; 90 + } 91 + 92 + $continue_text = $warning->getContinueActionText(); 93 + if ($continue_text !== null) { 94 + $continue_texts[] = $continue_text; 95 + } 96 + 97 + $cancel_text = $warning->getCancelActionText(); 98 + if ($cancel_text !== null) { 99 + $cancel_texts[] = $cancel_text; 100 + } 101 + } 102 + 103 + $title_texts = array_unique($title_texts); 104 + if (count($title_texts) === 1) { 105 + $title = head($title_texts); 106 + } else { 107 + $title = pht('Warnings'); 108 + } 109 + 110 + $continue_texts = array_unique($continue_texts); 111 + if (count($continue_texts) === 1) { 112 + $continue_action = head($continue_texts); 113 + } else { 114 + $continue_action = pht('Continue'); 115 + } 116 + 117 + $cancel_texts = array_unique($cancel_texts); 118 + if (count($cancel_texts) === 1) { 119 + $cancel_action = head($cancel_texts); 120 + } else { 121 + $cancel_action = null; 122 + } 123 + 124 + $dialog 125 + ->setTitle($title) 126 + ->addSubmitButton($continue_action); 127 + 128 + if ($cancel_action === null) { 129 + $dialog->addCancelButton($this->cancelURI); 130 + } else { 131 + $dialog->addCancelButton($this->cancelURI, $cancel_action); 132 + } 44 133 45 134 $passthrough = $request->getPassthroughRequestParameters(); 46 135 foreach ($passthrough as $key => $value) { 47 136 $dialog->addHiddenInput($key, $value); 48 137 } 49 138 50 - $dialog 51 - ->addHiddenInput('editEngine.warnings', 1) 52 - ->addSubmitButton($continue) 53 - ->addCancelButton($this->cancelURI); 139 + $dialog->addHiddenInput('editEngine.warnings', 1); 54 140 55 141 return $this->getProxy()->setDialog($dialog); 56 142 }
+6
src/applications/transactions/storage/PhabricatorModularTransaction.php
··· 196 196 return $this->getTransactionImplementation()->newRemarkupChanges(); 197 197 } 198 198 199 + /* final */ public function newWarningForTransactions( 200 + $object, 201 + array $xactions) { 202 + throw new PhutilMethodNotImplementedException(); 203 + } 204 + 199 205 }
+11
src/infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php
··· 1723 1723 'View All %d Subscribers', 1724 1724 ), 1725 1725 1726 + 'You are currently editing %s inline comment(s) on this '. 1727 + 'revision.' => array( 1728 + 'You are currently editing an inline comment on this revision.', 1729 + 'You are currently editing %s inline comments on this revision.', 1730 + ), 1731 + 1732 + 'These %s inline comment(s) will be saved and published.' => array( 1733 + 'This inline comment will be saved and published.', 1734 + 'These inline comments will be saved and published.', 1735 + ), 1736 + 1726 1737 ); 1727 1738 } 1728 1739
+5
webroot/rsrc/css/aphront/dialog-view.css
··· 192 192 .aphront-dialog-tab-group .aphront-dialog-body { 193 193 padding: 0 12px; 194 194 } 195 + 196 + .aphront-dialog-body > hr { 197 + background: {$thinblueborder}; 198 + margin: 24px 12px; 199 + }