From f5e842ebd9af21a4baa8a3708fab6fb1affa9f9e Mon Sep 17 00:00:00 2001 From: Bob Trahan Date: Fri, 25 May 2012 10:14:17 -0700 Subject: [PATCH] dark console - introduce "request log" section Summary: this section gets updated for each and every request. clicking a given entry updates the larger dark-console area to have the information from that request Test Plan: clicked around in maniphest and observed request log populating correctly. clicked a few entries in request log and saw it updated properly. clicked a different tab in the dark-console and it worked. clicked a different request log entry and it opened the dark console to the proper request on the proper tab. Reviewers: epriestley, vrana Reviewed By: epriestley CC: aran, Koolvin Maniphest Tasks: T1136 Differential Revision: https://secure.phabricator.com/D2574 --- src/__celerity_resource_map__.php | 75 +++++++++------ .../controller/DarkConsoleController.php | 4 +- src/aphront/console/core/DarkConsoleCore.php | 56 ++++++++++- src/aphront/console/core/__init__.php | 1 + .../errorlog/DarkConsoleErrorLogPlugin.php | 1 - .../response/ajax/AphrontAjaxResponse.php | 26 ++++++ src/aphront/response/ajax/__init__.php | 1 + .../standard/PhabricatorStandardPageView.php | 3 +- webroot/rsrc/css/aphront/dark-console.css | 25 +++-- .../core/behavior-dark-console-ajax.js | 49 ++++++++++ .../application/core/behavior-dark-console.js | 93 ++++++++++++++++++- 11 files changed, 292 insertions(+), 42 deletions(-) create mode 100644 webroot/rsrc/js/application/core/behavior-dark-console-ajax.js diff --git a/src/__celerity_resource_map__.php b/src/__celerity_resource_map__.php index 52a0fa1954..d5dc89e7a5 100644 --- a/src/__celerity_resource_map__.php +++ b/src/__celerity_resource_map__.php @@ -70,6 +70,13 @@ celerity_register_resource_map(array( 'disk' => '/rsrc/image/icon/fatcow/arrow_merge.png', 'type' => 'png', ), + '/rsrc/image/icon/fatcow/bullet_black.png' => + array( + 'hash' => '718f9c560a13766796f1be7dfaadeeab', + 'uri' => '/res/718f9c56/rsrc/image/icon/fatcow/bullet_black.png', + 'disk' => '/rsrc/image/icon/fatcow/bullet_black.png', + 'type' => 'png', + ), '/rsrc/image/icon/fatcow/bullet_orange.png' => array( 'hash' => 'c3bf91b65baacb27f2af143ab9180119', @@ -416,7 +423,7 @@ celerity_register_resource_map(array( ), 'aphront-dark-console-css' => array( - 'uri' => '/res/4965d970/rsrc/css/aphront/dark-console.css', + 'uri' => '/res/d9715ffb/rsrc/css/aphront/dark-console.css', 'type' => 'css', 'requires' => array( @@ -875,7 +882,7 @@ celerity_register_resource_map(array( ), 'javelin-behavior-dark-console' => array( - 'uri' => '/res/c80156c4/rsrc/js/application/core/behavior-dark-console.js', + 'uri' => '/res/d2518cbf/rsrc/js/application/core/behavior-dark-console.js', 'type' => 'js', 'requires' => array( @@ -885,9 +892,21 @@ celerity_register_resource_map(array( 3 => 'javelin-dom', 4 => 'javelin-request', 5 => 'phabricator-keyboard-shortcut', + 6 => 'javelin-behavior-dark-console-ajax', ), 'disk' => '/rsrc/js/application/core/behavior-dark-console.js', ), + 'javelin-behavior-dark-console-ajax' => + array( + 'uri' => '/res/ac3ab63a/rsrc/js/application/core/behavior-dark-console-ajax.js', + 'type' => 'js', + 'requires' => + array( + 0 => 'javelin-behavior', + 1 => 'javelin-dom', + ), + 'disk' => '/rsrc/js/application/core/behavior-dark-console-ajax.js', + ), 'javelin-behavior-differential-accept-with-errors' => array( 'uri' => '/res/ba5144c5/rsrc/js/application/differential/behavior-accept-with-errors.js', @@ -2223,7 +2242,7 @@ celerity_register_resource_map(array( ), 'phabricator-standard-page-view' => array( - 'uri' => '/res/82608dbf/rsrc/css/application/base/standard-page-view.css', + 'uri' => '/res/07d5f4cb/rsrc/css/application/base/standard-page-view.css', 'type' => 'css', 'requires' => array( @@ -2478,7 +2497,7 @@ celerity_register_resource_map(array( ), array( 'packages' => array( - 'bc35e3ce' => + '4984f83f' => array( 'name' => 'core.pkg.css', 'symbols' => @@ -2507,7 +2526,7 @@ celerity_register_resource_map(array( 21 => 'phabricator-flag-css', 22 => 'aphront-error-view-css', ), - 'uri' => '/res/pkg/bc35e3ce/core.pkg.css', + 'uri' => '/res/pkg/4984f83f/core.pkg.css', 'type' => 'css', ), '0c96375e' => @@ -2674,20 +2693,20 @@ celerity_register_resource_map(array( 'reverse' => array( 'aphront-attached-file-view-css' => '7839ae2d', - 'aphront-crumbs-view-css' => 'bc35e3ce', - 'aphront-dialog-view-css' => 'bc35e3ce', - 'aphront-error-view-css' => 'bc35e3ce', - 'aphront-form-view-css' => 'bc35e3ce', + 'aphront-crumbs-view-css' => '4984f83f', + 'aphront-dialog-view-css' => '4984f83f', + 'aphront-error-view-css' => '4984f83f', + 'aphront-form-view-css' => '4984f83f', 'aphront-headsup-action-list-view-css' => '5ed00902', - 'aphront-headsup-view-css' => 'bc35e3ce', - 'aphront-list-filter-view-css' => 'bc35e3ce', - 'aphront-pager-view-css' => 'bc35e3ce', - 'aphront-panel-view-css' => 'bc35e3ce', - 'aphront-side-nav-view-css' => 'bc35e3ce', - 'aphront-table-view-css' => 'bc35e3ce', - 'aphront-tokenizer-control-css' => 'bc35e3ce', - 'aphront-tooltip-css' => 'bc35e3ce', - 'aphront-typeahead-control-css' => 'bc35e3ce', + 'aphront-headsup-view-css' => '4984f83f', + 'aphront-list-filter-view-css' => '4984f83f', + 'aphront-pager-view-css' => '4984f83f', + 'aphront-panel-view-css' => '4984f83f', + 'aphront-side-nav-view-css' => '4984f83f', + 'aphront-table-view-css' => '4984f83f', + 'aphront-tokenizer-control-css' => '4984f83f', + 'aphront-tooltip-css' => '4984f83f', + 'aphront-typeahead-control-css' => '4984f83f', 'differential-changeset-view-css' => '5ed00902', 'differential-core-view-css' => '5ed00902', 'differential-inline-comment-editor' => '5ef7da0b', @@ -2753,15 +2772,15 @@ celerity_register_resource_map(array( 'javelin-workflow' => '0c96375e', 'maniphest-task-summary-css' => '7839ae2d', 'maniphest-transaction-detail-css' => '7839ae2d', - 'phabricator-app-buttons-css' => 'bc35e3ce', + 'phabricator-app-buttons-css' => '4984f83f', 'phabricator-content-source-view-css' => '5ed00902', - 'phabricator-core-buttons-css' => 'bc35e3ce', - 'phabricator-core-css' => 'bc35e3ce', - 'phabricator-directory-css' => 'bc35e3ce', + 'phabricator-core-buttons-css' => '4984f83f', + 'phabricator-core-css' => '4984f83f', + 'phabricator-directory-css' => '4984f83f', 'phabricator-drag-and-drop-file-upload' => '5ef7da0b', 'phabricator-dropdown-menu' => '0c96375e', - 'phabricator-flag-css' => 'bc35e3ce', - 'phabricator-jump-nav' => 'bc35e3ce', + 'phabricator-flag-css' => '4984f83f', + 'phabricator-jump-nav' => '4984f83f', 'phabricator-keyboard-shortcut' => '0c96375e', 'phabricator-keyboard-shortcut-manager' => '0c96375e', 'phabricator-menu-item' => '0c96375e', @@ -2769,11 +2788,11 @@ celerity_register_resource_map(array( 'phabricator-paste-file-upload' => '0c96375e', 'phabricator-prefab' => '0c96375e', 'phabricator-project-tag-css' => '7839ae2d', - 'phabricator-remarkup-css' => 'bc35e3ce', + 'phabricator-remarkup-css' => '4984f83f', 'phabricator-shaped-request' => '5ef7da0b', - 'phabricator-standard-page-view' => 'bc35e3ce', + 'phabricator-standard-page-view' => '4984f83f', 'phabricator-tooltip' => '0c96375e', - 'phabricator-transaction-view-css' => 'bc35e3ce', - 'syntax-highlighting-css' => 'bc35e3ce', + 'phabricator-transaction-view-css' => '4984f83f', + 'syntax-highlighting-css' => '4984f83f', ), )); diff --git a/src/aphront/console/controller/DarkConsoleController.php b/src/aphront/console/controller/DarkConsoleController.php index 9b0aebe7df..49e36c65b4 100644 --- a/src/aphront/console/controller/DarkConsoleController.php +++ b/src/aphront/console/controller/DarkConsoleController.php @@ -32,14 +32,14 @@ final class DarkConsoleController extends PhabricatorController { if (strlen($visible)) { $user->setConsoleVisible((int)$visible); $user->save(); - return new AphrontAjaxResponse(); + return id(new AphrontAjaxResponse())->setDisableConsole(true); } $tab = $request->getStr('tab'); if (strlen($tab)) { $user->setConsoleTab($tab); $user->save(); - return new AphrontAjaxResponse(); + return id(new AphrontAjaxResponse())->setDisableConsole(true); } if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) { diff --git a/src/aphront/console/core/DarkConsoleCore.php b/src/aphront/console/core/DarkConsoleCore.php index 1786447786..2de892e03c 100644 --- a/src/aphront/console/core/DarkConsoleCore.php +++ b/src/aphront/console/core/DarkConsoleCore.php @@ -155,7 +155,61 @@ final class DarkConsoleCore { $console); } - return "\n\n\n\n".$console."\n\n\n\n"; + if ($request->isAjax()) { + + // for ajax this HTML gets updated on the client + $request_history = null; + + } else { + + $request_table_header = + '
'; + + $rows = array(); + + $table = new AphrontTableView($rows); + $table->setHeaders( + array( + 'Sequence', + 'Type', + 'URI', + )); + $table->setColumnClasses( + array( + '', + '', + 'wide', + )); + + $request_table = $request_table_header . $table->render(); + $request_history = javelin_render_tag( + 'table', + array( + 'class' => 'dark-console dark-console-request-log', + 'sigil' => 'dark-console-request-log', + 'style' => $visible ? '' : 'display: none;', + ), + ''. + ''. + javelin_render_tag( + 'a', + array( + 'class' => 'dark-console-tab dark-console-tab-selected', + ), + 'Request Log'). + ''. + ''. + javelin_render_tag( + 'div', + array( + 'class' => 'dark-console-panel', + ), + $request_table). + ''. + ''); + } + + return "\n\n\n\n".$console.$request_history."\n\n\n\n"; } } diff --git a/src/aphront/console/core/__init__.php b/src/aphront/console/core/__init__.php index 077f4a6f60..494fd7e247 100644 --- a/src/aphront/console/core/__init__.php +++ b/src/aphront/console/core/__init__.php @@ -7,6 +7,7 @@ phutil_require_module('phabricator', 'infrastructure/javelin/markup'); +phutil_require_module('phabricator', 'view/control/table'); phutil_require_module('phutil', 'markup'); phutil_require_module('phutil', 'utils'); diff --git a/src/aphront/console/plugin/errorlog/DarkConsoleErrorLogPlugin.php b/src/aphront/console/plugin/errorlog/DarkConsoleErrorLogPlugin.php index 05d2b21933..8e4b70a770 100644 --- a/src/aphront/console/plugin/errorlog/DarkConsoleErrorLogPlugin.php +++ b/src/aphront/console/plugin/errorlog/DarkConsoleErrorLogPlugin.php @@ -105,7 +105,6 @@ final class DarkConsoleErrorLogPlugin extends DarkConsolePlugin { return '
'. '
'.$table->render().'
'. - '
'. '
'.
       $details.'
'. '
'; diff --git a/src/aphront/response/ajax/AphrontAjaxResponse.php b/src/aphront/response/ajax/AphrontAjaxResponse.php index 1e7bb01f6f..1736c96898 100644 --- a/src/aphront/response/ajax/AphrontAjaxResponse.php +++ b/src/aphront/response/ajax/AphrontAjaxResponse.php @@ -23,6 +23,7 @@ final class AphrontAjaxResponse extends AphrontResponse { private $content; private $error; + private $disableConsole; public function setContent($content) { $this->content = $content; @@ -34,7 +35,32 @@ final class AphrontAjaxResponse extends AphrontResponse { return $this; } + public function setDisableConsole($disable) { + $this->disableConsole = $disable; + return $this; + } + + private function getConsole() { + if ($this->disableConsole) { + $console = null; + } else { + $request = $this->getRequest(); + $console = $request->getApplicationConfiguration()->getConsole(); + } + return $console; + } + public function buildResponseString() { + $console = $this->getConsole(); + if ($console) { + Javelin::initBehavior( + 'dark-console-ajax', + array( + 'console' => $console->render($this->getRequest()), + 'uri' => (string) $this->getRequest()->getRequestURI(), + )); + } + $response = CelerityAPI::getStaticResourceResponse(); $object = $response->buildAjaxResponse( $this->content, diff --git a/src/aphront/response/ajax/__init__.php b/src/aphront/response/ajax/__init__.php index fd1560d506..73753cb2a9 100644 --- a/src/aphront/response/ajax/__init__.php +++ b/src/aphront/response/ajax/__init__.php @@ -8,6 +8,7 @@ phutil_require_module('phabricator', 'aphront/response/base'); phutil_require_module('phabricator', 'infrastructure/celerity/api'); +phutil_require_module('phabricator', 'infrastructure/javelin/api'); phutil_require_source('AphrontAjaxResponse.php'); diff --git a/src/view/page/standard/PhabricatorStandardPageView.php b/src/view/page/standard/PhabricatorStandardPageView.php index 7ebecc28f2..ea98182c4e 100644 --- a/src/view/page/standard/PhabricatorStandardPageView.php +++ b/src/view/page/standard/PhabricatorStandardPageView.php @@ -179,7 +179,8 @@ final class PhabricatorStandardPageView extends AphrontPageView { Javelin::initBehavior( 'dark-console', array( - 'uri' => '/~/', + 'uri' => '/~/', + 'request_uri' => $request ? (string) $request->getRequestURI() : '/', )); // Change this to initBehavior when there is some behavior to initialize diff --git a/webroot/rsrc/css/aphront/dark-console.css b/webroot/rsrc/css/aphront/dark-console.css index dbb4d580f4..b069b70ba7 100644 --- a/webroot/rsrc/css/aphront/dark-console.css +++ b/webroot/rsrc/css/aphront/dark-console.css @@ -8,7 +8,6 @@ width: 100%; font-family: "Verdana"; font-size: 11px; - border-bottom: 2px solid #000000; position: relative; z-index: 1; } @@ -71,6 +70,10 @@ a.dark-console-tab-selected { background: #666666; } +.dark-console .aphront-table-view tr.highlight { + background: #001A66; +} + .dark-console .aphront-table-view tr.no-data td { color: #dddddd; } @@ -84,13 +87,6 @@ a.dark-console-tab-selected { display: none; } -.dark-console-panel-error-separator { - background-color: #e8e8e8; - border-bottom: 1px solid #b7b7b7; - border-top: 1px solid #b7b7b7; - height: 2px; -} - .explain-sev-1 { color: #33ff33; } @@ -156,3 +152,16 @@ a.dark-console-tab-selected { padding: 1.5em 2em; font-style: italic; } + +.dark-console-request-log { + border-bottom: 2px solid #000000; +} + +.dark-console-panel-request-log-separator { + background-color: #e8e8e8; + border-bottom: 1px solid #b7b7b7; + border-top: 1px solid #b7b7b7; + height: 2px; +} + + diff --git a/webroot/rsrc/js/application/core/behavior-dark-console-ajax.js b/webroot/rsrc/js/application/core/behavior-dark-console-ajax.js new file mode 100644 index 0000000000..ecaa6053cc --- /dev/null +++ b/webroot/rsrc/js/application/core/behavior-dark-console-ajax.js @@ -0,0 +1,49 @@ +/** + * @provides javelin-behavior-dark-console-ajax + * @requires javelin-behavior + * javelin-dom + */ + +JX.behavior('dark-console-ajax', function(config) { + var requestLog = JX.DOM.find(document.body, + 'table', + 'dark-console-request-log'); + var requestTable = JX.DOM.find(requestLog, 'table'); + var requestRows = JX.DOM.scry(requestTable, 'tr'); + var requestNumber = requestRows.length - 1; // header don't count + var requestURI = config.uri; + var console = JX.$H(config.console); + var newRowType = 'ajax'; + + var newRowNumber = JX.$N( + 'a', + { + 'sigil' : 'request-log-number', + 'meta' : { 'console' : console } + }, + requestNumber + ); + var newRowURI = JX.$N( + 'a', + { + 'sigil' : 'request-log-uri', + 'meta' : { 'console' : console } + }, + requestURI + ); + + var newRow = JX.$N( + 'tr', + { + 'className' : requestNumber % 2 ? 'alt' : '' + }, + [ + JX.$N('td', {}, newRowNumber), + JX.$N('td', {}, newRowType), + JX.$N('td', {}, newRowURI) + ] + ); + + JX.DOM.appendContent(requestTable, newRow); + +}); diff --git a/webroot/rsrc/js/application/core/behavior-dark-console.js b/webroot/rsrc/js/application/core/behavior-dark-console.js index 2e32f7ac40..2a4d66940e 100644 --- a/webroot/rsrc/js/application/core/behavior-dark-console.js +++ b/webroot/rsrc/js/application/core/behavior-dark-console.js @@ -6,9 +6,12 @@ * javelin-dom * javelin-request * phabricator-keyboard-shortcut + * javelin-behavior-dark-console-ajax */ JX.behavior('dark-console', function(config) { + var selected_tab = null; + JX.Stratcom.listen( 'click', ['dark-console', 'dark-console-tab'], @@ -25,8 +28,10 @@ JX.behavior('dark-console', function(config) { (tabs[ii] != target ? JX.DOM.hide : JX.DOM.show)(panels[ii]); } + selected_tab = target.id.replace('dark-console-tab-', ''); + new JX.Request(config.uri, JX.bag) - .setData({tab: target.id.replace('dark-console-tab-', '')}) + .setData({ tab : selected_tab }) .send(); }); @@ -47,4 +52,90 @@ JX.behavior('dark-console', function(config) { .send(); }) .register(); + + var initRequestLog = function() { + var console = JX.DOM.find(document.body, + 'table', + 'dark-console'); + var requestLog = JX.DOM.find(document.body, + 'table', + 'dark-console-request-log'); + var requestTable = JX.DOM.find(requestLog, 'table'); + var rows = JX.DOM.scry(requestTable, 'tr'); + var tableHeader = rows[0]; + var newRowNumber = JX.$N( + 'a', + { + 'sigil' : 'request-log-number', + 'meta' : { 'console' : console } + }, + "0" + ); + var newRowURI = JX.$N( + 'a', + { + 'sigil' : 'request-log-uri', + 'meta' : { 'console' : console } + }, + config.request_uri + ); + + var newRow = JX.$N( + 'tr', + { + 'className' : 'highlight' + }, + [ + JX.$N('td', {}, newRowNumber), + JX.$N('td', {}, 'main'), + JX.$N('td', {}, newRowURI) + ] + ); + + JX.DOM.setContent(requestTable, [tableHeader, newRow]); + } + + initRequestLog(); + + var updateActiveRequest = function(e) { + var log = e.getNode('dark-console-request-log'); + var table = JX.DOM.find(log, 'table'); + var rows = JX.DOM.scry(table, 'tr'); + var targetRow = e.getTarget().parentNode.parentNode; + var data = JX.Stratcom.getData(e.getTarget()); + var newConsole = data.console; + for (var ii = 0; ii < rows.length; ii++) { + JX.DOM.alterClass( + rows[ii], + 'highlight', + rows[ii] == targetRow); + } + var console = JX.DOM.find(document.body, 'table', 'dark-console'); + JX.DOM.replace(console, newConsole); + if (selected_tab) { + console = JX.DOM.find(document.body, 'table', 'dark-console'); + var s_id = 'dark-console-tab-' + selected_tab; + var tabs = JX.DOM.scry(console, 'a', 'dark-console-tab'); + var panels = JX.DOM.scry(console, 'div', 'dark-console-panel'); + for (var ii = 0; ii < tabs.length; ii++) { + JX.DOM.alterClass( + tabs[ii], + 'dark-console-tab-selected', + tabs[ii].id == s_id); + (tabs[ii].id != s_id ? JX.DOM.hide : JX.DOM.show)(panels[ii]); + } + } + } + + JX.Stratcom.listen( + 'click', + ['dark-console-request-log', 'request-log-number'], + updateActiveRequest + ); + JX.Stratcom.listen( + 'click', + ['dark-console-request-log', 'request-log-uri'], + updateActiveRequest + ); + });