mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +01:00
Update Repository Management pages to new fixed UI
Summary: Simplifies the Repository Management pages to the new fixed column layout. I've also moved "Status" into the Basics page, which feels better, and moved "Documentation" as a nav item to a button in the header. This removed "action list" and "curtain view" from the management panels and uses the new bits from Config/Phacility. Undecided if the icons should stay or go for the nav. Left them in for Diffusion. I want to update the EditEngine pages to display in this UI and not leave the portal, but I haven't dug into that this page. I'm a bit worried it will not easily be possible. Test Plan: Generate a svn, git, hg repository, test each of the new pages and each of the new buttons. Activate, deactivate, etc. {F5164674} Reviewers: epriestley Reviewed By: epriestley Spies: Korvin Differential Revision: https://secure.phabricator.com/D18523
This commit is contained in:
parent
f40f3ca74c
commit
e1fd74ddb5
21 changed files with 749 additions and 978 deletions
|
@ -9,7 +9,7 @@ return array(
|
|||
'names' => array(
|
||||
'conpherence.pkg.css' => 'e68cf1fa',
|
||||
'conpherence.pkg.js' => 'b5b51108',
|
||||
'core.pkg.css' => '042e1782',
|
||||
'core.pkg.css' => 'ebbf04f7',
|
||||
'core.pkg.js' => '6c085267',
|
||||
'darkconsole.pkg.js' => '1f9a31bc',
|
||||
'differential.pkg.css' => '45951e9e',
|
||||
|
@ -142,7 +142,7 @@ return array(
|
|||
'rsrc/css/phui/phui-badge.css' => '22c0cf4f',
|
||||
'rsrc/css/phui/phui-basic-nav-view.css' => '98c11ab3',
|
||||
'rsrc/css/phui/phui-big-info-view.css' => 'acc3492c',
|
||||
'rsrc/css/phui/phui-box.css' => '4165eb0d',
|
||||
'rsrc/css/phui/phui-box.css' => '9f3745fb',
|
||||
'rsrc/css/phui/phui-chart.css' => '6bf6f78e',
|
||||
'rsrc/css/phui/phui-cms.css' => '504b4b23',
|
||||
'rsrc/css/phui/phui-comment-form.css' => 'ac68149f',
|
||||
|
@ -157,7 +157,7 @@ return array(
|
|||
'rsrc/css/phui/phui-form-view.css' => 'ae9f8d16',
|
||||
'rsrc/css/phui/phui-form.css' => '7aaa04e3',
|
||||
'rsrc/css/phui/phui-head-thing.css' => 'fd311e5f',
|
||||
'rsrc/css/phui/phui-header-view.css' => '3c722648',
|
||||
'rsrc/css/phui/phui-header-view.css' => '369275d6',
|
||||
'rsrc/css/phui/phui-hovercard.css' => 'f0592bcf',
|
||||
'rsrc/css/phui/phui-icon-set-selector.css' => '87db8fee',
|
||||
'rsrc/css/phui/phui-icon.css' => '5c4a5de6',
|
||||
|
@ -820,7 +820,7 @@ return array(
|
|||
'phui-badge-view-css' => '22c0cf4f',
|
||||
'phui-basic-nav-view-css' => '98c11ab3',
|
||||
'phui-big-info-view-css' => 'acc3492c',
|
||||
'phui-box-css' => '4165eb0d',
|
||||
'phui-box-css' => '9f3745fb',
|
||||
'phui-button-bar-css' => 'f1ff5494',
|
||||
'phui-button-css' => '1863cc6e',
|
||||
'phui-button-simple-css' => '8e1baf68',
|
||||
|
@ -843,7 +843,7 @@ return array(
|
|||
'phui-form-css' => '7aaa04e3',
|
||||
'phui-form-view-css' => 'ae9f8d16',
|
||||
'phui-head-thing-view-css' => 'fd311e5f',
|
||||
'phui-header-view-css' => '3c722648',
|
||||
'phui-header-view-css' => '369275d6',
|
||||
'phui-hovercard' => '1bd28176',
|
||||
'phui-hovercard-view-css' => 'f0592bcf',
|
||||
'phui-icon-set-selector-css' => '87db8fee',
|
||||
|
|
|
@ -843,7 +843,6 @@ phutil_register_library_map(array(
|
|||
'DiffusionRepositoryController' => 'applications/diffusion/controller/DiffusionRepositoryController.php',
|
||||
'DiffusionRepositoryDatasource' => 'applications/diffusion/typeahead/DiffusionRepositoryDatasource.php',
|
||||
'DiffusionRepositoryDefaultController' => 'applications/diffusion/controller/DiffusionRepositoryDefaultController.php',
|
||||
'DiffusionRepositoryDocumentationManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryDocumentationManagementPanel.php',
|
||||
'DiffusionRepositoryEditActivateController' => 'applications/diffusion/controller/DiffusionRepositoryEditActivateController.php',
|
||||
'DiffusionRepositoryEditConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRepositoryEditConduitAPIMethod.php',
|
||||
'DiffusionRepositoryEditController' => 'applications/diffusion/controller/DiffusionRepositoryEditController.php',
|
||||
|
@ -864,7 +863,6 @@ phutil_register_library_map(array(
|
|||
'DiffusionRepositoryRemarkupRule' => 'applications/diffusion/remarkup/DiffusionRepositoryRemarkupRule.php',
|
||||
'DiffusionRepositorySearchConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRepositorySearchConduitAPIMethod.php',
|
||||
'DiffusionRepositoryStagingManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryStagingManagementPanel.php',
|
||||
'DiffusionRepositoryStatusManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php',
|
||||
'DiffusionRepositoryStorageManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryStorageManagementPanel.php',
|
||||
'DiffusionRepositorySubversionManagementPanel' => 'applications/diffusion/management/DiffusionRepositorySubversionManagementPanel.php',
|
||||
'DiffusionRepositorySymbolsManagementPanel' => 'applications/diffusion/management/DiffusionRepositorySymbolsManagementPanel.php',
|
||||
|
@ -5863,7 +5861,6 @@ phutil_register_library_map(array(
|
|||
'DiffusionRepositoryController' => 'DiffusionController',
|
||||
'DiffusionRepositoryDatasource' => 'PhabricatorTypeaheadDatasource',
|
||||
'DiffusionRepositoryDefaultController' => 'DiffusionController',
|
||||
'DiffusionRepositoryDocumentationManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||
'DiffusionRepositoryEditActivateController' => 'DiffusionRepositoryManageController',
|
||||
'DiffusionRepositoryEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod',
|
||||
'DiffusionRepositoryEditController' => 'DiffusionRepositoryManageController',
|
||||
|
@ -5884,7 +5881,6 @@ phutil_register_library_map(array(
|
|||
'DiffusionRepositoryRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||
'DiffusionRepositorySearchConduitAPIMethod' => 'PhabricatorSearchEngineAPIMethod',
|
||||
'DiffusionRepositoryStagingManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||
'DiffusionRepositoryStatusManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||
'DiffusionRepositoryStorageManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||
'DiffusionRepositorySubversionManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||
'DiffusionRepositorySymbolsManagementPanel' => 'DiffusionRepositoryManagementPanel',
|
||||
|
|
|
@ -13,7 +13,7 @@ final class DiffusionRepositoryEditUpdateController
|
|||
$drequest = $this->getDiffusionRequest();
|
||||
$repository = $drequest->getRepository();
|
||||
|
||||
$panel_uri = id(new DiffusionRepositoryStatusManagementPanel())
|
||||
$panel_uri = id(new DiffusionRepositoryBasicsManagementPanel())
|
||||
->setRepository($repository)
|
||||
->getPanelURI();
|
||||
|
||||
|
|
|
@ -22,4 +22,20 @@ abstract class DiffusionRepositoryManageController
|
|||
return $crumbs;
|
||||
}
|
||||
|
||||
public function newBox($title, $content, $action = null) {
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title);
|
||||
|
||||
if ($action) {
|
||||
$header->addActionItem($action);
|
||||
}
|
||||
|
||||
$view = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->appendChild($content)
|
||||
->setBackground(PHUIObjectBoxView::WHITE_CONFIG);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,10 @@ final class DiffusionRepositoryManagePanelsController
|
|||
|
||||
$panel = $panels[$selected];
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($panel->getManagementPanelLabel());
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$content = $panel->buildManagementPanelContent();
|
||||
|
||||
$title = array(
|
||||
|
@ -60,45 +64,17 @@ final class DiffusionRepositoryManagePanelsController
|
|||
$repository->getDisplayName(),
|
||||
);
|
||||
|
||||
$crumbs = $this->buildApplicationCrumbs();
|
||||
$crumbs->addTextCrumb($panel->getManagementPanelLabel());
|
||||
$crumbs->setBorder(true);
|
||||
|
||||
$header_text = pht(
|
||||
'%s: %s',
|
||||
$repository->getDisplayName(),
|
||||
$panel->getManagementPanelLabel());
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($header_text)
|
||||
->setHeaderIcon('fa-pencil');
|
||||
if ($repository->isTracked()) {
|
||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||
} else {
|
||||
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
||||
}
|
||||
|
||||
$header->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('View Repository'))
|
||||
->setHref($repository->getURI())
|
||||
->setIcon('fa-code')
|
||||
->setColor(PHUIButtonView::GREEN));
|
||||
$header = $this->buildHeaderView($repository->getDisplayName());
|
||||
|
||||
$view = id(new PHUITwoColumnView())
|
||||
->setHeader($header)
|
||||
->setNavigation($nav)
|
||||
->setFixed(true)
|
||||
->setMainColumn($content);
|
||||
|
||||
$curtain = $panel->buildManagementPanelCurtain();
|
||||
if ($curtain) {
|
||||
$view->setCurtain($curtain);
|
||||
}
|
||||
|
||||
return $this->newPage()
|
||||
->setTitle($title)
|
||||
->setCrumbs($crumbs)
|
||||
->setNavigation($nav)
|
||||
->appendChild($view);
|
||||
}
|
||||
|
||||
|
@ -113,12 +89,6 @@ final class DiffusionRepositoryManagePanelsController
|
|||
$nav = id(new AphrontSideNavFilterView())
|
||||
->setBaseURI($base_uri);
|
||||
|
||||
$item = id(new PHUIListItemView())
|
||||
->setName(pht('manage'))
|
||||
->setType(PHUIListItemView::TYPE_LABEL);
|
||||
|
||||
$nav->addMenuItem($item);
|
||||
|
||||
foreach ($panels as $panel) {
|
||||
$key = $panel->getManagementPanelKey();
|
||||
$label = $panel->getManagementPanelLabel();
|
||||
|
@ -140,6 +110,46 @@ final class DiffusionRepositoryManagePanelsController
|
|||
return $nav;
|
||||
}
|
||||
|
||||
public function buildHeaderView($title) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$drequest = $this->getDiffusionRequest();
|
||||
$repository = $drequest->getRepository();
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($title)
|
||||
->setProfileHeader(true)
|
||||
->setHref($repository->getURI())
|
||||
->setImage($repository->getProfileImageURI());
|
||||
|
||||
if ($repository->isTracked()) {
|
||||
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
|
||||
} else {
|
||||
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
|
||||
}
|
||||
|
||||
$doc_href = PhabricatorEnv::getDoclink(
|
||||
'Diffusion User Guide: Managing Repositories');
|
||||
|
||||
$header->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('View Repository'))
|
||||
->setHref($repository->getURI())
|
||||
->setIcon('fa-code')
|
||||
->setColor(PHUIButtonView::GREY));
|
||||
|
||||
$header->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-book')
|
||||
->setHref($doc_href)
|
||||
->setText(pht('Help'))
|
||||
->setColor(PHUIButtonView::GREY));
|
||||
|
||||
return $header;
|
||||
}
|
||||
|
||||
public function newTimeline(PhabricatorRepository $repository) {
|
||||
$timeline = $this->buildTransactionTimeline(
|
||||
$repository,
|
||||
|
|
|
@ -14,20 +14,7 @@ final class DiffusionRepositoryActionsManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
$has_any =
|
||||
$repository->getDetail('herald-disabled') ||
|
||||
$repository->getDetail('disable-autoclose');
|
||||
|
||||
// NOTE: Any value here really means something is disabled, so try to
|
||||
// hint that a little bit with the icon.
|
||||
|
||||
if ($has_any) {
|
||||
return 'fa-comment-o';
|
||||
} else {
|
||||
return 'fa-commenting grey';
|
||||
}
|
||||
return 'fa-flash';
|
||||
}
|
||||
|
||||
protected function getEditEngineFieldKeys() {
|
||||
|
@ -37,29 +24,6 @@ final class DiffusionRepositoryActionsManagementPanel
|
|||
);
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$actions_uri = $this->getEditPageURI();
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Actions'))
|
||||
->setHref($actions_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -79,7 +43,22 @@ final class DiffusionRepositoryActionsManagementPanel
|
|||
$autoclose = phutil_tag('em', array(), $autoclose);
|
||||
$view->addProperty(pht('Autoclose'), $autoclose);
|
||||
|
||||
return $this->newBox(pht('Actions'), $view);
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$actions_uri = $this->getEditPageURI();
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-pencil')
|
||||
->setText(pht('Edit'))
|
||||
->setHref($actions_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
return $this->newBox(pht('Actions'), $view, array($button));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,59 +27,18 @@ final class DiffusionRepositoryAutomationManagementPanel
|
|||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
if (!$repository->canPerformAutomation()) {
|
||||
return 'fa-truck grey';
|
||||
}
|
||||
|
||||
$blueprint_phids = $repository->getAutomationBlueprintPHIDs();
|
||||
if (!$blueprint_phids) {
|
||||
return 'fa-truck grey';
|
||||
}
|
||||
|
||||
$is_authorized = DrydockAuthorizationQuery::isFullyAuthorized(
|
||||
$repository->getPHID(),
|
||||
$blueprint_phids);
|
||||
if (!$is_authorized) {
|
||||
return 'fa-exclamation-triangle yellow';
|
||||
return 'fa-exclamation-triangle';
|
||||
}
|
||||
|
||||
return 'fa-truck';
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$can_test = $can_edit && $repository->canPerformAutomation();
|
||||
|
||||
$automation_uri = $this->getEditPageURI();
|
||||
$test_uri = $repository->getPathURI('edit/testautomation/');
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Automation'))
|
||||
->setHref($automation_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-gamepad')
|
||||
->setName(pht('Test Configuration'))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_test)
|
||||
->setHref($test_uri));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -99,7 +58,33 @@ final class DiffusionRepositoryAutomationManagementPanel
|
|||
|
||||
$view->addProperty(pht('Automation'), $blueprint_view);
|
||||
|
||||
return $this->newBox(pht('Automation'), $view);
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$can_test = $can_edit && $repository->canPerformAutomation();
|
||||
|
||||
$automation_uri = $this->getEditPageURI();
|
||||
$test_uri = $repository->getPathURI('edit/testautomation/');
|
||||
|
||||
$edit = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-pencil')
|
||||
->setText(pht('Edit'))
|
||||
->setHref($automation_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$test = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-gamepad')
|
||||
->setText(pht('Test Config'))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_test)
|
||||
->setHref($test_uri);
|
||||
|
||||
return $this->newBox(pht('Automation'), $view, array($edit, $test));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,13 +14,7 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
if (!$repository->isTracked()) {
|
||||
return 'fa-ban indigo';
|
||||
} else {
|
||||
return 'fa-code';
|
||||
}
|
||||
return 'fa-code';
|
||||
}
|
||||
|
||||
protected function getEditEngineFieldKeys() {
|
||||
|
@ -33,10 +27,11 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
);
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
private function buildActionMenu() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
$action_list = id(new PhabricatorActionListView())
|
||||
->setViewer($viewer);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
|
@ -50,27 +45,22 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
$dangerous_uri = $repository->getPathURI('edit/dangerous/');
|
||||
|
||||
if ($repository->isTracked()) {
|
||||
$activate_icon = 'fa-pause';
|
||||
$activate_label = pht('Deactivate Repository');
|
||||
} else {
|
||||
$activate_icon = 'fa-play';
|
||||
$activate_label = pht('Activate Repository');
|
||||
}
|
||||
|
||||
$should_dangerous = $repository->shouldAllowDangerousChanges();
|
||||
if ($should_dangerous) {
|
||||
$dangerous_icon = 'fa-shield';
|
||||
$dangerous_name = pht('Prevent Dangerous Changes');
|
||||
$can_dangerous = $can_edit;
|
||||
} else {
|
||||
$dangerous_icon = 'fa-bullseye';
|
||||
$dangerous_name = pht('Allow Dangerous Changes');
|
||||
$can_dangerous = ($can_edit && $repository->canAllowDangerousChanges());
|
||||
}
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Basic Information'))
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
|
@ -78,7 +68,6 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-text-width')
|
||||
->setName(pht('Edit Text Encoding'))
|
||||
->setHref($encoding_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
|
@ -86,7 +75,6 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon($dangerous_icon)
|
||||
->setName($dangerous_name)
|
||||
->setHref($dangerous_uri)
|
||||
->setDisabled(!$can_dangerous)
|
||||
|
@ -95,26 +83,37 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setHref($activate_uri)
|
||||
->setIcon($activate_icon)
|
||||
->setName($activate_label)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(true));
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setType(PhabricatorActionView::TYPE_DIVIDER));
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setName(pht('Delete Repository'))
|
||||
->setIcon('fa-times')
|
||||
->setHref($delete_uri)
|
||||
->setColor(PhabricatorActionView::RED)
|
||||
->setDisabled(true)
|
||||
->setWorkflow(true));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
return $action_list;
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$result = array();
|
||||
|
||||
$basics = $this->newBox(pht('Repository Basics'), $this->buildBasics());
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Actions'))
|
||||
->setHref('#')
|
||||
->setIcon('fa-bars')
|
||||
->addClass('phui-mobile-menu')
|
||||
->setDropdownMenu($this->buildActionMenu());
|
||||
|
||||
$basics = $this->buildBasics();
|
||||
$basics = $this->newBox(pht('Properties'), $basics, array($button));
|
||||
|
||||
$repository = $this->getRepository();
|
||||
$is_new = $repository->isNewlyInitialized();
|
||||
|
@ -144,14 +143,13 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
->setErrors($messages);
|
||||
}
|
||||
|
||||
$result[] = $basics;
|
||||
|
||||
$description = $this->buildDescription();
|
||||
if ($description) {
|
||||
$result[] = $this->newBox(pht('Description'), $description);
|
||||
$description = $this->newBox(pht('Description'), $description);
|
||||
}
|
||||
$status = $this->buildStatus();
|
||||
|
||||
return array($info_view, $result);
|
||||
return array($info_view, $basics, $description, $status);
|
||||
}
|
||||
|
||||
private function buildBasics() {
|
||||
|
@ -213,7 +211,7 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
$view = id(new PHUIPropertyListView())
|
||||
->setViewer($viewer);
|
||||
if (!strlen($description)) {
|
||||
$description = phutil_tag('em', array(), pht('No description provided.'));
|
||||
return null;
|
||||
} else {
|
||||
$description = new PHUIRemarkupView($viewer, $description);
|
||||
}
|
||||
|
@ -222,4 +220,471 @@ final class DiffusionRepositoryBasicsManagementPanel
|
|||
return $view;
|
||||
}
|
||||
|
||||
private function buildStatus() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$update_uri = $repository->getPathURI('edit/update/');
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setViewer($viewer);
|
||||
|
||||
$view->addProperty(
|
||||
pht('Update Frequency'),
|
||||
$this->buildRepositoryUpdateInterval($repository));
|
||||
|
||||
$messages = $this->loadStatusMessages($repository);
|
||||
|
||||
$status = $this->buildRepositoryStatus($repository, $messages);
|
||||
$raw_error = $this->buildRepositoryRawError($repository, $messages);
|
||||
|
||||
$view->addProperty(pht('Status'), $status);
|
||||
if ($raw_error) {
|
||||
$view->addSectionHeader(pht('Raw Error'));
|
||||
$view->addTextContent($raw_error);
|
||||
}
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-refresh')
|
||||
->setText(pht('Update Now'))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit)
|
||||
->setHref($update_uri);
|
||||
|
||||
return $this->newBox(pht('Status'), $view, array($button));
|
||||
}
|
||||
|
||||
private function buildRepositoryUpdateInterval(
|
||||
PhabricatorRepository $repository) {
|
||||
|
||||
$smart_wait = $repository->loadUpdateInterval();
|
||||
|
||||
$doc_href = PhabricatorEnv::getDoclink(
|
||||
'Diffusion User Guide: Repository Updates');
|
||||
|
||||
return array(
|
||||
phutil_format_relative_time_detailed($smart_wait),
|
||||
" \xC2\xB7 ",
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $doc_href,
|
||||
'target' => '_blank',
|
||||
),
|
||||
pht('Learn More')),
|
||||
);
|
||||
}
|
||||
|
||||
private function buildRepositoryStatus(
|
||||
PhabricatorRepository $repository,
|
||||
array $messages) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$is_cluster = $repository->getAlmanacServicePHID();
|
||||
|
||||
$view = new PHUIStatusListView();
|
||||
|
||||
if ($repository->isTracked()) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Repository Active')));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey')
|
||||
->setTarget(pht('Repository Inactive'))
|
||||
->setNote(
|
||||
pht('Activate this repository to begin or resume import.')));
|
||||
return $view;
|
||||
}
|
||||
|
||||
$binaries = array();
|
||||
$svnlook_check = false;
|
||||
switch ($repository->getVersionControlSystem()) {
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||
$binaries[] = 'git';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
||||
$binaries[] = 'svn';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
||||
$binaries[] = 'hg';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($repository->isHosted()) {
|
||||
$proto_https = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS;
|
||||
$proto_http = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP;
|
||||
$can_http = $repository->canServeProtocol($proto_http, false) ||
|
||||
$repository->canServeProtocol($proto_https, false);
|
||||
|
||||
if ($can_http) {
|
||||
switch ($repository->getVersionControlSystem()) {
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||
$binaries[] = 'git-http-backend';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
||||
$binaries[] = 'svnserve';
|
||||
$binaries[] = 'svnadmin';
|
||||
$binaries[] = 'svnlook';
|
||||
$svnlook_check = true;
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
||||
$binaries[] = 'hg';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$proto_ssh = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH;
|
||||
$can_ssh = $repository->canServeProtocol($proto_ssh, false);
|
||||
|
||||
if ($can_ssh) {
|
||||
switch ($repository->getVersionControlSystem()) {
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||
$binaries[] = 'git-receive-pack';
|
||||
$binaries[] = 'git-upload-pack';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
||||
$binaries[] = 'svnserve';
|
||||
$binaries[] = 'svnadmin';
|
||||
$binaries[] = 'svnlook';
|
||||
$svnlook_check = true;
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
||||
$binaries[] = 'hg';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$binaries = array_unique($binaries);
|
||||
if (!$is_cluster) {
|
||||
// We're only checking for binaries if we aren't running with a cluster
|
||||
// configuration. In theory, we could check for binaries on the
|
||||
// repository host machine, but we'd need to make this more complicated
|
||||
// to do that.
|
||||
|
||||
foreach ($binaries as $binary) {
|
||||
$where = Filesystem::resolveBinary($binary);
|
||||
if (!$where) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(
|
||||
pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
|
||||
->setNote(pht(
|
||||
"Unable to find this binary in the webserver's PATH. You may ".
|
||||
"need to configure %s.",
|
||||
$this->getEnvConfigLink())));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(
|
||||
pht('Found Binary %s', phutil_tag('tt', array(), $binary)))
|
||||
->setNote(phutil_tag('tt', array(), $where)));
|
||||
}
|
||||
}
|
||||
|
||||
// This gets checked generically above. However, for svn commit hooks, we
|
||||
// need this to be in environment.append-paths because subversion strips
|
||||
// PATH.
|
||||
if ($svnlook_check) {
|
||||
$where = Filesystem::resolveBinary('svnlook');
|
||||
if ($where) {
|
||||
$path = substr($where, 0, strlen($where) - strlen('svnlook'));
|
||||
$dirs = PhabricatorEnv::getEnvConfig('environment.append-paths');
|
||||
$in_path = false;
|
||||
foreach ($dirs as $dir) {
|
||||
if (Filesystem::isDescendant($path, $dir)) {
|
||||
$in_path = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$in_path) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(
|
||||
pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
|
||||
->setNote(pht(
|
||||
'Unable to find this binary in `%s`. '.
|
||||
'You need to configure %s and include %s.',
|
||||
'environment.append-paths',
|
||||
$this->getEnvConfigLink(),
|
||||
$path)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$doc_href = PhabricatorEnv::getDoclink('Managing Daemons with phd');
|
||||
|
||||
$daemon_instructions = pht(
|
||||
'Use %s to start daemons. See %s.',
|
||||
phutil_tag('tt', array(), 'bin/phd start'),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $doc_href,
|
||||
),
|
||||
pht('Managing Daemons with phd')));
|
||||
|
||||
|
||||
$pull_daemon = id(new PhabricatorDaemonLogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||
->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon'))
|
||||
->setLimit(1)
|
||||
->execute();
|
||||
|
||||
if ($pull_daemon) {
|
||||
|
||||
// TODO: In a cluster environment, we need a daemon on this repository's
|
||||
// host, specifically, and we aren't checking for that right now. This
|
||||
// is a reasonable proxy for things being more-or-less correctly set up,
|
||||
// though.
|
||||
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Pull Daemon Running')));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Pull Daemon Not Running'))
|
||||
->setNote($daemon_instructions));
|
||||
}
|
||||
|
||||
|
||||
$task_daemon = id(new PhabricatorDaemonLogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||
->withDaemonClasses(array('PhabricatorTaskmasterDaemon'))
|
||||
->setLimit(1)
|
||||
->execute();
|
||||
if ($task_daemon) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Task Daemon Running')));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Task Daemon Not Running'))
|
||||
->setNote($daemon_instructions));
|
||||
}
|
||||
|
||||
|
||||
if ($is_cluster) {
|
||||
// Just omit this status check for now in cluster environments. We
|
||||
// could make a service call and pull it from the repository host
|
||||
// eventually.
|
||||
} else if ($repository->usesLocalWorkingCopy()) {
|
||||
$local_parent = dirname($repository->getLocalPath());
|
||||
if (Filesystem::pathExists($local_parent)) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Storage Directory OK'))
|
||||
->setNote(phutil_tag('tt', array(), $local_parent)));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('No Storage Directory'))
|
||||
->setNote(
|
||||
pht(
|
||||
'Storage directory %s does not exist, or is not readable by '.
|
||||
'the webserver. Create this directory or make it readable.',
|
||||
phutil_tag('tt', array(), $local_parent))));
|
||||
return $view;
|
||||
}
|
||||
|
||||
$local_path = $repository->getLocalPath();
|
||||
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT);
|
||||
if ($message) {
|
||||
switch ($message->getStatusCode()) {
|
||||
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Initialization Error'))
|
||||
->setNote($message->getParameter('message')));
|
||||
return $view;
|
||||
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
|
||||
if (Filesystem::pathExists($local_path)) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Working Copy OK'))
|
||||
->setNote(phutil_tag('tt', array(), $local_path)));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Working Copy Error'))
|
||||
->setNote(
|
||||
pht(
|
||||
'Working copy %s has been deleted, or is not '.
|
||||
'readable by the webserver. Make this directory '.
|
||||
'readable. If it has been deleted, the daemons should '.
|
||||
'restore it automatically.',
|
||||
phutil_tag('tt', array(), $local_path))));
|
||||
return $view;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
|
||||
->setTarget(pht('Initializing Working Copy'))
|
||||
->setNote(pht('Daemons are initializing the working copy.')));
|
||||
return $view;
|
||||
}
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
|
||||
->setTarget(pht('No Working Copy Yet'))
|
||||
->setNote(
|
||||
pht('Waiting for daemons to build a working copy.')));
|
||||
return $view;
|
||||
}
|
||||
}
|
||||
|
||||
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
|
||||
if ($message) {
|
||||
switch ($message->getStatusCode()) {
|
||||
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
|
||||
$message = $message->getParameter('message');
|
||||
|
||||
$suggestion = null;
|
||||
if (preg_match('/Permission denied \(publickey\)./', $message)) {
|
||||
$suggestion = pht(
|
||||
'Public Key Error: This error usually indicates that the '.
|
||||
'keypair you have configured does not have permission to '.
|
||||
'access the repository.');
|
||||
}
|
||||
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Update Error'))
|
||||
->setNote($suggestion));
|
||||
return $view;
|
||||
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
|
||||
$ago = (PhabricatorTime::getNow() - $message->getEpoch());
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Updates OK'))
|
||||
->setNote(
|
||||
pht(
|
||||
'Last updated %s (%s ago).',
|
||||
phabricator_datetime($message->getEpoch(), $viewer),
|
||||
phutil_format_relative_time_detailed($ago))));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
|
||||
->setTarget(pht('Waiting For Update'))
|
||||
->setNote(
|
||||
pht('Waiting for daemons to read updates.')));
|
||||
}
|
||||
|
||||
if ($repository->isImporting()) {
|
||||
$ratio = $repository->loadImportProgress();
|
||||
$percentage = sprintf('%.2f%%', 100 * $ratio);
|
||||
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
|
||||
->setTarget(pht('Importing'))
|
||||
->setNote(
|
||||
pht('%s Complete', $percentage)));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Fully Imported')));
|
||||
}
|
||||
|
||||
if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_UP, 'indigo')
|
||||
->setTarget(pht('Prioritized'))
|
||||
->setNote(pht('This repository will be updated soon!')));
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildRepositoryRawError(
|
||||
PhabricatorRepository $repository,
|
||||
array $messages) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$raw_error = null;
|
||||
|
||||
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
|
||||
if ($message) {
|
||||
switch ($message->getStatusCode()) {
|
||||
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
|
||||
$raw_error = $message->getParameter('message');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($raw_error !== null) {
|
||||
if (!$can_edit) {
|
||||
$raw_message = pht(
|
||||
'You must be able to edit a repository to see raw error messages '.
|
||||
'because they sometimes disclose sensitive information.');
|
||||
$raw_message = phutil_tag('em', array(), $raw_message);
|
||||
} else {
|
||||
$raw_message = phutil_escape_html_newlines($raw_error);
|
||||
}
|
||||
} else {
|
||||
$raw_message = null;
|
||||
}
|
||||
|
||||
return $raw_message;
|
||||
}
|
||||
|
||||
private function loadStatusMessages(PhabricatorRepository $repository) {
|
||||
$messages = id(new PhabricatorRepositoryStatusMessage())
|
||||
->loadAllWhere('repositoryID = %d', $repository->getID());
|
||||
$messages = mpull($messages, null, 'getStatusType');
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
private function getEnvConfigLink() {
|
||||
$config_href = '/config/edit/environment.append-paths/';
|
||||
return phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $config_href,
|
||||
),
|
||||
'environment.append-paths');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,18 +19,7 @@ final class DiffusionRepositoryBranchesManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
$has_any =
|
||||
$repository->getDetail('default-branch') ||
|
||||
$repository->getDetail('branch-filter') ||
|
||||
$repository->getDetail('close-commits-filter');
|
||||
|
||||
if ($has_any) {
|
||||
return 'fa-code-fork';
|
||||
} else {
|
||||
return 'fa-code-fork grey';
|
||||
}
|
||||
return 'fa-code-fork';
|
||||
}
|
||||
|
||||
protected function getEditEngineFieldKeys() {
|
||||
|
@ -41,29 +30,6 @@ final class DiffusionRepositoryBranchesManagementPanel
|
|||
);
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$branches_uri = $this->getEditPageURI();
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Branches'))
|
||||
->setHref($branches_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -94,7 +60,23 @@ final class DiffusionRepositoryBranchesManagementPanel
|
|||
}
|
||||
|
||||
$view->addProperty(pht('Autoclose Only'), $autoclose_only);
|
||||
$content[] = $this->newBox(pht('Branches'), $view);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$branches_uri = $this->getEditPageURI();
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-pencil')
|
||||
->setText(pht('Edit'))
|
||||
->setHref($branches_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
$content[] = $this->newBox(pht('Branches'), $view, array($button));
|
||||
|
||||
// Branch Autoclose Table
|
||||
if (!$repository->isImporting()) {
|
||||
|
@ -176,11 +158,8 @@ final class DiffusionRepositoryBranchesManagementPanel
|
|||
true,
|
||||
));
|
||||
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeaderText(pht('Branch Status'))
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
->setTable($branch_table)
|
||||
->setPager($pager);
|
||||
$box = $this->newBox(pht('Branch Status'), $branch_table);
|
||||
$box->setPager($pager);
|
||||
$content[] = $box;
|
||||
} else {
|
||||
$content[] = id(new PHUIInfoView())
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryDocumentationManagementPanel
|
||||
extends DiffusionRepositoryManagementPanel {
|
||||
|
||||
const PANELKEY = 'documentation';
|
||||
|
||||
public function getManagementPanelLabel() {
|
||||
return pht('Documentation');
|
||||
}
|
||||
|
||||
public function getManagementPanelOrder() {
|
||||
return 3000;
|
||||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
return 'fa-book';
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPanelNavigationURI() {
|
||||
return PhabricatorEnv::getDoclink(
|
||||
'Diffusion User Guide: Managing Repositories');
|
||||
}
|
||||
|
||||
}
|
|
@ -21,8 +21,4 @@ final class DiffusionRepositoryHistoryManagementPanel
|
|||
return $this->newTimeline();
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,6 @@ abstract class DiffusionRepositoryManagementPanel
|
|||
abstract public function getManagementPanelLabel();
|
||||
abstract public function getManagementPanelOrder();
|
||||
abstract public function buildManagementPanelContent();
|
||||
abstract public function buildManagementPanelCurtain();
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
return 'fa-pencil';
|
||||
|
@ -56,22 +55,6 @@ abstract class DiffusionRepositoryManagementPanel
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getNewActionList() {
|
||||
$viewer = $this->getViewer();
|
||||
$action_id = celerity_generate_unique_node_id();
|
||||
|
||||
return id(new PhabricatorActionListView())
|
||||
->setViewer($viewer)
|
||||
->setID($action_id);
|
||||
}
|
||||
|
||||
public function getNewCurtainView(PhabricatorActionListView $action_list) {
|
||||
$viewer = $this->getViewer();
|
||||
return id(new PHUICurtainView())
|
||||
->setViewer($viewer)
|
||||
->setActionList($action_list);
|
||||
}
|
||||
|
||||
public static function getAllPanels() {
|
||||
return id(new PhutilClassMapQuery())
|
||||
->setAncestorClass(__CLASS__)
|
||||
|
@ -80,11 +63,20 @@ abstract class DiffusionRepositoryManagementPanel
|
|||
->execute();
|
||||
}
|
||||
|
||||
final protected function newBox($header_text, $body) {
|
||||
return id(new PHUIObjectBoxView())
|
||||
->setHeaderText($header_text)
|
||||
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
|
||||
final protected function newBox($header_text, $body, $button = array()) {
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader($header_text);
|
||||
|
||||
foreach ($button as $link) {
|
||||
$header->addActionLink($link);
|
||||
}
|
||||
|
||||
$view = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->setBackground(PHUIObjectBoxView::WHITE_CONFIG)
|
||||
->appendChild($body);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
final protected function newTimeline() {
|
||||
|
|
|
@ -14,35 +14,7 @@ final class DiffusionRepositoryPoliciesManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$viewer = $this->getViewer();
|
||||
$repository = $this->getRepository();
|
||||
|
||||
$can_view = PhabricatorPolicyCapability::CAN_VIEW;
|
||||
$can_edit = PhabricatorPolicyCapability::CAN_EDIT;
|
||||
$can_push = DiffusionPushCapability::CAPABILITY;
|
||||
|
||||
$actual_values = array(
|
||||
'spacePHID' => $repository->getSpacePHID(),
|
||||
'view' => $repository->getPolicy($can_view),
|
||||
'edit' => $repository->getPolicy($can_edit),
|
||||
'push' => $repository->getPolicy($can_push),
|
||||
);
|
||||
|
||||
$default = PhabricatorRepository::initializeNewRepository(
|
||||
$viewer);
|
||||
|
||||
$default_values = array(
|
||||
'spacePHID' => $default->getSpacePHID(),
|
||||
'view' => $default->getPolicy($can_view),
|
||||
'edit' => $default->getPolicy($can_edit),
|
||||
'push' => $default->getPolicy($can_push),
|
||||
);
|
||||
|
||||
if ($actual_values === $default_values) {
|
||||
return 'fa-lock grey';
|
||||
} else {
|
||||
return 'fa-lock';
|
||||
}
|
||||
return 'fa-lock';
|
||||
}
|
||||
|
||||
protected function getEditEngineFieldKeys() {
|
||||
|
@ -54,29 +26,6 @@ final class DiffusionRepositoryPoliciesManagementPanel
|
|||
);
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$edit_uri = $this->getEditPageURI();
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Policies'))
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -109,7 +58,22 @@ final class DiffusionRepositoryPoliciesManagementPanel
|
|||
: phutil_tag('em', array(), pht('Not a Hosted Repository'));
|
||||
$view->addProperty(pht('Pushable By'), $pushable);
|
||||
|
||||
return $this->newBox(pht('Policies'), $view);
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$edit_uri = $this->getEditPageURI();
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-pencil')
|
||||
->setText(pht('Edit'))
|
||||
->setHref($edit_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
return $this->newBox(pht('Policies'), $view, array($button));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,15 +20,7 @@ final class DiffusionRepositoryStagingManagementPanel
|
|||
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
$staging_uri = $repository->getStagingURI();
|
||||
|
||||
if ($staging_uri) {
|
||||
return 'fa-upload';
|
||||
} else {
|
||||
return 'fa-upload grey';
|
||||
}
|
||||
return 'fa-upload';
|
||||
}
|
||||
|
||||
protected function getEditEngineFieldKeys() {
|
||||
|
@ -37,29 +29,6 @@ final class DiffusionRepositoryStagingManagementPanel
|
|||
);
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$staging_uri = $this->getEditPageURI();
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Staging'))
|
||||
->setHref($staging_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -74,7 +43,22 @@ final class DiffusionRepositoryStagingManagementPanel
|
|||
|
||||
$view->addProperty(pht('Staging Area URI'), $staging_uri);
|
||||
|
||||
return $this->newBox(pht('Staging Area'), $view);
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$staging_uri = $this->getEditPageURI();
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-pencil')
|
||||
->setText(pht('Edit'))
|
||||
->setHref($staging_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
return $this->newBox(pht('Staging Area'), $view, array($button));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,507 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryStatusManagementPanel
|
||||
extends DiffusionRepositoryManagementPanel {
|
||||
|
||||
const PANELKEY = 'status';
|
||||
|
||||
public function getManagementPanelLabel() {
|
||||
return pht('Status');
|
||||
}
|
||||
|
||||
public function getManagementPanelOrder() {
|
||||
return 200;
|
||||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
// TODO: We could try to show a warning icon in more cases, but just
|
||||
// raise in the most serious cases for now.
|
||||
$messages = $this->loadStatusMessages($repository);
|
||||
|
||||
$raw_error = $this->buildRepositoryRawError($repository, $messages);
|
||||
if ($raw_error) {
|
||||
return 'fa-exclamation-triangle red';
|
||||
}
|
||||
|
||||
return 'fa-check grey';
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$update_uri = $repository->getPathURI('edit/update/');
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-refresh')
|
||||
->setName(pht('Update Now'))
|
||||
->setWorkflow(true)
|
||||
->setDisabled(!$can_edit)
|
||||
->setHref($update_uri));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$view = id(new PHUIPropertyListView())
|
||||
->setViewer($viewer);
|
||||
|
||||
$view->addProperty(
|
||||
pht('Update Frequency'),
|
||||
$this->buildRepositoryUpdateInterval($repository));
|
||||
|
||||
$messages = $this->loadStatusMessages($repository);
|
||||
|
||||
$status = $this->buildRepositoryStatus($repository, $messages);
|
||||
$raw_error = $this->buildRepositoryRawError($repository, $messages);
|
||||
|
||||
$view->addProperty(pht('Status'), $status);
|
||||
if ($raw_error) {
|
||||
$view->addSectionHeader(pht('Raw Error'));
|
||||
$view->addTextContent($raw_error);
|
||||
}
|
||||
|
||||
return $this->newBox(pht('Status'), $view);
|
||||
}
|
||||
|
||||
private function buildRepositoryUpdateInterval(
|
||||
PhabricatorRepository $repository) {
|
||||
|
||||
$smart_wait = $repository->loadUpdateInterval();
|
||||
|
||||
$doc_href = PhabricatorEnv::getDoclink(
|
||||
'Diffusion User Guide: Repository Updates');
|
||||
|
||||
return array(
|
||||
phutil_format_relative_time_detailed($smart_wait),
|
||||
" \xC2\xB7 ",
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $doc_href,
|
||||
'target' => '_blank',
|
||||
),
|
||||
pht('Learn More')),
|
||||
);
|
||||
}
|
||||
|
||||
private function buildRepositoryStatus(
|
||||
PhabricatorRepository $repository,
|
||||
array $messages) {
|
||||
|
||||
$viewer = $this->getViewer();
|
||||
$is_cluster = $repository->getAlmanacServicePHID();
|
||||
|
||||
$view = new PHUIStatusListView();
|
||||
|
||||
if ($repository->isTracked()) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Repository Active')));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey')
|
||||
->setTarget(pht('Repository Inactive'))
|
||||
->setNote(
|
||||
pht('Activate this repository to begin or resume import.')));
|
||||
return $view;
|
||||
}
|
||||
|
||||
$binaries = array();
|
||||
$svnlook_check = false;
|
||||
switch ($repository->getVersionControlSystem()) {
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||
$binaries[] = 'git';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
||||
$binaries[] = 'svn';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
||||
$binaries[] = 'hg';
|
||||
break;
|
||||
}
|
||||
|
||||
if ($repository->isHosted()) {
|
||||
$proto_https = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS;
|
||||
$proto_http = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP;
|
||||
$can_http = $repository->canServeProtocol($proto_http, false) ||
|
||||
$repository->canServeProtocol($proto_https, false);
|
||||
|
||||
if ($can_http) {
|
||||
switch ($repository->getVersionControlSystem()) {
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||
$binaries[] = 'git-http-backend';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
||||
$binaries[] = 'svnserve';
|
||||
$binaries[] = 'svnadmin';
|
||||
$binaries[] = 'svnlook';
|
||||
$svnlook_check = true;
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
||||
$binaries[] = 'hg';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$proto_ssh = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH;
|
||||
$can_ssh = $repository->canServeProtocol($proto_ssh, false);
|
||||
|
||||
if ($can_ssh) {
|
||||
switch ($repository->getVersionControlSystem()) {
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
|
||||
$binaries[] = 'git-receive-pack';
|
||||
$binaries[] = 'git-upload-pack';
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
|
||||
$binaries[] = 'svnserve';
|
||||
$binaries[] = 'svnadmin';
|
||||
$binaries[] = 'svnlook';
|
||||
$svnlook_check = true;
|
||||
break;
|
||||
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
|
||||
$binaries[] = 'hg';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$binaries = array_unique($binaries);
|
||||
if (!$is_cluster) {
|
||||
// We're only checking for binaries if we aren't running with a cluster
|
||||
// configuration. In theory, we could check for binaries on the
|
||||
// repository host machine, but we'd need to make this more complicated
|
||||
// to do that.
|
||||
|
||||
foreach ($binaries as $binary) {
|
||||
$where = Filesystem::resolveBinary($binary);
|
||||
if (!$where) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(
|
||||
pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
|
||||
->setNote(pht(
|
||||
"Unable to find this binary in the webserver's PATH. You may ".
|
||||
"need to configure %s.",
|
||||
$this->getEnvConfigLink())));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(
|
||||
pht('Found Binary %s', phutil_tag('tt', array(), $binary)))
|
||||
->setNote(phutil_tag('tt', array(), $where)));
|
||||
}
|
||||
}
|
||||
|
||||
// This gets checked generically above. However, for svn commit hooks, we
|
||||
// need this to be in environment.append-paths because subversion strips
|
||||
// PATH.
|
||||
if ($svnlook_check) {
|
||||
$where = Filesystem::resolveBinary('svnlook');
|
||||
if ($where) {
|
||||
$path = substr($where, 0, strlen($where) - strlen('svnlook'));
|
||||
$dirs = PhabricatorEnv::getEnvConfig('environment.append-paths');
|
||||
$in_path = false;
|
||||
foreach ($dirs as $dir) {
|
||||
if (Filesystem::isDescendant($path, $dir)) {
|
||||
$in_path = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$in_path) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(
|
||||
pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
|
||||
->setNote(pht(
|
||||
'Unable to find this binary in `%s`. '.
|
||||
'You need to configure %s and include %s.',
|
||||
'environment.append-paths',
|
||||
$this->getEnvConfigLink(),
|
||||
$path)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$doc_href = PhabricatorEnv::getDoclink('Managing Daemons with phd');
|
||||
|
||||
$daemon_instructions = pht(
|
||||
'Use %s to start daemons. See %s.',
|
||||
phutil_tag('tt', array(), 'bin/phd start'),
|
||||
phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $doc_href,
|
||||
),
|
||||
pht('Managing Daemons with phd')));
|
||||
|
||||
|
||||
$pull_daemon = id(new PhabricatorDaemonLogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||
->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon'))
|
||||
->setLimit(1)
|
||||
->execute();
|
||||
|
||||
if ($pull_daemon) {
|
||||
|
||||
// TODO: In a cluster environment, we need a daemon on this repository's
|
||||
// host, specifically, and we aren't checking for that right now. This
|
||||
// is a reasonable proxy for things being more-or-less correctly set up,
|
||||
// though.
|
||||
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Pull Daemon Running')));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Pull Daemon Not Running'))
|
||||
->setNote($daemon_instructions));
|
||||
}
|
||||
|
||||
|
||||
$task_daemon = id(new PhabricatorDaemonLogQuery())
|
||||
->setViewer(PhabricatorUser::getOmnipotentUser())
|
||||
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
|
||||
->withDaemonClasses(array('PhabricatorTaskmasterDaemon'))
|
||||
->setLimit(1)
|
||||
->execute();
|
||||
if ($task_daemon) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Task Daemon Running')));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Task Daemon Not Running'))
|
||||
->setNote($daemon_instructions));
|
||||
}
|
||||
|
||||
|
||||
if ($is_cluster) {
|
||||
// Just omit this status check for now in cluster environments. We
|
||||
// could make a service call and pull it from the repository host
|
||||
// eventually.
|
||||
} else if ($repository->usesLocalWorkingCopy()) {
|
||||
$local_parent = dirname($repository->getLocalPath());
|
||||
if (Filesystem::pathExists($local_parent)) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Storage Directory OK'))
|
||||
->setNote(phutil_tag('tt', array(), $local_parent)));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('No Storage Directory'))
|
||||
->setNote(
|
||||
pht(
|
||||
'Storage directory %s does not exist, or is not readable by '.
|
||||
'the webserver. Create this directory or make it readable.',
|
||||
phutil_tag('tt', array(), $local_parent))));
|
||||
return $view;
|
||||
}
|
||||
|
||||
$local_path = $repository->getLocalPath();
|
||||
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT);
|
||||
if ($message) {
|
||||
switch ($message->getStatusCode()) {
|
||||
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Initialization Error'))
|
||||
->setNote($message->getParameter('message')));
|
||||
return $view;
|
||||
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
|
||||
if (Filesystem::pathExists($local_path)) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Working Copy OK'))
|
||||
->setNote(phutil_tag('tt', array(), $local_path)));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Working Copy Error'))
|
||||
->setNote(
|
||||
pht(
|
||||
'Working copy %s has been deleted, or is not '.
|
||||
'readable by the webserver. Make this directory '.
|
||||
'readable. If it has been deleted, the daemons should '.
|
||||
'restore it automatically.',
|
||||
phutil_tag('tt', array(), $local_path))));
|
||||
return $view;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
|
||||
->setTarget(pht('Initializing Working Copy'))
|
||||
->setNote(pht('Daemons are initializing the working copy.')));
|
||||
return $view;
|
||||
}
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
|
||||
->setTarget(pht('No Working Copy Yet'))
|
||||
->setNote(
|
||||
pht('Waiting for daemons to build a working copy.')));
|
||||
return $view;
|
||||
}
|
||||
}
|
||||
|
||||
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
|
||||
if ($message) {
|
||||
switch ($message->getStatusCode()) {
|
||||
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
|
||||
$message = $message->getParameter('message');
|
||||
|
||||
$suggestion = null;
|
||||
if (preg_match('/Permission denied \(publickey\)./', $message)) {
|
||||
$suggestion = pht(
|
||||
'Public Key Error: This error usually indicates that the '.
|
||||
'keypair you have configured does not have permission to '.
|
||||
'access the repository.');
|
||||
}
|
||||
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
|
||||
->setTarget(pht('Update Error'))
|
||||
->setNote($suggestion));
|
||||
return $view;
|
||||
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
|
||||
$ago = (PhabricatorTime::getNow() - $message->getEpoch());
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Updates OK'))
|
||||
->setNote(
|
||||
pht(
|
||||
'Last updated %s (%s ago).',
|
||||
phabricator_datetime($message->getEpoch(), $viewer),
|
||||
phutil_format_relative_time_detailed($ago))));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
|
||||
->setTarget(pht('Waiting For Update'))
|
||||
->setNote(
|
||||
pht('Waiting for daemons to read updates.')));
|
||||
}
|
||||
|
||||
if ($repository->isImporting()) {
|
||||
$ratio = $repository->loadImportProgress();
|
||||
$percentage = sprintf('%.2f%%', 100 * $ratio);
|
||||
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
|
||||
->setTarget(pht('Importing'))
|
||||
->setNote(
|
||||
pht('%s Complete', $percentage)));
|
||||
} else {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
|
||||
->setTarget(pht('Fully Imported')));
|
||||
}
|
||||
|
||||
if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) {
|
||||
$view->addItem(
|
||||
id(new PHUIStatusItemView())
|
||||
->setIcon(PHUIStatusItemView::ICON_UP, 'indigo')
|
||||
->setTarget(pht('Prioritized'))
|
||||
->setNote(pht('This repository will be updated soon!')));
|
||||
}
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
private function buildRepositoryRawError(
|
||||
PhabricatorRepository $repository,
|
||||
array $messages) {
|
||||
$viewer = $this->getViewer();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$raw_error = null;
|
||||
|
||||
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
|
||||
if ($message) {
|
||||
switch ($message->getStatusCode()) {
|
||||
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
|
||||
$raw_error = $message->getParameter('message');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($raw_error !== null) {
|
||||
if (!$can_edit) {
|
||||
$raw_message = pht(
|
||||
'You must be able to edit a repository to see raw error messages '.
|
||||
'because they sometimes disclose sensitive information.');
|
||||
$raw_message = phutil_tag('em', array(), $raw_message);
|
||||
} else {
|
||||
$raw_message = phutil_escape_html_newlines($raw_error);
|
||||
}
|
||||
} else {
|
||||
$raw_message = null;
|
||||
}
|
||||
|
||||
return $raw_message;
|
||||
}
|
||||
|
||||
private function loadStatusMessages(PhabricatorRepository $repository) {
|
||||
$messages = id(new PhabricatorRepositoryStatusMessage())
|
||||
->loadAllWhere('repositoryID = %d', $repository->getID());
|
||||
$messages = mpull($messages, null, 'getStatusType');
|
||||
|
||||
return $messages;
|
||||
}
|
||||
|
||||
private function getEnvConfigLink() {
|
||||
$config_href = '/config/edit/environment.append-paths/';
|
||||
return phutil_tag(
|
||||
'a',
|
||||
array(
|
||||
'href' => $config_href,
|
||||
),
|
||||
'environment.append-paths');
|
||||
}
|
||||
|
||||
}
|
|
@ -14,31 +14,7 @@ final class DiffusionRepositoryStorageManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
if ($repository->getAlmanacServicePHID()) {
|
||||
return 'fa-sitemap';
|
||||
} else if ($repository->isHosted()) {
|
||||
return 'fa-folder';
|
||||
} else {
|
||||
return 'fa-download';
|
||||
}
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories');
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-book')
|
||||
->setHref($doc_href)
|
||||
->setName(pht('Cluster Documentation')));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
return 'fa-database';
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
|
@ -71,9 +47,15 @@ final class DiffusionRepositoryStorageManagementPanel
|
|||
$view->addProperty(pht('Storage Path'), $storage_path);
|
||||
$view->addProperty(pht('Storage Cluster'), $storage_service);
|
||||
|
||||
$box = $this->newBox(pht('Storage'), null);
|
||||
$box->addPropertyList($view);
|
||||
return $box;
|
||||
$doc_href = PhabricatorEnv::getDoclink('Cluster: Repositories');
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-book')
|
||||
->setHref($doc_href)
|
||||
->setText(pht('Help'));
|
||||
|
||||
return $this->newBox(pht('Storage'), $view, array($button));
|
||||
}
|
||||
|
||||
private function buildClusterStatusPanel() {
|
||||
|
@ -243,9 +225,7 @@ final class DiffusionRepositoryStorageManagementPanel
|
|||
'date',
|
||||
));
|
||||
|
||||
$box = $this->newBox(pht('Cluster Status'), null);
|
||||
$box->setTable($table);
|
||||
return $box;
|
||||
return $this->newBox(pht('Cluster Status'), $table);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,15 +19,7 @@ final class DiffusionRepositorySubversionManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
$has_any = (bool)$repository->getDetail('svn-subpath');
|
||||
|
||||
if ($has_any) {
|
||||
return 'fa-database';
|
||||
} else {
|
||||
return 'fa-database grey';
|
||||
}
|
||||
return 'fa-folder';
|
||||
}
|
||||
|
||||
protected function getEditEngineFieldKeys() {
|
||||
|
@ -36,29 +28,6 @@ final class DiffusionRepositorySubversionManagementPanel
|
|||
);
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$subversion_uri = $this->getEditPageURI();
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Properties'))
|
||||
->setHref($subversion_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -71,8 +40,22 @@ final class DiffusionRepositorySubversionManagementPanel
|
|||
phutil_tag('em', array(), pht('Import Entire Repository')));
|
||||
$view->addProperty(pht('Import Only'), $default_branch);
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
return $this->newBox(pht('Subversion'), $view);
|
||||
$subversion_uri = $this->getEditPageURI();
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-pencil')
|
||||
->setText(pht('Edit'))
|
||||
->setHref($subversion_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
return $this->newBox(pht('Subversion'), $view, array($button));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,17 +14,7 @@ final class DiffusionRepositorySymbolsManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
$repository = $this->getRepository();
|
||||
|
||||
$has_any =
|
||||
$repository->getSymbolLanguages() ||
|
||||
$repository->getSymbolSources();
|
||||
|
||||
if ($has_any) {
|
||||
return 'fa-link';
|
||||
} else {
|
||||
return 'fa-link grey';
|
||||
}
|
||||
return 'fa-bullseye';
|
||||
}
|
||||
|
||||
protected function getEditEngineFieldKeys() {
|
||||
|
@ -34,29 +24,6 @@ final class DiffusionRepositorySymbolsManagementPanel
|
|||
);
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$symbols_uri = $this->getEditPageURI();
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-pencil')
|
||||
->setName(pht('Edit Symbols'))
|
||||
->setHref($symbols_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -80,7 +47,22 @@ final class DiffusionRepositorySymbolsManagementPanel
|
|||
}
|
||||
$view->addProperty(pht('Uses Symbols From'), $sources);
|
||||
|
||||
return $this->newBox(pht('Symbols'), $view);
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$symbols_uri = $this->getEditPageURI();
|
||||
|
||||
$button = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-pencil')
|
||||
->setText(pht('Edit'))
|
||||
->setHref($symbols_uri)
|
||||
->setDisabled(!$can_edit)
|
||||
->setWorkflow(!$can_edit);
|
||||
|
||||
return $this->newBox(pht('Symbols'), $view, array($button));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,42 +10,13 @@ final class DiffusionRepositoryURIsManagementPanel
|
|||
}
|
||||
|
||||
public function getManagementPanelIcon() {
|
||||
return 'fa-cogs';
|
||||
return 'fa-globe';
|
||||
}
|
||||
|
||||
public function getManagementPanelOrder() {
|
||||
return 400;
|
||||
}
|
||||
|
||||
public function buildManagementPanelCurtain() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
$action_list = $this->getNewActionList();
|
||||
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
$doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: URIs');
|
||||
$add_href = $repository->getPathURI('uri/edit/');
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-plus')
|
||||
->setHref($add_href)
|
||||
->setDisabled(!$can_edit)
|
||||
->setName(pht('Add New URI')));
|
||||
|
||||
$action_list->addAction(
|
||||
id(new PhabricatorActionView())
|
||||
->setIcon('fa-book')
|
||||
->setHref($doc_href)
|
||||
->setName(pht('URI Documentation')));
|
||||
|
||||
return $this->getNewCurtainView($action_list);
|
||||
}
|
||||
|
||||
public function buildManagementPanelContent() {
|
||||
$repository = $this->getRepository();
|
||||
$viewer = $this->getViewer();
|
||||
|
@ -151,10 +122,30 @@ final class DiffusionRepositoryURIsManagementPanel
|
|||
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
|
||||
->setErrors($messages);
|
||||
|
||||
$box = $this->newBox(pht('Repository URIs'), null);
|
||||
$box->setTable($table);
|
||||
$can_edit = PhabricatorPolicyFilter::hasCapability(
|
||||
$viewer,
|
||||
$repository,
|
||||
PhabricatorPolicyCapability::CAN_EDIT);
|
||||
|
||||
return array($info_view, $box);
|
||||
$doc_href = PhabricatorEnv::getDoclink('Diffusion User Guide: URIs');
|
||||
$add_href = $repository->getPathURI('uri/edit/');
|
||||
|
||||
$add = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-plus')
|
||||
->setHref($add_href)
|
||||
->setDisabled(!$can_edit)
|
||||
->setText(pht('New URI'));
|
||||
|
||||
$help = id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setIcon('fa-book')
|
||||
->setHref($doc_href)
|
||||
->setText(pht('Help'));
|
||||
|
||||
$box = $this->newBox(pht('Repository URIs'), $table, array($add, $help));
|
||||
|
||||
return array($box, $info_view);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -136,3 +136,8 @@ body .phui-box-blue-property .phui-header-shell + .phui-object-box {
|
|||
.phui-box-white-config .phui-header-header {
|
||||
color: {$bluetext};
|
||||
}
|
||||
|
||||
.phui-box-white-config .phui-header-action-links .button {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
|
|
@ -337,6 +337,10 @@ body .phui-header-shell.phui-bleed-header
|
|||
color: {$blacktext};
|
||||
}
|
||||
|
||||
.phui-profile-header.phui-header-shell .phui-header-header a {
|
||||
color: {$blacktext};
|
||||
}
|
||||
|
||||
.phui-profile-header .phui-header-col3 {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue