diff --git a/resources/celerity/map.php b/resources/celerity/map.php --- a/resources/celerity/map.php +++ b/resources/celerity/map.php @@ -7,7 +7,7 @@ */ return array( 'names' => array( - 'core.pkg.css' => 'efdeeb14', + 'core.pkg.css' => '70320e8a', 'core.pkg.js' => '5f50c01b', 'darkconsole.pkg.js' => '8ab24e01', 'differential.pkg.css' => '1940be3f', @@ -34,7 +34,7 @@ 'rsrc/css/aphront/typeahead.css' => '0e403212', 'rsrc/css/application/almanac/almanac.css' => 'dbb9b3af', 'rsrc/css/application/auth/auth.css' => '1e655982', - 'rsrc/css/application/base/main-menu-view.css' => '58db7ad2', + 'rsrc/css/application/base/main-menu-view.css' => 'f9f5cd1b', 'rsrc/css/application/base/notification-menu.css' => '6aa0a74b', 'rsrc/css/application/base/phabricator-application-launch-view.css' => '16ca323f', 'rsrc/css/application/base/standard-page-view.css' => 'df338a4b', @@ -44,7 +44,7 @@ 'rsrc/css/application/config/config-welcome.css' => '6abd79be', 'rsrc/css/application/config/setup-issue.css' => '22270af2', 'rsrc/css/application/config/unhandled-exception.css' => '37d4f9a2', - 'rsrc/css/application/conpherence/durable-column.css' => 'acefcb30', + 'rsrc/css/application/conpherence/durable-column.css' => '7abcc3f2', 'rsrc/css/application/conpherence/menu.css' => 'c6ac5299', 'rsrc/css/application/conpherence/message-pane.css' => '5930260a', 'rsrc/css/application/conpherence/notification.css' => '04a6e10a', @@ -105,12 +105,12 @@ 'rsrc/css/application/tokens/tokens.css' => '3d0f239e', 'rsrc/css/application/uiexample/example.css' => '528b19de', 'rsrc/css/core/core.css' => '86bfbe8c', - 'rsrc/css/core/remarkup.css' => 'bc65f3cc', + 'rsrc/css/core/remarkup.css' => '2dbff225', 'rsrc/css/core/syntax.css' => '56c1ba38', 'rsrc/css/core/z-index.css' => '2db67397', 'rsrc/css/diviner/diviner-shared.css' => '38813222', 'rsrc/css/font/font-awesome.css' => 'ae9a7b4d', - 'rsrc/css/font/font-source-sans-pro.css' => '4a2430d7', + 'rsrc/css/font/font-source-sans-pro.css' => '0d859f60', 'rsrc/css/font/phui-font-icon-base.css' => '3dad2ae3', 'rsrc/css/layout/phabricator-filetree-view.css' => 'fccf9f82', 'rsrc/css/layout/phabricator-hovercard-view.css' => '893f4783', @@ -128,7 +128,7 @@ 'rsrc/css/phui/phui-crumbs-view.css' => '594d719e', 'rsrc/css/phui/phui-document.css' => '0f83a7df', 'rsrc/css/phui/phui-feed-story.css' => 'c9f3a0b5', - 'rsrc/css/phui/phui-fontkit.css' => '1fa79503', + 'rsrc/css/phui/phui-fontkit.css' => 'd30f4fa3', 'rsrc/css/phui/phui-form-view.css' => '78d729fe', 'rsrc/css/phui/phui-form.css' => 'f535f938', 'rsrc/css/phui/phui-header-view.css' => '083669db', @@ -352,9 +352,9 @@ 'rsrc/js/application/aphlict/behavior-aphlict-status.js' => 'ea681761', 'rsrc/js/application/auth/behavior-persona-login.js' => '9414ff18', 'rsrc/js/application/config/behavior-reorder-fields.js' => '14a827de', - 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => '0324970d', - 'rsrc/js/application/conpherence/behavior-durable-column.js' => '9142e483', - 'rsrc/js/application/conpherence/behavior-menu.js' => 'c4151295', + 'rsrc/js/application/conpherence/ConpherenceThreadManager.js' => 'efef202b', + 'rsrc/js/application/conpherence/behavior-durable-column.js' => 'aa3b6c22', + 'rsrc/js/application/conpherence/behavior-menu.js' => 'e476c952', 'rsrc/js/application/conpherence/behavior-pontificate.js' => '21ba5861', 'rsrc/js/application/conpherence/behavior-quicksand-blacklist.js' => '7927a7d3', 'rsrc/js/application/conpherence/behavior-widget-pane.js' => '2c1cd7f5', @@ -514,11 +514,11 @@ 'changeset-view-manager' => '88be0133', 'config-options-css' => '7fedf08b', 'config-welcome-css' => '6abd79be', - 'conpherence-durable-column-view' => 'acefcb30', + 'conpherence-durable-column-view' => '7abcc3f2', 'conpherence-menu-css' => 'c6ac5299', 'conpherence-message-pane-css' => '5930260a', 'conpherence-notification-css' => '04a6e10a', - 'conpherence-thread-manager' => '0324970d', + 'conpherence-thread-manager' => 'efef202b', 'conpherence-update-css' => '1099a660', 'conpherence-widget-pane-css' => '3d575438', 'differential-changeset-view-css' => '6a8b172a', @@ -534,7 +534,7 @@ 'diffusion-source-css' => '66fdf661', 'diviner-shared-css' => '38813222', 'font-fontawesome' => 'ae9a7b4d', - 'font-source-sans-pro' => '4a2430d7', + 'font-source-sans-pro' => '0d859f60', 'global-drag-and-drop-css' => '697324ad', 'harbormaster-css' => '49d64eb4', 'herald-css' => '826075fa', @@ -558,7 +558,7 @@ 'javelin-behavior-boards-dropdown' => '0ec56e1d', 'javelin-behavior-choose-control' => '6153c708', 'javelin-behavior-config-reorder-fields' => '14a827de', - 'javelin-behavior-conpherence-menu' => 'c4151295', + 'javelin-behavior-conpherence-menu' => 'e476c952', 'javelin-behavior-conpherence-pontificate' => '21ba5861', 'javelin-behavior-conpherence-widget-pane' => '2c1cd7f5', 'javelin-behavior-countdown-timer' => 'e4cc26b3', @@ -585,7 +585,7 @@ 'javelin-behavior-diffusion-locate-file' => '6d3e1947', 'javelin-behavior-diffusion-pull-lastmodified' => '2b228192', 'javelin-behavior-doorkeeper-tag' => 'e5822781', - 'javelin-behavior-durable-column' => '9142e483', + 'javelin-behavior-durable-column' => 'aa3b6c22', 'javelin-behavior-error-log' => '6882e80a', 'javelin-behavior-fancy-datepicker' => 'c51ae228', 'javelin-behavior-global-drag-and-drop' => '07f199d8', @@ -730,7 +730,7 @@ 'phabricator-hovercard-view-css' => '893f4783', 'phabricator-keyboard-shortcut' => '1ae869f2', 'phabricator-keyboard-shortcut-manager' => 'c1700f6f', - 'phabricator-main-menu-view' => '58db7ad2', + 'phabricator-main-menu-view' => 'f9f5cd1b', 'phabricator-nav-view-css' => '7aeaf435', 'phabricator-notification' => '0c6946e7', 'phabricator-notification-css' => '9c279160', @@ -739,7 +739,7 @@ 'phabricator-phtize' => 'd254d646', 'phabricator-prefab' => '72da38cc', 'phabricator-profile-css' => '1a20dcbf', - 'phabricator-remarkup-css' => 'bc65f3cc', + 'phabricator-remarkup-css' => '2dbff225', 'phabricator-search-results-css' => '559cc554', 'phabricator-shaped-request' => '7cbe244b', 'phabricator-side-menu-view-css' => '7e8c6341', @@ -783,7 +783,7 @@ 'phui-document-view-css' => '0f83a7df', 'phui-feed-story-css' => 'c9f3a0b5', 'phui-font-icon-base-css' => '3dad2ae3', - 'phui-fontkit-css' => '1fa79503', + 'phui-fontkit-css' => 'd30f4fa3', 'phui-form-css' => 'f535f938', 'phui-form-view-css' => '78d729fe', 'phui-header-view-css' => '083669db', @@ -845,16 +845,6 @@ '029a133d' => array( 'aphront-dialog-view-css', ), - '0324970d' => array( - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-install', - 'javelin-workflow', - 'javelin-router', - 'javelin-behavior-device', - 'javelin-vector', - ), '03d6ed07' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1151,9 +1141,6 @@ 'javelin-request', 'javelin-util', ), - '4a2430d7' => array( - 'phui-fontkit-css', - ), '4d94d9c3' => array( 'javelin-behavior', 'javelin-stratcom', @@ -1546,16 +1533,6 @@ 'javelin-uri', 'phabricator-notification', ), - '9142e483' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-stratcom', - 'javelin-behavior-device', - 'javelin-scrollbar', - 'javelin-quicksand', - 'phabricator-keyboard-shortcut', - 'conpherence-thread-manager', - ), '92eb531d' => array( 'javelin-behavior', 'javelin-dom', @@ -1674,6 +1651,15 @@ 'javelin-util', 'phabricator-prefab', ), + 'aa3b6c22' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-stratcom', + 'javelin-scrollbar', + 'javelin-quicksand', + 'phabricator-keyboard-shortcut', + 'conpherence-thread-manager', + ), 'b1f0ccee' => array( 'javelin-install', 'javelin-dom', @@ -1758,18 +1744,6 @@ 'javelin-dom', 'javelin-vector', ), - 'c4151295' => array( - 'javelin-behavior', - 'javelin-dom', - 'javelin-util', - 'javelin-stratcom', - 'javelin-workflow', - 'javelin-behavior-device', - 'javelin-history', - 'javelin-vector', - 'phabricator-shaped-request', - 'conpherence-thread-manager', - ), 'c51ae228' => array( 'javelin-behavior', 'javelin-util', @@ -1873,6 +1847,18 @@ 'javelin-dom', 'javelin-uri', ), + 'e476c952' => array( + 'javelin-behavior', + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-workflow', + 'javelin-behavior-device', + 'javelin-history', + 'javelin-vector', + 'phabricator-shaped-request', + 'conpherence-thread-manager', + ), 'e4cc26b3' => array( 'javelin-behavior', 'javelin-dom', @@ -1920,6 +1906,16 @@ 'javelin-install', 'javelin-util', ), + 'efef202b' => array( + 'javelin-dom', + 'javelin-util', + 'javelin-stratcom', + 'javelin-install', + 'javelin-workflow', + 'javelin-router', + 'javelin-behavior-device', + 'javelin-vector', + ), 'f24f3253' => array( 'javelin-behavior', 'javelin-dom', diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1269,11 +1269,12 @@ 'PhabricatorApplication' => 'applications/base/PhabricatorApplication.php', 'PhabricatorApplicationApplicationPHIDType' => 'applications/meta/phid/PhabricatorApplicationApplicationPHIDType.php', 'PhabricatorApplicationConfigOptions' => 'applications/config/option/PhabricatorApplicationConfigOptions.php', + 'PhabricatorApplicationConfigurationPanel' => 'applications/meta/panel/PhabricatorApplicationConfigurationPanel.php', 'PhabricatorApplicationDatasource' => 'applications/meta/typeahead/PhabricatorApplicationDatasource.php', 'PhabricatorApplicationDetailViewController' => 'applications/meta/controller/PhabricatorApplicationDetailViewController.php', 'PhabricatorApplicationEditController' => 'applications/meta/controller/PhabricatorApplicationEditController.php', - 'PhabricatorApplicationEditEmailController' => 'applications/meta/controller/PhabricatorApplicationEditEmailController.php', 'PhabricatorApplicationLaunchView' => 'applications/meta/view/PhabricatorApplicationLaunchView.php', + 'PhabricatorApplicationPanelController' => 'applications/meta/controller/PhabricatorApplicationPanelController.php', 'PhabricatorApplicationQuery' => 'applications/meta/query/PhabricatorApplicationQuery.php', 'PhabricatorApplicationSearchController' => 'applications/search/controller/PhabricatorApplicationSearchController.php', 'PhabricatorApplicationSearchEngine' => 'applications/search/engine/PhabricatorApplicationSearchEngine.php', @@ -1988,6 +1989,7 @@ 'PhabricatorMetaMTAApplicationEmail' => 'applications/metamta/storage/PhabricatorMetaMTAApplicationEmail.php', 'PhabricatorMetaMTAApplicationEmailDatasource' => 'applications/metamta/typeahead/PhabricatorMetaMTAApplicationEmailDatasource.php', 'PhabricatorMetaMTAApplicationEmailPHIDType' => 'applications/phid/PhabricatorMetaMTAApplicationEmailPHIDType.php', + 'PhabricatorMetaMTAApplicationEmailPanel' => 'applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php', 'PhabricatorMetaMTAApplicationEmailQuery' => 'applications/metamta/query/PhabricatorMetaMTAApplicationEmailQuery.php', 'PhabricatorMetaMTAAttachment' => 'applications/metamta/storage/PhabricatorMetaMTAAttachment.php', 'PhabricatorMetaMTAConfigOptions' => 'applications/config/option/PhabricatorMetaMTAConfigOptions.php', @@ -4510,11 +4512,12 @@ 'PhabricatorApplication' => 'PhabricatorPolicyInterface', 'PhabricatorApplicationApplicationPHIDType' => 'PhabricatorPHIDType', 'PhabricatorApplicationConfigOptions' => 'Phobject', + 'PhabricatorApplicationConfigurationPanel' => 'Phobject', 'PhabricatorApplicationDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorApplicationDetailViewController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationEditController' => 'PhabricatorApplicationsController', - 'PhabricatorApplicationEditEmailController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationLaunchView' => 'AphrontTagView', + 'PhabricatorApplicationPanelController' => 'PhabricatorApplicationsController', 'PhabricatorApplicationQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorApplicationSearchController' => 'PhabricatorSearchBaseController', 'PhabricatorApplicationStatusView' => 'AphrontView', @@ -5272,6 +5275,7 @@ ), 'PhabricatorMetaMTAApplicationEmailDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorMetaMTAApplicationEmailPHIDType' => 'PhabricatorPHIDType', + 'PhabricatorMetaMTAApplicationEmailPanel' => 'PhabricatorApplicationConfigurationPanel', 'PhabricatorMetaMTAApplicationEmailQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 'PhabricatorMetaMTAConfigOptions' => 'PhabricatorApplicationConfigOptions', 'PhabricatorMetaMTAController' => 'PhabricatorController', diff --git a/src/applications/meta/application/PhabricatorApplicationsApplication.php b/src/applications/meta/application/PhabricatorApplicationsApplication.php --- a/src/applications/meta/application/PhabricatorApplicationsApplication.php +++ b/src/applications/meta/application/PhabricatorApplicationsApplication.php @@ -41,10 +41,10 @@ => 'PhabricatorApplicationDetailViewController', 'edit/(?P\w+)/' => 'PhabricatorApplicationEditController', - 'editemail/(?P\w+)/' - => 'PhabricatorApplicationEditEmailController', '(?P\w+)/(?Pinstall|uninstall)/' => 'PhabricatorApplicationUninstallController', + 'panel/(?P\w+)/(?P\w+)/(?P.*)' + => 'PhabricatorApplicationPanelController', ), ); } diff --git a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php --- a/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php +++ b/src/applications/meta/controller/PhabricatorApplicationDetailViewController.php @@ -9,11 +9,11 @@ } public function handleRequest(AphrontRequest $request) { - $user = $request->getUser(); + $viewer = $this->getViewer(); $application = $request->getURIData('application'); $selected = id(new PhabricatorApplicationQuery()) - ->setViewer($user) + ->setViewer($viewer) ->withClasses(array($application)) ->executeOne(); if (!$selected) { @@ -27,7 +27,7 @@ $header = id(new PHUIHeaderView()) ->setHeader($title) - ->setUser($user) + ->setUser($viewer) ->setPolicyObject($selected); if ($selected->isInstalled()) { @@ -36,17 +36,30 @@ $header->setStatus('fa-ban', 'dark', pht('Uninstalled')); } - $actions = $this->buildActionView($user, $selected); + $actions = $this->buildActionView($viewer, $selected); $properties = $this->buildPropertyView($selected, $actions); $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) ->addPropertyList($properties); + $configs = + PhabricatorApplicationConfigurationPanel::loadAllPanelsForApplication( + $selected); + + $panels = array(); + foreach ($configs as $config) { + $config->setViewer($viewer); + $config->setApplication($selected); + + $panels[] = $config->buildConfigurationPagePanel(); + } + return $this->buildApplicationPage( array( $crumbs, $object_box, + $panels, ), array( 'title' => $title, @@ -114,26 +127,6 @@ idx($descriptions, $capability)); } - if ($application->supportsEmailIntegration()) { - $properties->addSectionHeader(pht('Application Emails')); - $properties->addTextContent($application->getAppEmailBlurb()); - $email_addresses = id(new PhabricatorMetaMTAApplicationEmailQuery()) - ->setViewer($viewer) - ->withApplicationPHIDs(array($application->getPHID())) - ->execute(); - if (empty($email_addresses)) { - $properties->addProperty( - null, - pht('No email addresses configured.')); - } else { - foreach ($email_addresses as $email_address) { - $properties->addProperty( - null, - $email_address->getAddress()); - } - } - } - return $properties; } @@ -168,18 +161,6 @@ ->setWorkflow(!$can_edit) ->setHref($edit_uri)); - if ($selected->supportsEmailIntegration()) { - $edit_email_uri = $this->getApplicationURI( - 'editemail/'.get_class($selected).'/'); - $view->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Edit Application Emails')) - ->setIcon('fa-envelope') - ->setDisabled(!$can_edit) - ->setWorkflow(!$can_edit) - ->setHref($edit_email_uri)); - } - if ($selected->canUninstall()) { if ($selected->isInstalled()) { $view->addAction( diff --git a/src/applications/meta/controller/PhabricatorApplicationPanelController.php b/src/applications/meta/controller/PhabricatorApplicationPanelController.php new file mode 100644 --- /dev/null +++ b/src/applications/meta/controller/PhabricatorApplicationPanelController.php @@ -0,0 +1,67 @@ +getViewer(); + + $application = $request->getURIData('application'); + $panel_key = $request->getURIData('panel'); + + $selected = id(new PhabricatorApplicationQuery()) + ->setViewer($viewer) + ->withClasses(array($application)) + ->requireCapabilities( + array( + PhabricatorPolicyCapability::CAN_VIEW, + PhabricatorPolicyCapability::CAN_EDIT, + )) + ->executeOne(); + if (!$selected) { + return new Aphront404Response(); + } + + $panels = + PhabricatorApplicationConfigurationPanel::loadAllPanelsForApplication( + $selected); + if (empty($panels[$panel_key])) { + return new Aphront404Response(); + } + + $panel = $panels[$panel_key]; + + if (!$panel->shouldShowForApplication($selected)) { + return new Aphront404Response(); + } + + $panel->setViewer($viewer); + $panel->setApplication($selected); + + $this->application = $selected; + + return $panel->handlePanelRequest($request, $this); + } + + public function buildPanelCrumbs( + PhabricatorApplicationConfigurationPanel $panel) { + $application = $this->application; + + $crumbs = $this->buildApplicationCrumbs(); + + $view_uri = '/applications/view/'.get_class($application).'/'; + $crumbs->addTextCrumb($application->getName(), $view_uri); + + return $crumbs; + } + + public function buildPanelPage( + PhabricatorApplicationConfigurationPanel $panel, + $content, + array $options) { + return $this->buildApplicationPage($content, $options); + } + +} diff --git a/src/applications/meta/panel/PhabricatorApplicationConfigurationPanel.php b/src/applications/meta/panel/PhabricatorApplicationConfigurationPanel.php new file mode 100644 --- /dev/null +++ b/src/applications/meta/panel/PhabricatorApplicationConfigurationPanel.php @@ -0,0 +1,88 @@ +viewer = $viewer; + return $this; + } + + public function getViewer() { + return $this->viewer; + } + + public function setApplication(PhabricatorApplication $application) { + $this->application = $application; + return $this; + } + + public function getApplication() { + return $this->application; + } + + public function getPanelURI($path = null) { + $app_key = get_class($this->getApplication()); + $panel_key = $this->getPanelKey(); + $base = "/applications/panel/{$app_key}/{$panel_key}/"; + return $base.ltrim($path, '/'); + } + + /** + * Return a short, unique string key which identifies this panel. + * + * This key is used in URIs. Good values might be "email" or "files". + */ + abstract public function getPanelKey(); + + abstract public function shouldShowForApplication( + PhabricatorApplication $application); + + abstract public function buildConfigurationPagePanel(); + abstract public function handlePanelRequest( + AphrontRequest $request, + PhabricatorController $controller); + + public static function loadAllPanels() { + $objects = id(new PhutilSymbolLoader()) + ->setAncestorClass(__CLASS__) + ->loadObjects(); + + $panels = array(); + foreach ($objects as $object) { + $key = $object->getPanelKey(); + if (empty($panels[$key])) { + $panels[$key] = $object; + } else { + throw new Exception( + pht( + 'Application configuration panels "%s" and "%s" have the same '. + 'panel key, "%s". Each panel must have a unique key.', + get_class($object), + get_class($panels[$key]), + $key)); + } + } + + return $panels; + } + + public static function loadAllPanelsForApplication( + PhabricatorApplication $application) { + $panels = self::loadAllPanels(); + + $application_panels = array(); + foreach ($panels as $key => $panel) { + if (!$panel->shouldShowForApplication($application)) { + continue; + } + $application_panels[$key] = $panel; + } + + return $application_panels; + } + +} diff --git a/src/applications/meta/controller/PhabricatorApplicationEditEmailController.php b/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php rename from src/applications/meta/controller/PhabricatorApplicationEditEmailController.php rename to src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php --- a/src/applications/meta/controller/PhabricatorApplicationEditEmailController.php +++ b/src/applications/metamta/applicationpanel/PhabricatorMetaMTAApplicationEmailPanel.php @@ -1,27 +1,77 @@ getUser(); - $application = $request->getURIData('application'); + public function getPanelKey() { + return 'email'; + } + + public function shouldShowForApplication( + PhabricatorApplication $application) { + return $application->supportsEmailIntegration(); + } - $application = id(new PhabricatorApplicationQuery()) + public function buildConfigurationPagePanel() { + $viewer = $this->getViewer(); + $application = $this->getApplication(); + + $addresses = id(new PhabricatorMetaMTAApplicationEmailQuery()) ->setViewer($viewer) - ->withClasses(array($application)) - ->requireCapabilities( + ->withApplicationPHIDs(array($application->getPHID())) + ->execute(); + + $rows = array(); + foreach ($addresses as $address) { + $rows[] = array( + $address->getAddress(), + ); + } + + $table = id(new AphrontTableView($rows)) + ->setNoDataString(pht('No email addresses configured.')) + ->setHeaders( array( - PhabricatorPolicyCapability::CAN_VIEW, - PhabricatorPolicyCapability::CAN_EDIT, - )) - ->executeOne(); - if (!$application) { + pht('Address'), + )); + + $can_edit = PhabricatorPolicyFilter::hasCapability( + $viewer, + $application, + PhabricatorPolicyCapability::CAN_EDIT); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Application Emails')) + ->addActionLink( + id(new PHUIButtonView()) + ->setTag('a') + ->setText(pht('Edit Application Emails')) + ->setIcon( + id(new PHUIIconView()) + ->setIconFont('fa-pencil')) + ->setHref($this->getPanelURI()) + ->setDisabled(!$can_edit) + ->setWorkflow(!$can_edit)); + + + $box = id(new PHUIObjectBoxView()) + ->setHeader($header) + ->appendChild($table); + + return $box; + } + + public function handlePanelRequest( + AphrontRequest $request, + PhabricatorController $controller) { + $viewer = $request->getViewer(); + $application = $this->getApplication(); + + $path = $request->getURIData('path'); + if (strlen($path)) { return new Aphront404Response(); } - $title = $application->getName(); - $uri = $request->getRequestURI(); $uri->setQueryParams(array()); @@ -106,13 +156,12 @@ $form = id(new AphrontFormView()) ->setUser($viewer); - $view_uri = $this->getApplicationURI('view/'.get_class($application).'/'); - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb($application->getName(), $view_uri); + $crumbs = $controller->buildPanelCrumbs($this); $crumbs->addTextCrumb(pht('Edit Application Emails')); $header = id(new PHUIHeaderView()) - ->setHeader(pht('Edit Application Emails: %s', $application->getName())); + ->setHeader(pht('Edit Application Emails: %s', $application->getName())) + ->setSubheader($application->getAppEmailBlurb()); $icon = id(new PHUIIconView()) ->setIconFont('fa-plus'); @@ -126,13 +175,12 @@ $object_box = id(new PHUIObjectBoxView()) ->setHeader($header) - ->appendChild($table) - ->appendChild( - id(new PHUIBoxView()) - ->appendChild($application->getAppEmailBlurb()) - ->addPadding(PHUI::PADDING_MEDIUM)); + ->appendChild($table); + + $title = $application->getName(); - return $this->buildApplicationPage( + return $controller->buildPanelPage( + $this, array( $crumbs, $object_box, @@ -253,7 +301,10 @@ $default_user = $email_object->getConfigValue($default_user_key); if ($default_user) { - $default_user_handle = $this->loadViewerHandles(array($default_user)); + $default_user_handle = id(new PhabricatorHandleQuery()) + ->setViewer($viewer) + ->withPHIDs(array($default_user)) + ->execute(); } else { $default_user_handle = array(); }