From c7094d2def1d58d48cf3725e331e2d63754c80c9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Mon, 27 Feb 2012 13:00:23 -0800 Subject: [PATCH] Add preview and drafts to audits Summary: Add comment previews and saved drafts to audits, like Maniphest / Differential. Test Plan: Typed stuff into the box. Got a preview. Reloaded page. Stuff was still there. Submitted comment. Stuff is gone. Reviewers: btrahan, jungejason Reviewed By: btrahan CC: aran, epriestley Maniphest Tasks: T904 Differential Revision: https://secure.phabricator.com/D1699 --- src/__celerity_resource_map__.php | 51 +++++++++------ src/__phutil_library_map__.php | 2 + ...AphrontDefaultApplicationConfiguration.php | 1 + .../PhabricatorAuditAddCommentController.php | 9 +++ .../audit/controller/addcomment/__init__.php | 1 + .../PhabricatorAuditPreviewController.php | 62 +++++++++++++++++++ .../audit/controller/preview/__init__.php | 21 +++++++ .../commit/DiffusionCommitController.php | 36 ++++++++++- .../diffusion/controller/commit/__init__.php | 3 + .../view/comment/DiffusionCommentView.php | 33 ++++++++-- .../diffusion/behavior-audit-preview.js | 33 ++++++++++ 11 files changed, 228 insertions(+), 24 deletions(-) create mode 100644 src/applications/audit/controller/preview/PhabricatorAuditPreviewController.php create mode 100644 src/applications/audit/controller/preview/__init__.php create mode 100644 webroot/rsrc/js/application/diffusion/behavior-audit-preview.js diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 35ffdc7ddd..fa217f712e 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -72,7 +72,7 @@ celerity_register_resource_map(array( ), 'aphront-form-view-css' => array( - 'uri' => '/res/464a73e6/rsrc/css/aphront/form-view.css', + 'uri' => '/res/08bac3d6/rsrc/css/aphront/form-view.css', 'type' => 'css', 'requires' => array( @@ -108,7 +108,7 @@ celerity_register_resource_map(array( ), 'aphront-panel-view-css' => array( - 'uri' => '/res/b7ba1078/rsrc/css/aphront/panel-view.css', + 'uri' => '/res/12ca19c9/rsrc/css/aphront/panel-view.css', 'type' => 'css', 'requires' => array( @@ -384,6 +384,19 @@ celerity_register_resource_map(array( ), 'disk' => '/rsrc/js/application/core/behavior-form.js', ), + 'javelin-behavior-audit-preview' => + array( + 'uri' => '/res/3048b073/rsrc/js/application/diffusion/behavior-audit-preview.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-dom', + 2 => 'javelin-util', + 3 => 'phabricator-shaped-request', + ), + 'disk' => '/rsrc/js/application/diffusion/behavior-audit-preview.js', + ), 'javelin-behavior-buoyant' => array( 'uri' => '/res/e7581db1/rsrc/js/application/core/behavior-buoyant.js', @@ -1914,7 +1927,7 @@ celerity_register_resource_map(array( 'uri' => '/res/pkg/61f9d480/diffusion.pkg.css', 'type' => 'css', ), - '6a6def05' => + '784dc660' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -1935,7 +1948,7 @@ celerity_register_resource_map(array( 13 => 'phabricator-remarkup-css', 14 => 'syntax-highlighting-css', ), - 'uri' => '/res/pkg/6a6def05/core.pkg.css', + 'uri' => '/res/pkg/784dc660/core.pkg.css', 'type' => 'css', ), '8152415f' => @@ -1986,16 +1999,16 @@ celerity_register_resource_map(array( ), 'reverse' => array( - 'aphront-crumbs-view-css' => '6a6def05', - 'aphront-dialog-view-css' => '6a6def05', - 'aphront-form-view-css' => '6a6def05', + 'aphront-crumbs-view-css' => '784dc660', + 'aphront-dialog-view-css' => '784dc660', + 'aphront-form-view-css' => '784dc660', 'aphront-headsup-action-list-view-css' => '8152415f', - 'aphront-list-filter-view-css' => '6a6def05', - 'aphront-panel-view-css' => '6a6def05', - 'aphront-side-nav-view-css' => '6a6def05', - 'aphront-table-view-css' => '6a6def05', - 'aphront-tokenizer-control-css' => '6a6def05', - 'aphront-typeahead-control-css' => '6a6def05', + 'aphront-list-filter-view-css' => '784dc660', + 'aphront-panel-view-css' => '784dc660', + 'aphront-side-nav-view-css' => '784dc660', + 'aphront-table-view-css' => '784dc660', + 'aphront-tokenizer-control-css' => '784dc660', + 'aphront-typeahead-control-css' => '784dc660', 'differential-changeset-view-css' => '8152415f', 'differential-core-view-css' => '8152415f', 'differential-inline-comment-editor' => 'c8aaade8', @@ -2044,16 +2057,16 @@ celerity_register_resource_map(array( 'javelin-vector' => '4fbae2af', 'javelin-workflow' => '46547a92', 'phabricator-content-source-view-css' => '8152415f', - 'phabricator-core-buttons-css' => '6a6def05', - 'phabricator-core-css' => '6a6def05', - 'phabricator-directory-css' => '6a6def05', + 'phabricator-core-buttons-css' => '784dc660', + 'phabricator-core-css' => '784dc660', + 'phabricator-directory-css' => '784dc660', 'phabricator-drag-and-drop-file-upload' => 'c8aaade8', 'phabricator-keyboard-shortcut' => '46547a92', 'phabricator-keyboard-shortcut-manager' => '46547a92', 'phabricator-object-selector-css' => '8152415f', - 'phabricator-remarkup-css' => '6a6def05', + 'phabricator-remarkup-css' => '784dc660', 'phabricator-shaped-request' => 'c8aaade8', - 'phabricator-standard-page-view' => '6a6def05', - 'syntax-highlighting-css' => '6a6def05', + 'phabricator-standard-page-view' => '784dc660', + 'syntax-highlighting-css' => '784dc660', ), )); diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 6f3d9b5033..610a085893 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -449,6 +449,7 @@ phutil_register_library_map(array( 'PhabricatorAuditEditController' => 'applications/audit/controller/edit', 'PhabricatorAuditListController' => 'applications/audit/controller/list', 'PhabricatorAuditListView' => 'applications/audit/view/list', + 'PhabricatorAuditPreviewController' => 'applications/audit/controller/preview', 'PhabricatorAuditQuery' => 'applications/audit/query/audit', 'PhabricatorAuditReplyHandler' => 'applications/audit/replyhandler', 'PhabricatorAuditStatusConstants' => 'applications/audit/constants/status', @@ -1241,6 +1242,7 @@ phutil_register_library_map(array( 'PhabricatorAuditEditController' => 'PhabricatorAuditController', 'PhabricatorAuditListController' => 'PhabricatorAuditController', 'PhabricatorAuditListView' => 'AphrontView', + 'PhabricatorAuditPreviewController' => 'PhabricatorAuditController', 'PhabricatorAuditReplyHandler' => 'PhabricatorMailReplyHandler', 'PhabricatorAuthController' => 'PhabricatorController', 'PhabricatorCalendarBrowseController' => 'PhabricatorCalendarController', diff --git a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php index 3405aa06e0..14fa0b7aca 100644 --- a/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php +++ b/src/aphront/default/configuration/AphrontDefaultApplicationConfiguration.php @@ -350,6 +350,7 @@ class AphrontDefaultApplicationConfiguration 'view/(?P[^/]+)/$' => 'PhabricatorAuditListController', 'edit/$' => 'PhabricatorAuditEditController', 'addcomment/$' => 'PhabricatorAuditAddCommentController', + 'preview/(?P\d+)/$' => 'PhabricatorAuditPreviewController', ), '/xhpast/' => array( diff --git a/src/applications/audit/controller/addcomment/PhabricatorAuditAddCommentController.php b/src/applications/audit/controller/addcomment/PhabricatorAuditAddCommentController.php index c1e1f3ca0b..091feff98e 100644 --- a/src/applications/audit/controller/addcomment/PhabricatorAuditAddCommentController.php +++ b/src/applications/audit/controller/addcomment/PhabricatorAuditAddCommentController.php @@ -40,6 +40,7 @@ final class PhabricatorAuditAddCommentController ->setAction($request->getStr('action')) ->setContent($request->getStr('content')); + id(new PhabricatorAuditCommentEditor($commit)) ->setUser($user) ->addComment($comment); @@ -48,6 +49,14 @@ final class PhabricatorAuditAddCommentController $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); $uri = $handles[$commit_phid]->getURI(); + $draft = id(new PhabricatorDraft())->loadOneWhere( + 'authorPHID = %s AND draftKey = %s', + $user->getPHID(), + 'diffusion-audit-'.$commit->getID()); + if ($draft) { + $draft->delete(); + } + return id(new AphrontRedirectResponse())->setURI($uri); } diff --git a/src/applications/audit/controller/addcomment/__init__.php b/src/applications/audit/controller/addcomment/__init__.php index bf381ff397..1ea2d48c05 100644 --- a/src/applications/audit/controller/addcomment/__init__.php +++ b/src/applications/audit/controller/addcomment/__init__.php @@ -12,6 +12,7 @@ phutil_require_module('phabricator', 'aphront/response/redirect'); phutil_require_module('phabricator', 'applications/audit/controller/base'); phutil_require_module('phabricator', 'applications/audit/editor/comment'); phutil_require_module('phabricator', 'applications/audit/storage/auditcomment'); +phutil_require_module('phabricator', 'applications/draft/storage/draft'); phutil_require_module('phabricator', 'applications/phid/handle/data'); phutil_require_module('phabricator', 'applications/repository/storage/commit'); diff --git a/src/applications/audit/controller/preview/PhabricatorAuditPreviewController.php b/src/applications/audit/controller/preview/PhabricatorAuditPreviewController.php new file mode 100644 index 0000000000..2a82dee89c --- /dev/null +++ b/src/applications/audit/controller/preview/PhabricatorAuditPreviewController.php @@ -0,0 +1,62 @@ +id = $data['id']; + } + + public function processRequest() { + $request = $this->getRequest(); + $user = $request->getUser(); + + $commit = id(new PhabricatorRepositoryCommit())->load($this->id); + if (!$commit) { + return new Aphront404Response(); + } + + $comment = id(new PhabricatorAuditComment()) + ->setActorPHID($user->getPHID()) + ->setTargetPHID($commit->getPHID()) + ->setAction($request->getStr('action')) + ->setContent($request->getStr('content')); + + $view = id(new DiffusionCommentView()) + ->setUser($user) + ->setComment($comment) + ->setIsPreview(true); + + $phids = $view->getRequiredHandlePHIDs(); + $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); + $view->setHandles($handles); + + id(new PhabricatorDraft()) + ->setAuthorPHID($comment->getActorPHID()) + ->setDraftKey('diffusion-audit-'.$this->id) + ->setDraft($comment->getContent()) + ->replace(); + + return id(new AphrontAjaxResponse()) + ->setContent($view->render()); + } + +} diff --git a/src/applications/audit/controller/preview/__init__.php b/src/applications/audit/controller/preview/__init__.php new file mode 100644 index 0000000000..29abbc7cb5 --- /dev/null +++ b/src/applications/audit/controller/preview/__init__.php @@ -0,0 +1,21 @@ +loadOneWhere( + 'authorPHID = %s AND draftKey = %s', + $user->getPHID(), + 'diffusion-audit-'.$commit->getID()); + if ($draft) { + $draft = $draft->getDraft(); + } else { + $draft = null; + } + $form = id(new AphrontFormView()) ->setUser($user) ->setAction('/audit/addcomment/') @@ -348,11 +358,14 @@ class DiffusionCommitController extends DiffusionController { id(new AphrontFormSelectControl()) ->setLabel('Action') ->setName('action') + ->setID('audit-action') ->setOptions(PhabricatorAuditActionConstants::getActionNameMap())) ->appendChild( id(new AphrontFormTextAreaControl()) ->setLabel('Comments') ->setName('content') + ->setValue($draft) + ->setID('audit-content') ->setCaption(phutil_render_tag( 'a', array( @@ -370,7 +383,28 @@ class DiffusionCommitController extends DiffusionController { $panel->setHeader($is_serious ? 'Audit Commit' : 'Creative Accounting'); $panel->appendChild($form); - return $panel; + require_celerity_resource('phabricator-transaction-view-css'); + + Javelin::initBehavior('audit-preview', array( + 'uri' => '/audit/preview/'.$commit->getID().'/', + 'preview' => 'audit-preview', + 'content' => 'audit-content', + 'action' => 'audit-action', + )); + + $preview_panel = + '
+
+
+ Loading preview... +
+
+
'; + + $view = new AphrontNullView(); + $view->appendChild($panel); + $view->appendChild($preview_panel); + return $view; } } diff --git a/src/applications/diffusion/controller/commit/__init__.php b/src/applications/diffusion/controller/commit/__init__.php index e646cead37..570374bb62 100644 --- a/src/applications/diffusion/controller/commit/__init__.php +++ b/src/applications/diffusion/controller/commit/__init__.php @@ -19,12 +19,14 @@ phutil_require_module('phabricator', 'applications/diffusion/query/contains/base phutil_require_module('phabricator', 'applications/diffusion/query/pathchange/base'); phutil_require_module('phabricator', 'applications/diffusion/view/commentlist'); phutil_require_module('phabricator', 'applications/diffusion/view/commitchangetable'); +phutil_require_module('phabricator', 'applications/draft/storage/draft'); phutil_require_module('phabricator', 'applications/markup/engine'); phutil_require_module('phabricator', 'applications/phid/handle/data'); phutil_require_module('phabricator', 'applications/repository/constants/repositorytype'); phutil_require_module('phabricator', 'applications/repository/storage/repository'); phutil_require_module('phabricator', 'infrastructure/celerity/api'); phutil_require_module('phabricator', 'infrastructure/env'); +phutil_require_module('phabricator', 'infrastructure/javelin/api'); phutil_require_module('phabricator', 'storage/queryfx'); phutil_require_module('phabricator', 'view/form/base'); phutil_require_module('phabricator', 'view/form/control/select'); @@ -32,6 +34,7 @@ phutil_require_module('phabricator', 'view/form/control/submit'); phutil_require_module('phabricator', 'view/form/control/textarea'); phutil_require_module('phabricator', 'view/form/error'); phutil_require_module('phabricator', 'view/layout/panel'); +phutil_require_module('phabricator', 'view/null'); phutil_require_module('phabricator', 'view/utils'); phutil_require_module('phutil', 'markup'); diff --git a/src/applications/diffusion/view/comment/DiffusionCommentView.php b/src/applications/diffusion/view/comment/DiffusionCommentView.php index e9b19b30fa..8d4cbadec6 100644 --- a/src/applications/diffusion/view/comment/DiffusionCommentView.php +++ b/src/applications/diffusion/view/comment/DiffusionCommentView.php @@ -22,6 +22,9 @@ final class DiffusionCommentView extends AphrontView { private $comment; private $commentNumber; private $handles; + private $isPreview; + + private $engine; public function setUser(PhabricatorUser $user) { $this->user = $user; @@ -43,6 +46,15 @@ final class DiffusionCommentView extends AphrontView { return $this; } + public function setIsPreview($is_preview) { + $this->isPreview = $is_preview; + return $this; + } + + public function getRequiredHandlePHIDs() { + return array($this->comment->getActorPHID()); + } + private function getHandle($phid) { if (empty($this->handles[$phid])) { throw new Exception("Unloaded handle '{$phid}'!"); @@ -63,15 +75,21 @@ final class DiffusionCommentView extends AphrontView { ->setUser($this->user) ->setImageURI($author->getImageURI()) ->setActions($actions) - ->setAnchor('comment-'.$this->commentNumber, '#'.$this->commentNumber) - ->setEpoch($comment->getDateCreated()) ->appendChild($content); + if ($this->isPreview) { + $xaction_view->setIsPreview(true); + } else { + $xaction_view + ->setAnchor('comment-'.$this->commentNumber, '#'.$this->commentNumber) + ->setEpoch($comment->getDateCreated()); + } + foreach ($classes as $class) { $xaction_view->addClass($class); } - return $xaction_view; + return $xaction_view->render(); } private function renderActions() { @@ -102,14 +120,21 @@ final class DiffusionCommentView extends AphrontView { private function renderContent() { $comment = $this->comment; + $engine = $this->getEngine(); - $engine = PhabricatorMarkupEngine::newDiffusionMarkupEngine(); return '
'. $engine->markupText($comment->getContent()). '
'; } + private function getEngine() { + if (!$this->engine) { + $this->engine = PhabricatorMarkupEngine::newDiffusionMarkupEngine(); + } + return $this->engine; + } + private function renderClasses() { $comment = $this->comment; diff --git a/webroot/rsrc/js/application/diffusion/behavior-audit-preview.js b/webroot/rsrc/js/application/diffusion/behavior-audit-preview.js new file mode 100644 index 0000000000..fa2b6dddfe --- /dev/null +++ b/webroot/rsrc/js/application/diffusion/behavior-audit-preview.js @@ -0,0 +1,33 @@ +/** + * @provides javelin-behavior-audit-preview + * @requires javelin-behavior + * javelin-dom + * javelin-util + * phabricator-shaped-request + */ + +JX.behavior('audit-preview', function(config) { + + var preview = JX.$(config.preview); + var content = JX.$(config.content); + var action = JX.$(config.action); + + var callback = function(r) { + JX.DOM.setContent(JX.$(config.preview), JX.$H(r)); + }; + + var getdata = function() { + return { + action: action.value, + content: content.value + }; + } + + var request = new JX.PhabricatorShapedRequest(config.uri, callback, getdata); + var trigger = JX.bind(request, request.trigger); + + JX.DOM.listen(content, 'keydown', null, trigger); + JX.DOM.listen(action, 'change', null, trigger); + + request.start(); +});