Page MenuHomePhabricator

D20384.id48630.diff
No OneTemporary

D20384.id48630.diff

diff --git a/resources/celerity/map.php b/resources/celerity/map.php
--- a/resources/celerity/map.php
+++ b/resources/celerity/map.php
@@ -9,7 +9,7 @@
'names' => array(
'conpherence.pkg.css' => '3c8a0668',
'conpherence.pkg.js' => '020aebcf',
- 'core.pkg.css' => '2d4810eb',
+ 'core.pkg.css' => '671b9fae',
'core.pkg.js' => 'f9e9d770',
'differential.pkg.css' => '8d8360fb',
'differential.pkg.js' => '67e02996',
@@ -134,7 +134,7 @@
'rsrc/css/phui/object-item/phui-oi-flush-ui.css' => '490e2e2e',
'rsrc/css/phui/object-item/phui-oi-list-view.css' => 'f14f2422',
'rsrc/css/phui/object-item/phui-oi-simple-ui.css' => '6a30fa46',
- 'rsrc/css/phui/phui-action-list.css' => 'c4972757',
+ 'rsrc/css/phui/phui-action-list.css' => 'c34af376',
'rsrc/css/phui/phui-action-panel.css' => '6c386cbf',
'rsrc/css/phui/phui-badge.css' => '666e25ad',
'rsrc/css/phui/phui-basic-nav-view.css' => '56ebd66d',
@@ -757,7 +757,7 @@
'path-typeahead' => 'ad486db3',
'people-picture-menu-item-css' => 'fe8e07cf',
'people-profile-css' => '2ea2daa1',
- 'phabricator-action-list-view-css' => 'c4972757',
+ 'phabricator-action-list-view-css' => 'c34af376',
'phabricator-busy' => '5202e831',
'phabricator-chatlog-css' => 'abdc76ee',
'phabricator-content-source-view-css' => 'cdf0d579',
diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2942,6 +2942,7 @@
'PhabricatorDashboardPanelRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php',
'PhabricatorDashboardPanelSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardPanelSearchEngine.php',
'PhabricatorDashboardPanelStatusTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardPanelStatusTransaction.php',
+ 'PhabricatorDashboardPanelTabsController' => 'applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php',
'PhabricatorDashboardPanelTransaction' => 'applications/dashboard/storage/PhabricatorDashboardPanelTransaction.php',
'PhabricatorDashboardPanelTransactionEditor' => 'applications/dashboard/editor/PhabricatorDashboardPanelTransactionEditor.php',
'PhabricatorDashboardPanelTransactionQuery' => 'applications/dashboard/query/PhabricatorDashboardPanelTransactionQuery.php',
@@ -2984,6 +2985,7 @@
'PhabricatorDashboardRenderingEngine' => 'applications/dashboard/engine/PhabricatorDashboardRenderingEngine.php',
'PhabricatorDashboardSchemaSpec' => 'applications/dashboard/storage/PhabricatorDashboardSchemaSpec.php',
'PhabricatorDashboardSearchEngine' => 'applications/dashboard/query/PhabricatorDashboardSearchEngine.php',
+ 'PhabricatorDashboardTabsPanelTabsTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardTabsPanelTabsTransaction.php',
'PhabricatorDashboardTabsPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php',
'PhabricatorDashboardTextPanelTextTransaction' => 'applications/dashboard/xaction/panel/PhabricatorDashboardTextPanelTextTransaction.php',
'PhabricatorDashboardTextPanelType' => 'applications/dashboard/paneltype/PhabricatorDashboardTextPanelType.php',
@@ -8919,6 +8921,7 @@
'PhabricatorDashboardPanelRenderingEngine' => 'Phobject',
'PhabricatorDashboardPanelSearchEngine' => 'PhabricatorApplicationSearchEngine',
'PhabricatorDashboardPanelStatusTransaction' => 'PhabricatorDashboardPanelTransactionType',
+ 'PhabricatorDashboardPanelTabsController' => 'PhabricatorDashboardController',
'PhabricatorDashboardPanelTransaction' => 'PhabricatorModularTransaction',
'PhabricatorDashboardPanelTransactionEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorDashboardPanelTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
@@ -8966,6 +8969,7 @@
'PhabricatorDashboardRenderingEngine' => 'Phobject',
'PhabricatorDashboardSchemaSpec' => 'PhabricatorConfigSchemaSpec',
'PhabricatorDashboardSearchEngine' => 'PhabricatorApplicationSearchEngine',
+ 'PhabricatorDashboardTabsPanelTabsTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
'PhabricatorDashboardTabsPanelType' => 'PhabricatorDashboardPanelType',
'PhabricatorDashboardTextPanelTextTransaction' => 'PhabricatorDashboardPanelPropertyTransaction',
'PhabricatorDashboardTextPanelType' => 'PhabricatorDashboardPanelType',
diff --git a/src/applications/dashboard/application/PhabricatorDashboardApplication.php b/src/applications/dashboard/application/PhabricatorDashboardApplication.php
--- a/src/applications/dashboard/application/PhabricatorDashboardApplication.php
+++ b/src/applications/dashboard/application/PhabricatorDashboardApplication.php
@@ -62,6 +62,8 @@
'render/(?P<id>\d+)/' => 'PhabricatorDashboardPanelRenderController',
'archive/(?P<id>\d+)/'
=> 'PhabricatorDashboardPanelArchiveController',
+ 'tabs/(?P<id>\d+)/(?P<op>add|move|remove|rename)/'
+ => 'PhabricatorDashboardPanelTabsController',
),
),
'/portal/' => array(
diff --git a/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php
@@ -0,0 +1,295 @@
+<?php
+
+final class PhabricatorDashboardPanelTabsController
+ extends PhabricatorDashboardController {
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+
+ $panel = id(new PhabricatorDashboardPanelQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($request->getURIData('id')))
+ ->requireCapabilities(
+ array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ ))
+ ->executeOne();
+ if (!$panel) {
+ return new Aphront404Response();
+ }
+
+ $tabs_type = id(new PhabricatorDashboardTabsPanelType())
+ ->getPanelTypeKey();
+
+ // This controller may only be used to edit tab panels.
+ $panel_type = $panel->getPanelType();
+ if ($panel_type !== $tabs_type) {
+ return new Aphront404Response();
+ }
+
+ $op = $request->getURIData('op');
+ $after = $request->getStr('after');
+ if (!strlen($after)) {
+ $after = null;
+ }
+
+ $target = $request->getStr('target');
+ if (!strlen($target)) {
+ $target = null;
+ }
+
+ $impl = $panel->getImplementation();
+ $config = $impl->getPanelConfiguration($panel);
+
+ $cancel_uri = $panel->getURI();
+
+ if ($after !== null) {
+ $found = false;
+ foreach ($config as $key => $spec) {
+ if ((string)$key === $after) {
+ $found = true;
+ break;
+ }
+ }
+
+ if (!$found) {
+ return $this->newDialog()
+ ->setTitle(pht('Adjacent Tab Not Found'))
+ ->appendParagraph(
+ pht(
+ 'Adjacent tab ("%s") was not found on this panel. It may have '.
+ 'been removed.',
+ $after))
+ ->addCancelButton($cancel_uri);
+ }
+ }
+
+ if ($target !== null) {
+ $found = false;
+ foreach ($config as $key => $spec) {
+ if ((string)$key === $target) {
+ $found = true;
+ break;
+ }
+ }
+
+ if (!$found) {
+ return $this->newDialog()
+ ->setTitle(pht('Target Tab Not Found'))
+ ->appendParagraph(
+ pht(
+ 'Target tab ("%s") was not found on this panel. It may have '.
+ 'been removed.',
+ $target))
+ ->addCancelButton($cancel_uri);
+ }
+ }
+
+ switch ($op) {
+ case 'add':
+ return $this->handleAddOperation($panel, $after, $cancel_uri);
+ case 'remove':
+ return $this->handleRemoveOperation($panel, $target, $cancel_uri);
+ case 'move':
+ break;
+ case 'rename':
+ return $this->handleRenameOperation($panel, $target, $cancel_uri);
+ }
+ }
+
+ private function handleAddOperation(
+ PhabricatorDashboardPanel $panel,
+ $after,
+ $cancel_uri) {
+ $request = $this->getRequest();
+ $viewer = $this->getViewer();
+
+ $panel_phid = null;
+ $errors = array();
+ if ($request->isFormPost()) {
+ $panel_phid = $request->getArr('panelPHID');
+ $panel_phid = head($panel_phid);
+
+ $add_panel = id(new PhabricatorDashboardPanelQuery())
+ ->setViewer($viewer)
+ ->withPHIDs(array($panel_phid))
+ ->executeOne();
+ if (!$add_panel) {
+ $errors[] = pht('You must select a valid panel.');
+ }
+
+ if (!$errors) {
+ $add_panel_config = array(
+ 'name' => null,
+ 'panelID' => $add_panel->getID(),
+ );
+ $add_panel_key = Filesystem::readRandomCharacters(12);
+
+ $impl = $panel->getImplementation();
+ $old_config = $impl->getPanelConfiguration($panel);
+ $new_config = array();
+ if ($after === null) {
+ $new_config = $old_config;
+ $new_config[] = $add_panel_config;
+ } else {
+ foreach ($old_config as $key => $value) {
+ $new_config[$key] = $value;
+ if ((string)$key === $after) {
+ $new_config[$add_panel_key] = $add_panel_config;
+ }
+ }
+ }
+
+ $xactions = array();
+
+ $xactions[] = $panel->getApplicationTransactionTemplate()
+ ->setTransactionType(
+ PhabricatorDashboardTabsPanelTabsTransaction::TRANSACTIONTYPE)
+ ->setNewValue($new_config);
+
+ $editor = id(new PhabricatorDashboardPanelTransactionEditor())
+ ->setContentSourceFromRequest($request)
+ ->setActor($viewer)
+ ->setContinueOnNoEffect(true)
+ ->setContinueOnMissingFields(true);
+
+ $editor->applyTransactions($panel, $xactions);
+
+ return id(new AphrontRedirectResponse())->setURI($cancel_uri);
+ }
+ }
+
+ if ($panel_phid) {
+ $v_panel = array($panel_phid);
+ } else {
+ $v_panel = array();
+ }
+
+ $form = id(new AphrontFormView())
+ ->setViewer($viewer)
+ ->appendControl(
+ id(new AphrontFormTokenizerControl())
+ ->setDatasource(new PhabricatorDashboardPanelDatasource())
+ ->setLimit(1)
+ ->setName('panelPHID')
+ ->setLabel(pht('Panel'))
+ ->setValue($v_panel));
+
+ return $this->newDialog()
+ ->setTitle(pht('Choose Dashboard Panel'))
+ ->setErrors($errors)
+ ->setWidth(AphrontDialogView::WIDTH_FORM)
+ ->addHiddenInput('after', $after)
+ ->appendForm($form)
+ ->addCancelButton($cancel_uri)
+ ->addSubmitButton(pht('Add Panel'));
+ }
+
+ private function handleRemoveOperation(
+ PhabricatorDashboardPanel $panel,
+ $target,
+ $cancel_uri) {
+ $request = $this->getRequest();
+ $viewer = $this->getViewer();
+
+ $panel_phid = null;
+ $errors = array();
+ if ($request->isFormPost()) {
+ $impl = $panel->getImplementation();
+ $old_config = $impl->getPanelConfiguration($panel);
+
+ $new_config = $this->removePanel($old_config, $target);
+ $this->writePanelConfig($panel, $new_config);
+
+ return id(new AphrontRedirectResponse())->setURI($cancel_uri);
+ }
+
+ return $this->newDialog()
+ ->setTitle(pht('Remove tab?'))
+ ->addHiddenInput('target', $target)
+ ->appendParagraph(pht('Really remove this tab?'))
+ ->addCancelButton($cancel_uri)
+ ->addSubmitButton(pht('Remove Tab'));
+ }
+
+ private function handleRenameOperation(
+ PhabricatorDashboardPanel $panel,
+ $target,
+ $cancel_uri) {
+ $request = $this->getRequest();
+ $viewer = $this->getViewer();
+
+ $impl = $panel->getImplementation();
+ $old_config = $impl->getPanelConfiguration($panel);
+
+ $spec = $old_config[$target];
+ $name = idx($spec, 'name');
+
+ if ($request->isFormPost()) {
+ $name = $request->getStr('name');
+
+ $new_config = $this->renamePanel($old_config, $target, $name);
+ $this->writePanelConfig($panel, $new_config);
+
+ return id(new AphrontRedirectResponse())->setURI($cancel_uri);
+ }
+
+ $form = id(new AphrontFormView())
+ ->setViewer($viewer)
+ ->appendControl(
+ id(new AphrontFormTextControl())
+ ->setValue($name)
+ ->setName('name')
+ ->setLabel(pht('Tab Name')));
+
+ return $this->newDialog()
+ ->setTitle(pht('Rename Panel'))
+ ->addHiddenInput('target', $target)
+ ->appendForm($form)
+ ->addCancelButton($cancel_uri)
+ ->addSubmitButton(pht('Rename Tab'));
+ }
+
+
+ private function writePanelConfig(
+ PhabricatorDashboardPanel $panel,
+ array $config) {
+ $request = $this->getRequest();
+ $viewer = $this->getViewer();
+
+ $xactions = array();
+
+ $xactions[] = $panel->getApplicationTransactionTemplate()
+ ->setTransactionType(
+ PhabricatorDashboardTabsPanelTabsTransaction::TRANSACTIONTYPE)
+ ->setNewValue($config);
+
+ $editor = id(new PhabricatorDashboardPanelTransactionEditor())
+ ->setContentSourceFromRequest($request)
+ ->setActor($viewer)
+ ->setContinueOnNoEffect(true)
+ ->setContinueOnMissingFields(true);
+
+ return $editor->applyTransactions($panel, $xactions);
+ }
+
+ private function removePanel(array $config, $target) {
+ $result = array();
+
+ foreach ($config as $key => $panel_spec) {
+ if ((string)$key === $target) {
+ continue;
+ }
+ $result[$key] = $panel_spec;
+ }
+
+ return $result;
+ }
+
+ private function renamePanel(array $config, $target, $name) {
+ $config[$target]['name'] = $name;
+ return $config;
+ }
+
+}
diff --git a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php
--- a/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php
+++ b/src/applications/dashboard/engine/PhabricatorDashboardPanelRenderingEngine.php
@@ -43,6 +43,10 @@
return $this->panelHandle;
}
+ public function isEditMode() {
+ return ($this->getHeaderMode() === self::HEADER_MODE_EDIT);
+ }
+
/**
* Allow the engine to render the panel via Ajax.
*/
diff --git a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php
--- a/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php
+++ b/src/applications/dashboard/paneltype/PhabricatorDashboardTabsPanelType.php
@@ -20,7 +20,6 @@
}
protected function newEditEngineFields(PhabricatorDashboardPanel $panel) {
- // TODO: Restore this using EditEngine instead of CustomField.
return array();
}
@@ -29,37 +28,37 @@
return false;
}
+ public function getPanelConfiguration(PhabricatorDashboardPanel $panel) {
+ $config = $panel->getProperty('config');
+
+ if (!is_array($config)) {
+ // NOTE: The older version of this panel stored raw JSON.
+ try {
+ $config = phutil_json_decode($config);
+ } catch (PhutilJSONParserException $ex) {
+ $config = array();
+ }
+ }
+
+ return $config;
+ }
+
public function renderPanelContent(
PhabricatorUser $viewer,
PhabricatorDashboardPanel $panel,
PhabricatorDashboardPanelRenderingEngine $engine) {
- $config = $panel->getProperty('config');
- if (!is_array($config)) {
- // NOTE: The older version of this panel stored raw JSON.
- $config = phutil_json_decode($config);
- }
+ $is_edit = $engine->isEditMode();
+ $config = $this->getPanelConfiguration($panel);
$list = id(new PHUIListView())
->setType(PHUIListView::NAVBAR_LIST);
- $selected = 0;
-
$node_ids = array();
foreach ($config as $idx => $tab_spec) {
$node_ids[$idx] = celerity_generate_unique_node_id();
}
- foreach ($config as $idx => $tab_spec) {
- $list->addMenuItem(
- id(new PHUIListItemView())
- ->setHref('#')
- ->setSelected($idx == $selected)
- ->addSigil('dashboard-tab-panel-tab')
- ->setMetadata(array('idx' => $idx))
- ->setName(idx($tab_spec, 'name', pht('Nameless Tab'))));
- }
-
$ids = ipull($config, 'panelID');
if ($ids) {
$panels = id(new PhabricatorDashboardPanelQuery())
@@ -70,6 +69,135 @@
$panels = array();
}
+ $id = $panel->getID();
+
+ $add_uri = urisprintf('/dashboard/panel/tabs/%d/add/', $id);
+ $add_uri = new PhutilURI($add_uri);
+
+ $remove_uri = urisprintf('/dashboard/panel/tabs/%d/remove/', $id);
+ $remove_uri = new PhutilURI($remove_uri);
+
+ $rename_uri = urisprintf('/dashboard/panel/tabs/%d/rename/', $id);
+ $rename_uri = new PhutilURI($rename_uri);
+
+ $selected = 0;
+
+ $last_idx = null;
+ foreach ($config as $idx => $tab_spec) {
+ $panel_id = idx($tab_spec, 'panelID');
+ $subpanel = idx($panels, $panel_id);
+
+ $name = idx($tab_spec, 'name');
+ if (!strlen($name)) {
+ if ($subpanel) {
+ $name = $subpanel->getName();
+ }
+ }
+
+ if (!strlen($name)) {
+ $name = pht('Unnamed Tab');
+ }
+
+ $tab_view = id(new PHUIListItemView())
+ ->setHref('#')
+ ->setSelected($idx == $selected)
+ ->addSigil('dashboard-tab-panel-tab')
+ ->setMetadata(array('idx' => $idx))
+ ->setName($name);
+
+ if ($is_edit) {
+ $dropdown_menu = id(new PhabricatorActionListView())
+ ->setViewer($viewer);
+
+ $remove_tab_uri = id(clone $remove_uri)
+ ->replaceQueryParam('target', $idx);
+
+ $rename_tab_uri = id(clone $rename_uri)
+ ->replaceQueryParam('target', $idx);
+
+ if ($subpanel) {
+ $details_uri = $subpanel->getURI();
+ } else {
+ $details_uri = null;
+ }
+
+ $edit_uri = urisprintf(
+ '/dashboard/panel/edit/%d/',
+ $panel_id);
+ if ($subpanel) {
+ $can_edit = PhabricatorPolicyFilter::hasCapability(
+ $viewer,
+ $subpanel,
+ PhabricatorPolicyCapability::CAN_EDIT);
+ } else {
+ $can_edit = false;
+ }
+
+ $dropdown_menu->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Rename Tab'))
+ ->setIcon('fa-pencil')
+ ->setHref($rename_tab_uri)
+ ->setWorkflow(true));
+
+ $dropdown_menu->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Remove Tab'))
+ ->setIcon('fa-times')
+ ->setHref($remove_tab_uri)
+ ->setWorkflow(true));
+
+ $dropdown_menu->addAction(
+ id(new PhabricatorActionView())
+ ->setType(PhabricatorActionView::TYPE_DIVIDER));
+
+ $dropdown_menu->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Edit Panel'))
+ ->setIcon('fa-pencil')
+ ->setHref($edit_uri)
+ ->setWorkflow(true)
+ ->setDisabled(!$can_edit));
+
+ $dropdown_menu->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('View Panel Details'))
+ ->setIcon('fa-window-maximize')
+ ->setHref($details_uri)
+ ->setDisabled(!$subpanel));
+
+ $tab_view->setDropdownMenu($dropdown_menu);
+ }
+
+ $list->addMenuItem($tab_view);
+
+ $last_idx = $idx;
+ }
+
+ if ($is_edit) {
+ $actions = id(new PhabricatorActionListView())
+ ->setViewer($viewer);
+
+ $add_last_uri = clone $add_uri;
+ if ($last_idx) {
+ $add_last_uri->replaceQueryParam('after', $last_idx);
+ }
+
+ $actions->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Add Existing Panel'))
+ ->setIcon('fa-window-maximize')
+ ->setHref($add_last_uri)
+ ->setWorkflow(true));
+
+ $list->addMenuItem(
+ id(new PHUIListItemView())
+ ->setHref('#')
+ ->setSelected(false)
+ ->setName(pht('Add Tab...'))
+ ->setDropdownMenu($actions));
+ }
+
$parent_phids = $engine->getParentPanelPHIDs();
$parent_phids[] = $panel->getPHID();
@@ -83,15 +211,15 @@
$no_headers = PhabricatorDashboardPanelRenderingEngine::HEADER_MODE_NONE;
foreach ($config as $idx => $tab_spec) {
$panel_id = idx($tab_spec, 'panelID');
- $panel = idx($panels, $panel_id);
+ $subpanel = idx($panels, $panel_id);
- if ($panel) {
+ if ($subpanel) {
$panel_content = id(new PhabricatorDashboardPanelRenderingEngine())
->setViewer($viewer)
->setEnableAsyncRendering(true)
->setParentPanelPHIDs($parent_phids)
- ->setPanel($panel)
- ->setPanelPHID($panel->getPHID())
+ ->setPanel($subpanel)
+ ->setPanelPHID($subpanel->getPHID())
->setHeaderMode($no_headers)
->setMovable(false)
->renderPanel();
@@ -108,6 +236,28 @@
$panel_content);
}
+ if (!$content) {
+ if ($is_edit) {
+ $message = pht(
+ 'This tab panel does not have any tabs yet. Use "Add Tab" to '.
+ 'create or place a tab.');
+ } else {
+ $message = pht(
+ 'This tab panel does not have any tabs yet.');
+ }
+
+ $content = id(new PHUIInfoView())
+ ->setSeverity(PHUIInfoView::SEVERITY_NODATA)
+ ->setErrors(
+ array(
+ $message,
+ ));
+
+ $content = id(new PHUIBoxView())
+ ->addClass('mlt mlb')
+ ->appendChild($content);
+ }
+
Javelin::initBehavior('dashboard-tab-panel');
return javelin_tag(
diff --git a/src/applications/dashboard/typeahead/PhabricatorDashboardPanelDatasource.php b/src/applications/dashboard/typeahead/PhabricatorDashboardPanelDatasource.php
--- a/src/applications/dashboard/typeahead/PhabricatorDashboardPanelDatasource.php
+++ b/src/applications/dashboard/typeahead/PhabricatorDashboardPanelDatasource.php
@@ -48,13 +48,13 @@
$type_text = nonempty($panel->getPanelType(), pht('Unknown Type'));
$icon = 'fa-question';
}
- $id = $panel->getID();
+ $phid = $panel->getPHID();
$monogram = $panel->getMonogram();
$properties = $panel->getProperties();
$result = id(new PhabricatorTypeaheadResult())
->setName($monogram.' '.$panel->getName())
- ->setPHID($id)
+ ->setPHID($phid)
->setIcon($icon)
->addAttribute($type_text);
@@ -66,7 +66,7 @@
$result->setClosed(pht('Archived'));
}
- $results[$id] = $result;
+ $results[$phid] = $result;
}
return $results;
diff --git a/src/applications/dashboard/xaction/panel/PhabricatorDashboardTabsPanelTabsTransaction.php b/src/applications/dashboard/xaction/panel/PhabricatorDashboardTabsPanelTabsTransaction.php
new file mode 100644
--- /dev/null
+++ b/src/applications/dashboard/xaction/panel/PhabricatorDashboardTabsPanelTabsTransaction.php
@@ -0,0 +1,12 @@
+<?php
+
+final class PhabricatorDashboardTabsPanelTabsTransaction
+ extends PhabricatorDashboardPanelPropertyTransaction {
+
+ const TRANSACTIONTYPE = 'tabs.tabs';
+
+ protected function getPropertyKey() {
+ return 'config';
+ }
+
+}
diff --git a/src/view/phui/PHUIListItemView.php b/src/view/phui/PHUIListItemView.php
--- a/src/view/phui/PHUIListItemView.php
+++ b/src/view/phui/PHUIListItemView.php
@@ -35,6 +35,7 @@
private $actionIconHref;
private $count;
private $rel;
+ private $hasDropdown;
public function setOpenInNewWindow($open_in_new_window) {
$this->openInNewWindow = $open_in_new_window;
@@ -68,6 +69,7 @@
$this->addSigil('phui-dropdown-menu');
$this->setMetadata($actions->getDropdownMenuMetadata());
+ $this->hasDropdown = true;
return $this;
}
@@ -235,6 +237,10 @@
$classes[] = 'phui-list-item-has-action-icon';
}
+ if ($this->hasDropdown) {
+ $classes[] = 'dropdown';
+ }
+
return array(
'class' => implode(' ', $classes),
);
@@ -363,6 +369,12 @@
$this->count);
}
+ if ($this->hasDropdown) {
+ $caret = phutil_tag('span', array('class' => 'caret'), '');
+ } else {
+ $caret = null;
+ }
+
$icons = $this->getIcons();
$list_item = javelin_tag(
@@ -381,6 +393,7 @@
$icons,
$this->renderChildren(),
$name,
+ $caret,
$count,
));
diff --git a/webroot/rsrc/css/phui/phui-action-list.css b/webroot/rsrc/css/phui/phui-action-list.css
--- a/webroot/rsrc/css/phui/phui-action-list.css
+++ b/webroot/rsrc/css/phui/phui-action-list.css
@@ -213,3 +213,14 @@
.phabricator-action-view-item .phui-icon-view {
color: {$sky};
}
+
+.phui-list-item-view.dropdown .phui-list-item-href {
+ padding-right: 28px;
+}
+
+.phui-list-item-view .caret {
+ position: absolute;
+ top: 6px;
+ right: 12px;
+ border-top: 7px solid {$greytext};
+}

File Metadata

Mime Type
text/plain
Expires
Tue, May 21, 3:32 AM (3 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6304386
Default Alt Text
D20384.id48630.diff (24 KB)

Event Timeline