Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15379836
D20384.id48630.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
24 KB
Referenced Files
None
Subscribers
None
D20384.id48630.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Fri, Mar 14, 11:41 PM (1 w, 6 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7598310
Default Alt Text
D20384.id48630.diff (24 KB)
Attached To
Mode
D20384: Rebuild Dashboards on EditEngine: v1 Major Jank Edition
Attached
Detach File
Event Timeline
Log In to Comment