Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/conduit/controller/PhabricatorConduitController.php b/src/applications/conduit/controller/PhabricatorConduitController.php
index b29c05f2af..6187421e16 100644
--- a/src/applications/conduit/controller/PhabricatorConduitController.php
+++ b/src/applications/conduit/controller/PhabricatorConduitController.php
@@ -1,281 +1,296 @@
<?php
abstract class PhabricatorConduitController extends PhabricatorController {
protected function buildSideNavView() {
$viewer = $this->getRequest()->getUser();
$nav = new AphrontSideNavFilterView();
$nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
id(new PhabricatorConduitSearchEngine())
->setViewer($viewer)
->addNavigationItems($nav->getMenu());
$nav->addLabel('Logs');
$nav->addFilter('log', pht('Call Logs'));
$nav->selectFilter(null);
return $nav;
}
public function buildApplicationMenu() {
return $this->buildSideNavView()->getMenu();
}
protected function renderExampleBox(ConduitAPIMethod $method, $params) {
$viewer = $this->getViewer();
$arc_example = id(new PHUIPropertyListView())
->addRawContent($this->renderExample($method, 'arc', $params));
$curl_example = id(new PHUIPropertyListView())
->addRawContent($this->renderExample($method, 'curl', $params));
$php_example = id(new PHUIPropertyListView())
->addRawContent($this->renderExample($method, 'php', $params));
$panel_uri = id(new PhabricatorConduitTokensSettingsPanel())
->setViewer($viewer)
->setUser($viewer)
->getPanelURI();
$panel_link = phutil_tag(
'a',
array(
'href' => $panel_uri,
),
pht('Conduit API Tokens'));
$panel_link = phutil_tag('strong', array(), $panel_link);
$messages = array(
pht(
'Use the %s panel in Settings to generate or manage API tokens.',
$panel_link),
);
$info_view = id(new PHUIInfoView())
->setErrors($messages)
->setSeverity(PHUIInfoView::SEVERITY_NOTICE);
+ $tab_group = id(new PHUITabGroupView())
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('arc call-conduit'))
+ ->setKey('arc')
+ ->appendChild($arc_example))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('cURL'))
+ ->setKey('curl')
+ ->appendChild($curl_example))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('PHP'))
+ ->setKey('php')
+ ->appendChild($php_example));
+
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Examples'))
->setInfoView($info_view)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
- ->addPropertyList($arc_example, pht('arc call-conduit'))
- ->addPropertyList($curl_example, pht('cURL'))
- ->addPropertyList($php_example, pht('PHP'));
+ ->addTabGroup($tab_group);
}
private function renderExample(
ConduitAPIMethod $method,
$kind,
$params) {
switch ($kind) {
case 'arc':
$example = $this->buildArcanistExample($method, $params);
break;
case 'php':
$example = $this->buildPHPExample($method, $params);
break;
case 'curl':
$example = $this->buildCURLExample($method, $params);
break;
default:
throw new Exception(pht('Conduit client "%s" is not known.', $kind));
}
return $example;
}
private function buildArcanistExample(
ConduitAPIMethod $method,
$params) {
$parts = array();
$parts[] = '$ echo ';
if ($params === null) {
$parts[] = phutil_tag('strong', array(), '<json-parameters>');
} else {
$params = $this->simplifyParams($params);
$params = id(new PhutilJSON())->encodeFormatted($params);
$params = trim($params);
$params = csprintf('%s', $params);
$parts[] = phutil_tag('strong', array('class' => 'real'), $params);
}
$parts[] = ' | ';
$parts[] = 'arc call-conduit ';
$parts[] = '--conduit-uri ';
$parts[] = phutil_tag(
'strong',
array('class' => 'real'),
PhabricatorEnv::getURI('/'));
$parts[] = ' ';
$parts[] = '--conduit-token ';
$parts[] = phutil_tag('strong', array(), '<conduit-token>');
$parts[] = ' ';
$parts[] = $method->getAPIMethodName();
return $this->renderExampleCode($parts);
}
private function buildPHPExample(
ConduitAPIMethod $method,
$params) {
$parts = array();
$libphutil_path = 'path/to/libphutil/src/__phutil_library_init__.php';
$parts[] = '<?php';
$parts[] = "\n\n";
$parts[] = 'require_once ';
$parts[] = phutil_var_export($libphutil_path, true);
$parts[] = ";\n\n";
$parts[] = '$api_token = "';
$parts[] = phutil_tag('strong', array(), pht('<api-token>'));
$parts[] = "\";\n";
$parts[] = '$api_parameters = ';
if ($params === null) {
$parts[] = 'array(';
$parts[] = phutil_tag('strong', array(), pht('<parameters>'));
$parts[] = ');';
} else {
$params = $this->simplifyParams($params);
$params = phutil_var_export($params, true);
$parts[] = phutil_tag('strong', array('class' => 'real'), $params);
$parts[] = ';';
}
$parts[] = "\n\n";
$parts[] = '$client = new ConduitClient(';
$parts[] = phutil_tag(
'strong',
array('class' => 'real'),
phutil_var_export(PhabricatorEnv::getURI('/'), true));
$parts[] = ");\n";
$parts[] = '$client->setConduitToken($api_token);';
$parts[] = "\n\n";
$parts[] = '$result = $client->callMethodSynchronous(';
$parts[] = phutil_tag(
'strong',
array('class' => 'real'),
phutil_var_export($method->getAPIMethodName(), true));
$parts[] = ', ';
$parts[] = '$api_parameters';
$parts[] = ");\n";
$parts[] = 'print_r($result);';
return $this->renderExampleCode($parts);
}
private function buildCURLExample(
ConduitAPIMethod $method,
$params) {
$call_uri = '/api/'.$method->getAPIMethodName();
$parts = array();
$linebreak = array('\\', phutil_tag('br'), ' ');
$parts[] = '$ curl ';
$parts[] = phutil_tag(
'strong',
array('class' => 'real'),
csprintf('%R', PhabricatorEnv::getURI($call_uri)));
$parts[] = ' ';
$parts[] = $linebreak;
$parts[] = '-d api.token=';
$parts[] = phutil_tag('strong', array(), 'api-token');
$parts[] = ' ';
$parts[] = $linebreak;
if ($params === null) {
$parts[] = '-d ';
$parts[] = phutil_tag('strong', array(), 'param');
$parts[] = '=';
$parts[] = phutil_tag('strong', array(), 'value');
$parts[] = ' ';
$parts[] = $linebreak;
$parts[] = phutil_tag('strong', array(), '...');
} else {
$lines = array();
$params = $this->simplifyParams($params);
foreach ($params as $key => $value) {
$pieces = $this->getQueryStringParts(null, $key, $value);
foreach ($pieces as $piece) {
$lines[] = array(
'-d ',
phutil_tag('strong', array('class' => 'real'), $piece),
);
}
}
$parts[] = phutil_implode_html(array(' ', $linebreak), $lines);
}
return $this->renderExampleCode($parts);
}
private function renderExampleCode($example) {
require_celerity_resource('conduit-api-css');
return phutil_tag(
'div',
array(
'class' => 'PhabricatorMonospaced conduit-api-example-code',
),
$example);
}
private function simplifyParams(array $params) {
foreach ($params as $key => $value) {
if ($value === null) {
unset($params[$key]);
}
}
return $params;
}
private function getQueryStringParts($prefix, $key, $value) {
if ($prefix === null) {
$head = phutil_escape_uri($key);
} else {
$head = $prefix.'['.phutil_escape_uri($key).']';
}
if (!is_array($value)) {
return array(
$head.'='.phutil_escape_uri($value),
);
}
$results = array();
foreach ($value as $subkey => $subvalue) {
$subparts = $this->getQueryStringParts($head, $subkey, $subvalue);
foreach ($subparts as $subpart) {
$results[] = $subpart;
}
}
return $results;
}
}
diff --git a/src/applications/drydock/controller/DrydockLeaseViewController.php b/src/applications/drydock/controller/DrydockLeaseViewController.php
index 7166b0bef6..1583d28df2 100644
--- a/src/applications/drydock/controller/DrydockLeaseViewController.php
+++ b/src/applications/drydock/controller/DrydockLeaseViewController.php
@@ -1,158 +1,173 @@
<?php
final class DrydockLeaseViewController extends DrydockLeaseController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$lease = id(new DrydockLeaseQuery())
->setViewer($viewer)
->withIDs(array($id))
->needUnconsumedCommands(true)
->executeOne();
if (!$lease) {
return new Aphront404Response();
}
$id = $lease->getID();
$lease_uri = $this->getApplicationURI("lease/{$id}/");
$title = pht('Lease %d', $lease->getID());
$header = id(new PHUIHeaderView())
->setHeader($title)
->setHeaderIcon('fa-link');
if ($lease->isReleasing()) {
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
}
$curtain = $this->buildCurtain($lease);
$properties = $this->buildPropertyListView($lease);
$log_query = id(new DrydockLogQuery())
->withLeasePHIDs(array($lease->getPHID()));
$logs = $this->buildLogBox(
$log_query,
$this->getApplicationURI("lease/{$id}/logs/query/all/"));
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb($title, $lease_uri);
$crumbs->setBorder(true);
$locks = $this->buildLocksTab($lease->getPHID());
$commands = $this->buildCommandsTab($lease->getPHID());
+ $tab_group = id(new PHUITabGroupView())
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Properties'))
+ ->setKey('properties')
+ ->appendChild($properties))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Slot Locks'))
+ ->setKey('locks')
+ ->appendChild($locks))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Commands'))
+ ->setKey('commands')
+ ->appendChild($commands));
+
$object_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Properties'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
- ->addPropertyList($properties, pht('Properties'))
- ->addPropertyList($locks, pht('Slot Locks'))
- ->addPropertyList($commands, pht('Commands'));
+ ->addTabGroup($tab_group);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$object_box,
$logs,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$view,
));
}
private function buildCurtain(DrydockLease $lease) {
$viewer = $this->getViewer();
$curtain = $this->newCurtainView($lease);
$id = $lease->getID();
$can_release = $lease->canRelease();
if ($lease->isReleasing()) {
$can_release = false;
}
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$lease,
PhabricatorPolicyCapability::CAN_EDIT);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Release Lease'))
->setIcon('fa-times')
->setHref($this->getApplicationURI("/lease/{$id}/release/"))
->setWorkflow(true)
->setDisabled(!$can_release || !$can_edit));
return $curtain;
}
private function buildPropertyListView(
DrydockLease $lease) {
$viewer = $this->getViewer();
$view = new PHUIPropertyListView();
$view->addProperty(
pht('Status'),
DrydockLeaseStatus::getNameForStatus($lease->getStatus()));
$view->addProperty(
pht('Resource Type'),
$lease->getResourceType());
$owner_phid = $lease->getOwnerPHID();
if ($owner_phid) {
$owner_display = $viewer->renderHandle($owner_phid);
} else {
$owner_display = phutil_tag('em', array(), pht('No Owner'));
}
$view->addProperty(pht('Owner'), $owner_display);
$authorizing_phid = $lease->getAuthorizingPHID();
if ($authorizing_phid) {
$authorizing_display = $viewer->renderHandle($authorizing_phid);
} else {
$authorizing_display = phutil_tag('em', array(), pht('None'));
}
$view->addProperty(pht('Authorized By'), $authorizing_display);
$resource_phid = $lease->getResourcePHID();
if ($resource_phid) {
$resource_display = $viewer->renderHandle($resource_phid);
} else {
$resource_display = phutil_tag('em', array(), pht('No Resource'));
}
$view->addProperty(pht('Resource'), $resource_display);
$until = $lease->getUntil();
if ($until) {
$until_display = phabricator_datetime($until, $viewer);
} else {
$until_display = phutil_tag('em', array(), pht('Never'));
}
$view->addProperty(pht('Expires'), $until_display);
$attributes = $lease->getAttributes();
if ($attributes) {
$view->addSectionHeader(
pht('Attributes'), 'fa-list-ul');
foreach ($attributes as $key => $value) {
$view->addProperty($key, $value);
}
}
return $view;
}
}
diff --git a/src/applications/drydock/controller/DrydockResourceViewController.php b/src/applications/drydock/controller/DrydockResourceViewController.php
index c2ab4337f5..c6771007ba 100644
--- a/src/applications/drydock/controller/DrydockResourceViewController.php
+++ b/src/applications/drydock/controller/DrydockResourceViewController.php
@@ -1,189 +1,205 @@
<?php
final class DrydockResourceViewController extends DrydockResourceController {
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$id = $request->getURIData('id');
$resource = id(new DrydockResourceQuery())
->setViewer($viewer)
->withIDs(array($id))
->needUnconsumedCommands(true)
->executeOne();
if (!$resource) {
return new Aphront404Response();
}
$title = pht(
'Resource %s %s',
$resource->getID(),
$resource->getResourceName());
$header = id(new PHUIHeaderView())
->setUser($viewer)
->setPolicyObject($resource)
->setHeader($title)
->setHeaderIcon('fa-map');
if ($resource->isReleasing()) {
$header->setStatus('fa-exclamation-triangle', 'red', pht('Releasing'));
}
$curtain = $this->buildCurtain($resource);
$properties = $this->buildPropertyListView($resource);
$id = $resource->getID();
$resource_uri = $this->getApplicationURI("resource/{$id}/");
$log_query = id(new DrydockLogQuery())
->withResourcePHIDs(array($resource->getPHID()));
$log_box = $this->buildLogBox(
$log_query,
$this->getApplicationURI("resource/{$id}/logs/query/all/"));
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Resource %d', $resource->getID()));
$crumbs->setBorder(true);
$locks = $this->buildLocksTab($resource->getPHID());
$commands = $this->buildCommandsTab($resource->getPHID());
- $lease_box = $this->buildLeaseBox($resource);
+
+ $tab_group = id(new PHUITabGroupView())
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Properties'))
+ ->setKey('properties')
+ ->appendChild($properties))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Slot Locks'))
+ ->setKey('locks')
+ ->appendChild($locks))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Commands'))
+ ->setKey('commands')
+ ->appendChild($commands));
$object_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Properties'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
- ->addPropertyList($properties, pht('Properties'))
- ->addPropertyList($locks, pht('Slot Locks'))
- ->addPropertyList($commands, pht('Commands'));
+ ->addTabGroup($tab_group);
+
+ $lease_box = $this->buildLeaseBox($resource);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setCurtain($curtain)
->setMainColumn(array(
$object_box,
$lease_box,
$log_box,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild(
array(
$view,
));
}
private function buildCurtain(DrydockResource $resource) {
$viewer = $this->getViewer();
$curtain = $this->newCurtainView($resource);
$can_release = $resource->canRelease();
if ($resource->isReleasing()) {
$can_release = false;
}
$can_edit = PhabricatorPolicyFilter::hasCapability(
$viewer,
$resource,
PhabricatorPolicyCapability::CAN_EDIT);
$uri = '/resource/'.$resource->getID().'/release/';
$uri = $this->getApplicationURI($uri);
$curtain->addAction(
id(new PhabricatorActionView())
->setHref($uri)
->setName(pht('Release Resource'))
->setIcon('fa-times')
->setWorkflow(true)
->setDisabled(!$can_release || !$can_edit));
return $curtain;
}
private function buildPropertyListView(
DrydockResource $resource) {
$viewer = $this->getViewer();
$view = new PHUIPropertyListView();
$status = $resource->getStatus();
$status = DrydockResourceStatus::getNameForStatus($status);
$view->addProperty(
pht('Status'),
$status);
$until = $resource->getUntil();
if ($until) {
$until_display = phabricator_datetime($until, $viewer);
} else {
$until_display = phutil_tag('em', array(), pht('Never'));
}
$view->addProperty(pht('Expires'), $until_display);
$view->addProperty(
pht('Resource Type'),
$resource->getType());
$view->addProperty(
pht('Blueprint'),
$viewer->renderHandle($resource->getBlueprintPHID()));
$attributes = $resource->getAttributes();
if ($attributes) {
$view->addSectionHeader(
pht('Attributes'), 'fa-list-ul');
foreach ($attributes as $key => $value) {
$view->addProperty($key, $value);
}
}
return $view;
}
private function buildLeaseBox(DrydockResource $resource) {
$viewer = $this->getViewer();
$leases = id(new DrydockLeaseQuery())
->setViewer($viewer)
->withResourcePHIDs(array($resource->getPHID()))
->withStatuses(
array(
DrydockLeaseStatus::STATUS_PENDING,
DrydockLeaseStatus::STATUS_ACQUIRED,
DrydockLeaseStatus::STATUS_ACTIVE,
))
->setLimit(100)
->execute();
$id = $resource->getID();
$leases_uri = "resource/{$id}/leases/query/all/";
$leases_uri = $this->getApplicationURI($leases_uri);
$lease_header = id(new PHUIHeaderView())
->setHeader(pht('Active Leases'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setHref($leases_uri)
->setIcon('fa-search')
->setText(pht('View All')));
$lease_list = id(new DrydockLeaseListView())
->setUser($viewer)
->setLeases($leases)
->render()
->setNoDataString(pht('This resource has no active leases.'));
return id(new PHUIObjectBoxView())
->setHeader($lease_header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setObjectList($lease_list);
}
}
diff --git a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
index 6b0e7c1e0d..f78db68149 100644
--- a/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
+++ b/src/applications/harbormaster/controller/HarbormasterBuildViewController.php
@@ -1,643 +1,667 @@
<?php
final class HarbormasterBuildViewController
extends HarbormasterController {
public function handleRequest(AphrontRequest $request) {
$request = $this->getRequest();
$viewer = $request->getUser();
$id = $request->getURIData('id');
$generation = $request->getInt('g');
$build = id(new HarbormasterBuildQuery())
->setViewer($viewer)
->withIDs(array($id))
->executeOne();
if (!$build) {
return new Aphront404Response();
}
require_celerity_resource('harbormaster-css');
$title = pht('Build %d', $id);
$page_header = id(new PHUIHeaderView())
->setHeader($title)
->setUser($viewer)
->setPolicyObject($build)
->setHeaderIcon('fa-cubes');
if ($build->isRestarting()) {
$page_header->setStatus(
'fa-exclamation-triangle', 'red', pht('Restarting'));
} else if ($build->isPausing()) {
$page_header->setStatus(
'fa-exclamation-triangle', 'red', pht('Pausing'));
} else if ($build->isResuming()) {
$page_header->setStatus(
'fa-exclamation-triangle', 'red', pht('Resuming'));
} else if ($build->isAborting()) {
$page_header->setStatus(
'fa-exclamation-triangle', 'red', pht('Aborting'));
}
$curtain = $this->buildCurtainView($build);
$properties = $this->buildPropertyList($build);
$crumbs = $this->buildApplicationCrumbs();
$this->addBuildableCrumb($crumbs, $build->getBuildable());
$crumbs->addTextCrumb($title);
$crumbs->setBorder(true);
if ($generation === null || $generation > $build->getBuildGeneration() ||
$generation < 0) {
$generation = $build->getBuildGeneration();
}
$build_targets = id(new HarbormasterBuildTargetQuery())
->setViewer($viewer)
->needBuildSteps(true)
->withBuildPHIDs(array($build->getPHID()))
->withBuildGenerations(array($generation))
->execute();
if ($build_targets) {
$messages = id(new HarbormasterBuildMessageQuery())
->setViewer($viewer)
->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))
->execute();
$messages = mgroup($messages, 'getBuildTargetPHID');
} else {
$messages = array();
}
if ($build_targets) {
$artifacts = id(new HarbormasterBuildArtifactQuery())
->setViewer($viewer)
->withBuildTargetPHIDs(mpull($build_targets, 'getPHID'))
->execute();
$artifacts = msort($artifacts, 'getArtifactKey');
$artifacts = mgroup($artifacts, 'getBuildTargetPHID');
} else {
$artifacts = array();
}
$targets = array();
foreach ($build_targets as $build_target) {
$header = id(new PHUIHeaderView())
->setHeader($build_target->getName())
->setUser($viewer)
->setHeaderIcon('fa-bullseye');
$target_box = id(new PHUIObjectBoxView())
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setHeader($header);
+ $tab_group = new PHUITabGroupView();
+ $target_box->addTabGroup($tab_group);
+
$property_list = new PHUIPropertyListView();
$target_artifacts = idx($artifacts, $build_target->getPHID(), array());
$links = array();
$type_uri = HarbormasterURIArtifact::ARTIFACTCONST;
foreach ($target_artifacts as $artifact) {
if ($artifact->getArtifactType() == $type_uri) {
$impl = $artifact->getArtifactImplementation();
if ($impl->isExternalLink()) {
$links[] = $impl->renderLink();
}
}
}
if ($links) {
$links = phutil_implode_html(phutil_tag('br'), $links);
$property_list->addProperty(
pht('External Link'),
$links);
}
$status_view = new PHUIStatusListView();
$item = new PHUIStatusItemView();
$status = $build_target->getTargetStatus();
$status_name =
HarbormasterBuildTarget::getBuildTargetStatusName($status);
$icon = HarbormasterBuildTarget::getBuildTargetStatusIcon($status);
$color = HarbormasterBuildTarget::getBuildTargetStatusColor($status);
$item->setTarget($status_name);
$item->setIcon($icon, $color);
$status_view->addItem($item);
$when = array();
$started = $build_target->getDateStarted();
$now = PhabricatorTime::getNow();
if ($started) {
$ended = $build_target->getDateCompleted();
if ($ended) {
$when[] = pht(
'Completed at %s',
phabricator_datetime($started, $viewer));
$duration = ($ended - $started);
if ($duration) {
$when[] = pht(
'Built for %s',
phutil_format_relative_time_detailed($duration));
} else {
$when[] = pht('Built instantly');
}
} else {
$when[] = pht(
'Started at %s',
phabricator_datetime($started, $viewer));
$duration = ($now - $started);
if ($duration) {
$when[] = pht(
'Running for %s',
phutil_format_relative_time_detailed($duration));
}
}
} else {
$created = $build_target->getDateCreated();
$when[] = pht(
'Queued at %s',
phabricator_datetime($started, $viewer));
$duration = ($now - $created);
if ($duration) {
$when[] = pht(
'Waiting for %s',
phutil_format_relative_time_detailed($duration));
}
}
$property_list->addProperty(
pht('When'),
phutil_implode_html(" \xC2\xB7 ", $when));
$property_list->addProperty(pht('Status'), $status_view);
- $target_box->addPropertyList($property_list, pht('Overview'));
+ $tab_group->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Overview'))
+ ->setKey('overview')
+ ->appendChild($property_list));
$step = $build_target->getBuildStep();
if ($step) {
$description = $step->getDescription();
if ($description) {
$description = new PHUIRemarkupView($viewer, $description);
$property_list->addSectionHeader(
pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
$property_list->addTextContent($description);
}
} else {
$target_box->setFormErrors(
array(
pht(
'This build step has since been deleted on the build plan. '.
'Some information may be omitted.'),
));
}
$details = $build_target->getDetails();
$property_list = new PHUIPropertyListView();
foreach ($details as $key => $value) {
$property_list->addProperty($key, $value);
}
- $target_box->addPropertyList($property_list, pht('Configuration'));
+ $tab_group->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Configuration'))
+ ->setKey('configuration')
+ ->appendChild($property_list));
$variables = $build_target->getVariables();
- $property_list = new PHUIPropertyListView();
- $property_list->addRawContent($this->buildProperties($variables));
- $target_box->addPropertyList($property_list, pht('Variables'));
+ $variables_tab = $this->buildProperties($variables);
+ $tab_group->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Variables'))
+ ->setKey('variables')
+ ->appendChild($variables_tab));
$artifacts_tab = $this->buildArtifacts($build_target, $target_artifacts);
- $property_list = new PHUIPropertyListView();
- $property_list->addRawContent($artifacts_tab);
- $target_box->addPropertyList($property_list, pht('Artifacts'));
+ $tab_group->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Artifacts'))
+ ->setKey('artifacts')
+ ->appendChild($artifacts_tab));
$build_messages = idx($messages, $build_target->getPHID(), array());
- $property_list = new PHUIPropertyListView();
- $property_list->addRawContent($this->buildMessages($build_messages));
- $target_box->addPropertyList($property_list, pht('Messages'));
+ $messages_tab = $this->buildMessages($build_messages);
+ $tab_group->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Messages'))
+ ->setKey('messages')
+ ->appendChild($messages_tab));
$property_list = new PHUIPropertyListView();
$property_list->addProperty(
pht('Build Target ID'),
$build_target->getID());
$property_list->addProperty(
pht('Build Target PHID'),
$build_target->getPHID());
- $target_box->addPropertyList($property_list, pht('Metadata'));
+
+ $tab_group->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Metadata'))
+ ->setKey('metadata')
+ ->appendChild($property_list));
$targets[] = $target_box;
$targets[] = $this->buildLog($build, $build_target);
}
$timeline = $this->buildTransactionTimeline(
$build,
new HarbormasterBuildTransactionQuery());
$timeline->setShouldTerminate(true);
$view = id(new PHUITwoColumnView())
->setHeader($page_header)
->setCurtain($curtain)
->setMainColumn(array(
$properties,
$targets,
$timeline,
));
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($view);
}
private function buildArtifacts(
HarbormasterBuildTarget $build_target,
array $artifacts) {
$viewer = $this->getViewer();
$rows = array();
foreach ($artifacts as $artifact) {
$impl = $artifact->getArtifactImplementation();
if ($impl) {
$summary = $impl->renderArtifactSummary($viewer);
$type_name = $impl->getArtifactTypeName();
} else {
$summary = pht('<Unknown Artifact Type>');
$type_name = $artifact->getType();
}
$rows[] = array(
$artifact->getArtifactKey(),
$type_name,
$summary,
);
}
$table = id(new AphrontTableView($rows))
->setNoDataString(pht('This target has no associated artifacts.'))
->setHeaders(
array(
pht('Key'),
pht('Type'),
pht('Summary'),
))
->setColumnClasses(
array(
'pri',
'',
'wide',
));
return $table;
}
private function buildLog(
HarbormasterBuild $build,
HarbormasterBuildTarget $build_target) {
$request = $this->getRequest();
$viewer = $request->getUser();
$limit = $request->getInt('l', 25);
$logs = id(new HarbormasterBuildLogQuery())
->setViewer($viewer)
->withBuildTargetPHIDs(array($build_target->getPHID()))
->execute();
$empty_logs = array();
$log_boxes = array();
foreach ($logs as $log) {
$start = 1;
$lines = preg_split("/\r\n|\r|\n/", $log->getLogText());
if ($limit !== 0) {
$start = count($lines) - $limit;
if ($start >= 1) {
$lines = array_slice($lines, -$limit, $limit);
} else {
$start = 1;
}
}
$id = null;
$is_empty = false;
if (count($lines) === 1 && trim($lines[0]) === '') {
// Prevent Harbormaster from showing empty build logs.
$id = celerity_generate_unique_node_id();
$empty_logs[] = $id;
$is_empty = true;
}
$log_view = new ShellLogView();
$log_view->setLines($lines);
$log_view->setStart($start);
$header = id(new PHUIHeaderView())
->setHeader(pht(
'Build Log %d (%s - %s)',
$log->getID(),
$log->getLogSource(),
$log->getLogType()))
->setSubheader($this->createLogHeader($build, $log))
->setUser($viewer);
$log_box = id(new PHUIObjectBoxView())
->setHeader($header)
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->setForm($log_view);
if ($is_empty) {
$log_box = phutil_tag(
'div',
array(
'style' => 'display: none',
'id' => $id,
),
$log_box);
}
$log_boxes[] = $log_box;
}
if ($empty_logs) {
$hide_id = celerity_generate_unique_node_id();
Javelin::initBehavior('phabricator-reveal-content');
$expand = phutil_tag(
'div',
array(
'id' => $hide_id,
'class' => 'harbormaster-empty-logs-are-hidden',
),
array(
pht(
'%s empty logs are hidden.',
phutil_count($empty_logs)),
' ',
javelin_tag(
'a',
array(
'href' => '#',
'sigil' => 'reveal-content',
'meta' => array(
'showIDs' => $empty_logs,
'hideIDs' => array($hide_id),
),
),
pht('Show all logs.')),
));
array_unshift($log_boxes, $expand);
}
return $log_boxes;
}
private function createLogHeader($build, $log) {
$request = $this->getRequest();
$limit = $request->getInt('l', 25);
$lines_25 = $this->getApplicationURI('/build/'.$build->getID().'/?l=25');
$lines_50 = $this->getApplicationURI('/build/'.$build->getID().'/?l=50');
$lines_100 =
$this->getApplicationURI('/build/'.$build->getID().'/?l=100');
$lines_0 = $this->getApplicationURI('/build/'.$build->getID().'/?l=0');
$link_25 = phutil_tag('a', array('href' => $lines_25), pht('25'));
$link_50 = phutil_tag('a', array('href' => $lines_50), pht('50'));
$link_100 = phutil_tag('a', array('href' => $lines_100), pht('100'));
$link_0 = phutil_tag('a', array('href' => $lines_0), pht('Unlimited'));
if ($limit === 25) {
$link_25 = phutil_tag('strong', array(), $link_25);
} else if ($limit === 50) {
$link_50 = phutil_tag('strong', array(), $link_50);
} else if ($limit === 100) {
$link_100 = phutil_tag('strong', array(), $link_100);
} else if ($limit === 0) {
$link_0 = phutil_tag('strong', array(), $link_0);
}
return phutil_tag(
'span',
array(),
array(
$link_25,
' - ',
$link_50,
' - ',
$link_100,
' - ',
$link_0,
' Lines',
));
}
private function buildCurtainView(HarbormasterBuild $build) {
$viewer = $this->getViewer();
$id = $build->getID();
$curtain = $this->newCurtainView($build);
$can_restart =
$build->canRestartBuild() &&
$build->canIssueCommand(
$viewer,
HarbormasterBuildCommand::COMMAND_RESTART);
$can_pause =
$build->canPauseBuild() &&
$build->canIssueCommand(
$viewer,
HarbormasterBuildCommand::COMMAND_PAUSE);
$can_resume =
$build->canResumeBuild() &&
$build->canIssueCommand(
$viewer,
HarbormasterBuildCommand::COMMAND_RESUME);
$can_abort =
$build->canAbortBuild() &&
$build->canIssueCommand(
$viewer,
HarbormasterBuildCommand::COMMAND_ABORT);
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Restart Build'))
->setIcon('fa-repeat')
->setHref($this->getApplicationURI('/build/restart/'.$id.'/'))
->setDisabled(!$can_restart)
->setWorkflow(true));
if ($build->canResumeBuild()) {
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Resume Build'))
->setIcon('fa-play')
->setHref($this->getApplicationURI('/build/resume/'.$id.'/'))
->setDisabled(!$can_resume)
->setWorkflow(true));
} else {
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Pause Build'))
->setIcon('fa-pause')
->setHref($this->getApplicationURI('/build/pause/'.$id.'/'))
->setDisabled(!$can_pause)
->setWorkflow(true));
}
$curtain->addAction(
id(new PhabricatorActionView())
->setName(pht('Abort Build'))
->setIcon('fa-exclamation-triangle')
->setHref($this->getApplicationURI('/build/abort/'.$id.'/'))
->setDisabled(!$can_abort)
->setWorkflow(true));
return $curtain;
}
private function buildPropertyList(HarbormasterBuild $build) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(array(
$build->getBuildablePHID(),
$build->getBuildPlanPHID(),
))
->execute();
$properties->addProperty(
pht('Buildable'),
$handles[$build->getBuildablePHID()]->renderLink());
$properties->addProperty(
pht('Build Plan'),
$handles[$build->getBuildPlanPHID()]->renderLink());
$properties->addProperty(
pht('Restarts'),
$build->getBuildGeneration());
$properties->addProperty(
pht('Status'),
$this->getStatus($build));
return id(new PHUIObjectBoxView())
->setHeaderText(pht('Properties'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
->appendChild($properties);
}
private function getStatus(HarbormasterBuild $build) {
$status_view = new PHUIStatusListView();
$item = new PHUIStatusItemView();
if ($build->isPausing()) {
$status_name = pht('Pausing');
$icon = PHUIStatusItemView::ICON_RIGHT;
$color = 'dark';
} else {
$status = $build->getBuildStatus();
$status_name =
HarbormasterBuild::getBuildStatusName($status);
$icon = HarbormasterBuild::getBuildStatusIcon($status);
$color = HarbormasterBuild::getBuildStatusColor($status);
}
$item->setTarget($status_name);
$item->setIcon($icon, $color);
$status_view->addItem($item);
return $status_view;
}
private function buildMessages(array $messages) {
$viewer = $this->getRequest()->getUser();
if ($messages) {
$handles = id(new PhabricatorHandleQuery())
->setViewer($viewer)
->withPHIDs(mpull($messages, 'getAuthorPHID'))
->execute();
} else {
$handles = array();
}
$rows = array();
foreach ($messages as $message) {
$rows[] = array(
$message->getID(),
$handles[$message->getAuthorPHID()]->renderLink(),
$message->getType(),
$message->getIsConsumed() ? pht('Consumed') : null,
phabricator_datetime($message->getDateCreated(), $viewer),
);
}
$table = new AphrontTableView($rows);
$table->setNoDataString(pht('No messages for this build target.'));
$table->setHeaders(
array(
pht('ID'),
pht('From'),
pht('Type'),
pht('Consumed'),
pht('Received'),
));
$table->setColumnClasses(
array(
'',
'',
'wide',
'',
'date',
));
return $table;
}
private function buildProperties(array $properties) {
ksort($properties);
$rows = array();
foreach ($properties as $key => $value) {
$rows[] = array(
$key,
$value,
);
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Key'),
pht('Value'),
))
->setColumnClasses(
array(
'pri right',
'wide',
));
return $table;
}
}
diff --git a/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php b/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
index fda471b79f..80da535a9e 100644
--- a/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
+++ b/src/applications/metamta/controller/PhabricatorMetaMTAMailViewController.php
@@ -1,381 +1,400 @@
<?php
final class PhabricatorMetaMTAMailViewController
extends PhabricatorMetaMTAController {
public function handleRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$mail = id(new PhabricatorMetaMTAMailQuery())
->setViewer($viewer)
->withIDs(array($request->getURIData('id')))
->executeOne();
if (!$mail) {
return new Aphront404Response();
}
if ($mail->hasSensitiveContent()) {
$title = pht('Content Redacted');
} else {
$title = $mail->getSubject();
}
$header = id(new PHUIHeaderView())
->setHeader($title)
->setUser($viewer)
->setPolicyObject($mail)
->setHeaderIcon('fa-envelope');
$status = $mail->getStatus();
$name = PhabricatorMailOutboundStatus::getStatusName($status);
$icon = PhabricatorMailOutboundStatus::getStatusIcon($status);
$color = PhabricatorMailOutboundStatus::getStatusColor($status);
$header->setStatus($icon, $color, $name);
$crumbs = $this->buildApplicationCrumbs()
->addTextCrumb(pht('Mail %d', $mail->getID()))
->setBorder(true);
+ $tab_group = id(new PHUITabGroupView())
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Message'))
+ ->setKey('message')
+ ->appendChild($this->buildMessageProperties($mail)))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Headers'))
+ ->setKey('headers')
+ ->appendChild($this->buildHeaderProperties($mail)))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Delivery'))
+ ->setKey('delivery')
+ ->appendChild($this->buildDeliveryProperties($mail)))
+ ->addTab(
+ id(new PHUITabView())
+ ->setName(pht('Metadata'))
+ ->setKey('metadata')
+ ->appendChild($this->buildMetadataProperties($mail)));
+
$object_box = id(new PHUIObjectBoxView())
->setHeaderText(pht('Mail'))
->setBackground(PHUIObjectBoxView::BLUE_PROPERTY)
- ->addPropertyList($this->buildMessageProperties($mail), pht('Message'))
- ->addPropertyList($this->buildHeaderProperties($mail), pht('Headers'))
- ->addPropertyList($this->buildDeliveryProperties($mail), pht('Delivery'))
- ->addPropertyList($this->buildMetadataProperties($mail), pht('Metadata'));
+ ->addTabGroup($tab_group);
$view = id(new PHUITwoColumnView())
->setHeader($header)
->setFooter($object_box);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->setPageObjectPHIDs(array($mail->getPHID()))
->appendChild($view);
}
private function buildMessageProperties(PhabricatorMetaMTAMail $mail) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($mail);
if ($mail->getFrom()) {
$from_str = $viewer->renderHandle($mail->getFrom());
} else {
$from_str = pht('Sent by Phabricator');
}
$properties->addProperty(
pht('From'),
$from_str);
if ($mail->getToPHIDs()) {
$to_list = $viewer->renderHandleList($mail->getToPHIDs());
} else {
$to_list = pht('None');
}
$properties->addProperty(
pht('To'),
$to_list);
if ($mail->getCcPHIDs()) {
$cc_list = $viewer->renderHandleList($mail->getCcPHIDs());
} else {
$cc_list = pht('None');
}
$properties->addProperty(
pht('Cc'),
$cc_list);
$properties->addProperty(
pht('Sent'),
phabricator_datetime($mail->getDateCreated(), $viewer));
$properties->addSectionHeader(
pht('Message'),
PHUIPropertyListView::ICON_SUMMARY);
if ($mail->hasSensitiveContent()) {
$body = phutil_tag(
'em',
array(),
pht(
'The content of this mail is sensitive and it can not be '.
'viewed from the web UI.'));
} else {
$body = phutil_tag(
'div',
array(
'style' => 'white-space: pre-wrap',
),
$mail->getBody());
}
$properties->addTextContent($body);
return $properties;
}
private function buildHeaderProperties(PhabricatorMetaMTAMail $mail) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setStacked(true);
$headers = $mail->getDeliveredHeaders();
if ($headers === null) {
$headers = $mail->generateHeaders();
}
// Sort headers by name.
$headers = isort($headers, 0);
foreach ($headers as $header) {
list($key, $value) = $header;
$properties->addProperty($key, $value);
}
return $properties;
}
private function buildDeliveryProperties(PhabricatorMetaMTAMail $mail) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
$actors = $mail->getDeliveredActors();
$reasons = null;
if (!$actors) {
if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {
$delivery = $this->renderEmptyMessage(
pht(
'This message has not been delivered yet, so delivery information '.
'is not available.'));
} else {
$delivery = $this->renderEmptyMessage(
pht(
'This is an older message that predates recording delivery '.
'information, so none is available.'));
}
} else {
$actor = idx($actors, $viewer->getPHID());
if (!$actor) {
$delivery = phutil_tag(
'em',
array(),
pht('This message was not delivered to you.'));
} else {
$deliverable = $actor['deliverable'];
if ($deliverable) {
$delivery = pht('Delivered');
} else {
$delivery = pht('Voided');
}
$reasons = id(new PHUIStatusListView());
$reason_codes = $actor['reasons'];
if (!$reason_codes) {
$reason_codes = array(
PhabricatorMetaMTAActor::REASON_NONE,
);
}
$icon_yes = 'fa-check green';
$icon_no = 'fa-times red';
foreach ($reason_codes as $reason) {
$target = phutil_tag(
'strong',
array(),
PhabricatorMetaMTAActor::getReasonName($reason));
if (PhabricatorMetaMTAActor::isDeliveryReason($reason)) {
$icon = $icon_yes;
} else {
$icon = $icon_no;
}
$item = id(new PHUIStatusItemView())
->setIcon($icon)
->setTarget($target)
->setNote(PhabricatorMetaMTAActor::getReasonDescription($reason));
$reasons->addItem($item);
}
}
}
$properties->addProperty(pht('Delivery'), $delivery);
if ($reasons) {
$properties->addProperty(pht('Reasons'), $reasons);
$properties->addProperty(
null,
$this->renderEmptyMessage(
pht(
'Delivery reasons are listed from weakest to strongest.')));
}
$properties->addSectionHeader(
pht('Routing Rules'), 'fa-paper-plane-o');
$map = $mail->getDeliveredRoutingMap();
$routing_detail = null;
if ($map === null) {
if ($mail->getStatus() == PhabricatorMailOutboundStatus::STATUS_QUEUE) {
$routing_result = $this->renderEmptyMessage(
pht(
'This message has not been sent yet, so routing rules have '.
'not been computed.'));
} else {
$routing_result = $this->renderEmptyMessage(
pht(
'This is an older message which predates routing rules.'));
}
} else {
$rule = idx($map, $viewer->getPHID());
if ($rule === null) {
$rule = idx($map, 'default');
}
if ($rule === null) {
$routing_result = $this->renderEmptyMessage(
pht(
'No routing rules applied when delivering this message to you.'));
} else {
$rule_const = $rule['rule'];
$reason_phid = $rule['reason'];
switch ($rule_const) {
case PhabricatorMailRoutingRule::ROUTE_AS_NOTIFICATION:
$routing_result = pht(
'This message was routed as a notification because it '.
'matched %s.',
$viewer->renderHandle($reason_phid)->render());
break;
case PhabricatorMailRoutingRule::ROUTE_AS_MAIL:
$routing_result = pht(
'This message was routed as an email because it matched %s.',
$viewer->renderHandle($reason_phid)->render());
break;
default:
$routing_result = pht('Unknown routing rule "%s".', $rule_const);
break;
}
}
$routing_rules = $mail->getDeliveredRoutingRules();
if ($routing_rules) {
$rules = array();
foreach ($routing_rules as $rule) {
$phids = idx($rule, 'phids');
if ($phids === null) {
$rules[] = $rule;
} else if (in_array($viewer->getPHID(), $phids)) {
$rules[] = $rule;
}
}
// Reorder rules by strength.
foreach ($rules as $key => $rule) {
$const = $rule['routingRule'];
$phids = $rule['phids'];
if ($phids === null) {
$type = 'A';
} else {
$type = 'B';
}
$rules[$key]['strength'] = sprintf(
'~%s%08d',
$type,
PhabricatorMailRoutingRule::getRuleStrength($const));
}
$rules = isort($rules, 'strength');
$routing_detail = id(new PHUIStatusListView());
foreach ($rules as $rule) {
$const = $rule['routingRule'];
$phids = $rule['phids'];
$name = PhabricatorMailRoutingRule::getRuleName($const);
$icon = PhabricatorMailRoutingRule::getRuleIcon($const);
$color = PhabricatorMailRoutingRule::getRuleColor($const);
if ($phids === null) {
$kind = pht('Global');
} else {
$kind = pht('Personal');
}
$target = array($kind, ': ', $name);
$target = phutil_tag('strong', array(), $target);
$item = id(new PHUIStatusItemView())
->setTarget($target)
->setNote($viewer->renderHandle($rule['reasonPHID']))
->setIcon($icon, $color);
$routing_detail->addItem($item);
}
}
}
$properties->addProperty(pht('Effective Rule'), $routing_result);
if ($routing_detail !== null) {
$properties->addProperty(pht('All Matching Rules'), $routing_detail);
$properties->addProperty(
null,
$this->renderEmptyMessage(
pht(
'Matching rules are listed from weakest to strongest.')));
}
return $properties;
}
private function buildMetadataProperties(PhabricatorMetaMTAMail $mail) {
$viewer = $this->getViewer();
$properties = id(new PHUIPropertyListView())
->setUser($viewer);
$properties->addProperty(pht('Message PHID'), $mail->getPHID());
$details = $mail->getMessage();
if (!strlen($details)) {
$details = phutil_tag('em', array(), pht('None'));
}
$properties->addProperty(pht('Status Details'), $details);
$actor_phid = $mail->getActorPHID();
if ($actor_phid) {
$actor_str = $viewer->renderHandle($actor_phid);
} else {
$actor_str = pht('Generated by Phabricator');
}
$properties->addProperty(pht('Actor'), $actor_str);
$related_phid = $mail->getRelatedPHID();
if ($related_phid) {
$related = $viewer->renderHandle($mail->getRelatedPHID());
} else {
$related = phutil_tag('em', array(), pht('None'));
}
$properties->addProperty(pht('Related Object'), $related);
return $properties;
}
private function renderEmptyMessage($message) {
return phutil_tag('em', array(), $message);
}
}
diff --git a/src/applications/uiexample/examples/PHUIPropertyListExample.php b/src/applications/uiexample/examples/PHUIPropertyListExample.php
index 76a39774b6..68bc13158b 100644
--- a/src/applications/uiexample/examples/PHUIPropertyListExample.php
+++ b/src/applications/uiexample/examples/PHUIPropertyListExample.php
@@ -1,138 +1,136 @@
<?php
final class PHUIPropertyListExample extends PhabricatorUIExample {
public function getName() {
return pht('Property List');
}
public function getDescription() {
return pht(
'Use %s to render object properties.',
phutil_tag('tt', array(), 'PHUIPropertyListView'));
}
public function renderExample() {
$request = $this->getRequest();
$user = $request->getUser();
- $details1 = id(new PHUIListItemView())
- ->setName(pht('Details'))
- ->setSelected(true);
-
- $details2 = id(new PHUIListItemView())
- ->setName(pht('Rainbow Info'))
- ->setStatusColor(PHUIListItemView::STATUS_WARN);
-
- $details3 = id(new PHUIListItemView())
- ->setName(pht('Pasta Haiku'))
- ->setStatusColor(PHUIListItemView::STATUS_FAIL);
-
- $statustabs = id(new PHUIListView())
- ->setType(PHUIListView::NAVBAR_LIST)
- ->addMenuItem($details1)
- ->addMenuItem($details2)
- ->addMenuItem($details3);
-
$view = new PHUIPropertyListView();
$view->addProperty(
pht('Color'),
pht('Yellow'));
$view->addProperty(
pht('Size'),
pht('Mouse'));
$view->addProperty(
pht('Element'),
pht('Electric'));
$view->addTextContent(
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '.
'Quisque rhoncus tempus massa, sit amet faucibus lectus bibendum '.
'viverra. Nunc tempus tempor quam id iaculis. Maecenas lectus '.
'velit, aliquam et consequat quis, tincidunt id dolor.');
-
$view2 = new PHUIPropertyListView();
$view2->addSectionHeader(pht('Colors of the Rainbow'));
$view2->addProperty('R', pht('Red'));
$view2->addProperty('O', pht('Orange'));
$view2->addProperty('Y', pht('Yellow'));
$view2->addProperty('G', pht('Green'));
$view2->addProperty('B', pht('Blue'));
$view2->addProperty('I', pht('Indigo'));
$view2->addProperty('V', pht('Violet'));
-
$view3 = new PHUIPropertyListView();
$view3->addSectionHeader(pht('Haiku About Pasta'));
$view3->addTextContent(
hsprintf(
'%s<br />%s<br />%s',
pht('this is a pasta'),
pht('haiku. it is very bad.'),
pht('what did you expect?')));
+ $details1 = id(new PHUITabView())
+ ->setName(pht('Details'))
+ ->setKey('details')
+ ->appendChild($view);
+
+ $details2 = id(new PHUITabView())
+ ->setName(pht('Rainbow Info'))
+ ->setKey('rainbow')
+ ->appendChild($view2);
+
+ $details3 = id(new PHUITabView())
+ ->setName(pht('Pasta Haiku'))
+ ->setKey('haiku')
+ ->appendChild($view3);
+
+ $tab_group = id(new PHUITabGroupView())
+ ->addTab($details1)
+ ->addTab($details2)
+ ->addTab($details3);
+
$object_box1 = id(new PHUIObjectBoxView())
->setHeaderText(pht('%s Stackered', 'PHUIPropertyListView'))
- ->addPropertyList($view, $details1)
- ->addPropertyList($view2, $details2)
- ->addPropertyList($view3, $details3);
+ ->addTabGroup($tab_group);
$edge_cases_view = new PHUIPropertyListView();
$edge_cases_view->addProperty(
pht('Description'),
pht(
'These layouts test UI edge cases in the element. This block '.
'tests wrapping and overflow behavior.'));
$edge_cases_view->addProperty(
pht('A Very Very Very Very Very Very Very Very Very Long Property Label'),
pht(
'This property label and property value are quite long. They '.
'demonstrate the wrapping behavior of the element, or lack thereof '.
'if something terrible has happened.'));
$edge_cases_view->addProperty(
pht('AVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLongUnbrokenPropertyLabel'),
pht(
'Thispropertylabelandpropertyvaluearequitelongandhave'.
'nospacestheydemonstratetheoverflowbehavioroftheelement'.
'orlackthereof.'));
$edge_cases_view->addProperty(
pht('Description'),
pht('The next section is an empty text block.'));
$edge_cases_view->addTextContent('');
$edge_cases_view->addProperty(
pht('Description'),
pht('This section should have multiple properties with the same name.'));
$edge_cases_view->addProperty(
pht('Joe'),
pht('Smith'));
$edge_cases_view->addProperty(
pht('Joe'),
pht('Smith'));
$edge_cases_view->addProperty(
pht('Joe'),
pht('Smith'));
$object_box2 = id(new PHUIObjectBoxView())
->setHeaderText(pht('Some Bad Examples'))
->addPropertyList($edge_cases_view);
return array(
$object_box1,
$object_box2,
);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Fri, Mar 14, 2:20 PM (1 d, 8 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
71940
Default Alt Text
(57 KB)

Event Timeline