1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-27 01:02:42 +01:00

Modularize application configuration panels

Summary:
Ref T7149. This is a few steps away, but:

  - Generally, I'd like to reduce the amount of "Config" configuration we have.
  - One good way to do this is to move it into UIs in Application configuration. We did this with email recently.
  - I think this was a great change and I'd like to keep moving in this direction.
  - T7149 touches configuration related to file storage engines. Although I'm not planning to fully move configuration into applications yet, it would be easier to debug and test if I could drop a read-only panel there to show engines.
  - So, modularize the config stuff so I can add a new panel without hard-coding it.

Test Plan:
  - Added, edited, and deleted application emails.
  - Viewed non-email application detail pages.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7149

Differential Revision: https://secure.phabricator.com/D12051
This commit is contained in:
epriestley 2015-03-12 13:28:37 -07:00
parent c1bd1d1b9a
commit 973079a7da
7 changed files with 306 additions and 119 deletions

View file

@ -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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'javelin-request',
'javelin-util',
),
'4a2430d7' => array(
'phui-fontkit-css',
),
'4d94d9c3' => array(
'javelin-behavior',
'javelin-stratcom',
@ -1546,16 +1533,6 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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 @@ return array(
'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',

View file

@ -1269,11 +1269,12 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
'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 @@ phutil_register_library_map(array(
),
'PhabricatorMetaMTAApplicationEmailDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorMetaMTAApplicationEmailPHIDType' => 'PhabricatorPHIDType',
'PhabricatorMetaMTAApplicationEmailPanel' => 'PhabricatorApplicationConfigurationPanel',
'PhabricatorMetaMTAApplicationEmailQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorMetaMTAConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorMetaMTAController' => 'PhabricatorController',

View file

@ -41,10 +41,10 @@ final class PhabricatorApplicationsApplication extends PhabricatorApplication {
=> 'PhabricatorApplicationDetailViewController',
'edit/(?P<application>\w+)/'
=> 'PhabricatorApplicationEditController',
'editemail/(?P<application>\w+)/'
=> 'PhabricatorApplicationEditEmailController',
'(?P<application>\w+)/(?P<action>install|uninstall)/'
=> 'PhabricatorApplicationUninstallController',
'panel/(?P<application>\w+)/(?P<panel>\w+)/(?P<path>.*)'
=> 'PhabricatorApplicationPanelController',
),
);
}

View file

@ -9,11 +9,11 @@ final class PhabricatorApplicationDetailViewController
}
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 @@ final class PhabricatorApplicationDetailViewController
$header = id(new PHUIHeaderView())
->setHeader($title)
->setUser($user)
->setUser($viewer)
->setPolicyObject($selected);
if ($selected->isInstalled()) {
@ -36,17 +36,30 @@ final class PhabricatorApplicationDetailViewController
$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 @@ final class PhabricatorApplicationDetailViewController
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 @@ final class PhabricatorApplicationDetailViewController
->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(

View file

@ -0,0 +1,67 @@
<?php
final class PhabricatorApplicationPanelController
extends PhabricatorApplicationsController {
private $application;
public function handleRequest(AphrontRequest $request) {
$viewer = $this->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);
}
}

View file

@ -0,0 +1,88 @@
<?php
abstract class PhabricatorApplicationConfigurationPanel
extends Phobject {
private $viewer;
private $application;
public function setViewer(PhabricatorUser $viewer) {
$this->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;
}
}

View file

@ -1,26 +1,76 @@
<?php
final class PhabricatorApplicationEditEmailController
extends PhabricatorApplicationsController {
final class PhabricatorMetaMTAApplicationEmailPanel
extends PhabricatorApplicationConfigurationPanel {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getUser();
$application = $request->getURIData('application');
$application = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withClasses(array($application))
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->executeOne();
if (!$application) {
return new Aphront404Response();
public function getPanelKey() {
return 'email';
}
$title = $application->getName();
public function shouldShowForApplication(
PhabricatorApplication $application) {
return $application->supportsEmailIntegration();
}
public function buildConfigurationPagePanel() {
$viewer = $this->getViewer();
$application = $this->getApplication();
$addresses = id(new PhabricatorMetaMTAApplicationEmailQuery())
->setViewer($viewer)
->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(
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();
}
$uri = $request->getRequestURI();
$uri->setQueryParams(array());
@ -106,13 +156,12 @@ final class PhabricatorApplicationEditEmailController
$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 @@ final class PhabricatorApplicationEditEmailController
$object_box = id(new PHUIObjectBoxView())
->setHeader($header)
->appendChild($table)
->appendChild(
id(new PHUIBoxView())
->appendChild($application->getAppEmailBlurb())
->addPadding(PHUI::PADDING_MEDIUM));
->appendChild($table);
return $this->buildApplicationPage(
$title = $application->getName();
return $controller->buildPanelPage(
$this,
array(
$crumbs,
$object_box,
@ -253,7 +301,10 @@ final class PhabricatorApplicationEditEmailController
$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();
}