mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 08:52:39 +01:00
Add "Move Left" and "Move Right" to dashboard tab panels
Summary: Depends on D20474. Ref T13272. Provide an easy way to rearrange tabs on a tab panel, by moving them left or right from the context menu. Test Plan: Moved tabs left and right. Tried to move them off the end of the tab list, no luck. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13272 Differential Revision: https://secure.phabricator.com/D20475
This commit is contained in:
parent
9d716379a3
commit
c43618a3a8
4 changed files with 142 additions and 10 deletions
|
@ -383,6 +383,15 @@ final class AphrontRequest extends Phobject {
|
||||||
return $this->validateCSRF();
|
return $this->validateCSRF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function hasCSRF() {
|
||||||
|
try {
|
||||||
|
$this->validateCSRF();
|
||||||
|
return true;
|
||||||
|
} catch (AphrontMalformedRequestException $ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function isFormOrHisecPost() {
|
public function isFormOrHisecPost() {
|
||||||
$post = $this->getExists(self::TYPE_FORM) &&
|
$post = $this->getExists(self::TYPE_FORM) &&
|
||||||
$this->isHTTPPost();
|
$this->isHTTPPost();
|
||||||
|
|
|
@ -140,7 +140,7 @@ final class PhabricatorDashboardPanelTabsController
|
||||||
case 'remove':
|
case 'remove':
|
||||||
return $this->handleRemoveOperation($panel, $target, $cancel_uri);
|
return $this->handleRemoveOperation($panel, $target, $cancel_uri);
|
||||||
case 'move':
|
case 'move':
|
||||||
break;
|
return $this->handleMoveOperation($panel, $target, $after, $cancel_uri);
|
||||||
case 'rename':
|
case 'rename':
|
||||||
return $this->handleRenameOperation($panel, $target, $cancel_uri);
|
return $this->handleRenameOperation($panel, $target, $cancel_uri);
|
||||||
}
|
}
|
||||||
|
@ -298,6 +298,89 @@ final class PhabricatorDashboardPanelTabsController
|
||||||
->addSubmitButton(pht('Rename Tab'));
|
->addSubmitButton(pht('Rename Tab'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function handleMoveOperation(
|
||||||
|
PhabricatorDashboardPanel $panel,
|
||||||
|
$target,
|
||||||
|
$after,
|
||||||
|
$cancel_uri) {
|
||||||
|
$request = $this->getRequest();
|
||||||
|
$viewer = $this->getViewer();
|
||||||
|
|
||||||
|
$move = $request->getStr('move');
|
||||||
|
|
||||||
|
$impl = $panel->getImplementation();
|
||||||
|
$old_config = $impl->getPanelConfiguration($panel);
|
||||||
|
|
||||||
|
$is_next = ($move === 'next');
|
||||||
|
if ($target === $after) {
|
||||||
|
return $this->newDialog()
|
||||||
|
->setTitle(pht('Impossible!'))
|
||||||
|
->appendParagraph(
|
||||||
|
pht(
|
||||||
|
'You can not move a tab relative to itself.'))
|
||||||
|
->addCancelButton($cancel_uri);
|
||||||
|
} else if ($is_next && ((string)last_key($old_config) === $target)) {
|
||||||
|
return $this->newDialog()
|
||||||
|
->setTitle(pht('Impossible!'))
|
||||||
|
->appendParagraph(
|
||||||
|
pht(
|
||||||
|
'This is already the last tab. It can not move any farther to '.
|
||||||
|
'the right.'))
|
||||||
|
->addCancelButton($cancel_uri);
|
||||||
|
} else if ((string)head_key($old_config) === $target) {
|
||||||
|
return $this->newDialog()
|
||||||
|
->setTitle(pht('Impossible!'))
|
||||||
|
->appendParagraph(
|
||||||
|
pht(
|
||||||
|
'This is already the first tab. It can not move any farther to '.
|
||||||
|
'the left.'))
|
||||||
|
->addCancelButton($cancel_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->hasCSRF()) {
|
||||||
|
$new_config = array();
|
||||||
|
foreach ($old_config as $old_key => $old_spec) {
|
||||||
|
$old_key = (string)$old_key;
|
||||||
|
|
||||||
|
$is_after = ($old_key === $after);
|
||||||
|
|
||||||
|
if (!$is_after) {
|
||||||
|
if ($old_key === $target) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_after && !$is_next) {
|
||||||
|
$new_config[$target] = $old_config[$target];
|
||||||
|
}
|
||||||
|
|
||||||
|
$new_config[$old_key] = $old_spec;
|
||||||
|
|
||||||
|
if ($is_after && $is_next) {
|
||||||
|
$new_config[$target] = $old_config[$target];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->writePanelConfig($panel, $new_config);
|
||||||
|
|
||||||
|
return id(new AphrontRedirectResponse())->setURI($cancel_uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($is_next) {
|
||||||
|
$prompt = pht('Move this tab to the right?');
|
||||||
|
} else {
|
||||||
|
$prompt = pht('Move this tab to the left?');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->newEditDialog()
|
||||||
|
->setTitle(pht('Move Tab'))
|
||||||
|
->addHiddenInput('target', $target)
|
||||||
|
->addHiddenInput('after', $after)
|
||||||
|
->addHiddenInput('move', $move)
|
||||||
|
->appendParagraph($prompt)
|
||||||
|
->addCancelButton($cancel_uri)
|
||||||
|
->addSubmitButton(pht('Move Tab'));
|
||||||
|
}
|
||||||
|
|
||||||
private function writePanelConfig(
|
private function writePanelConfig(
|
||||||
PhabricatorDashboardPanel $panel,
|
PhabricatorDashboardPanel $panel,
|
||||||
|
|
|
@ -87,7 +87,15 @@ final class PhabricatorDashboardTabsPanelType
|
||||||
|
|
||||||
$selected = 0;
|
$selected = 0;
|
||||||
|
|
||||||
$last_idx = null;
|
$key_list = array_keys($config);
|
||||||
|
|
||||||
|
$next_keys = array();
|
||||||
|
$prev_keys = array();
|
||||||
|
for ($ii = 0; $ii < count($key_list); $ii++) {
|
||||||
|
$next_keys[$key_list[$ii]] = idx($key_list, $ii + 1);
|
||||||
|
$prev_keys[$key_list[$ii]] = idx($key_list, $ii - 1);
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($config as $idx => $tab_spec) {
|
foreach ($config as $idx => $tab_spec) {
|
||||||
$panel_id = idx($tab_spec, 'panelID');
|
$panel_id = idx($tab_spec, 'panelID');
|
||||||
$subpanel = idx($panels, $panel_id);
|
$subpanel = idx($panels, $panel_id);
|
||||||
|
@ -145,6 +153,42 @@ final class PhabricatorDashboardTabsPanelType
|
||||||
->setHref($rename_tab_uri)
|
->setHref($rename_tab_uri)
|
||||||
->setWorkflow(true));
|
->setWorkflow(true));
|
||||||
|
|
||||||
|
$move_uri = urisprintf('/dashboard/panel/tabs/%d/move/', $id);
|
||||||
|
|
||||||
|
$prev_key = $prev_keys[$idx];
|
||||||
|
$prev_params = array(
|
||||||
|
'target' => $idx,
|
||||||
|
'after' => $prev_key,
|
||||||
|
'move' => 'prev',
|
||||||
|
'contextPHID' => $context_phid,
|
||||||
|
);
|
||||||
|
$prev_uri = new PhutilURI($move_uri, $prev_params);
|
||||||
|
|
||||||
|
$next_key = $next_keys[$idx];
|
||||||
|
$next_params = array(
|
||||||
|
'target' => $idx,
|
||||||
|
'after' => $next_key,
|
||||||
|
'move' => 'next',
|
||||||
|
'contextPHID' => $context_phid,
|
||||||
|
);
|
||||||
|
$next_uri = new PhutilURI($move_uri, $next_params);
|
||||||
|
|
||||||
|
$dropdown_menu->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Move Tab Left'))
|
||||||
|
->setIcon('fa-chevron-left')
|
||||||
|
->setHref($prev_uri)
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(($prev_key === null) || !$can_edit));
|
||||||
|
|
||||||
|
$dropdown_menu->addAction(
|
||||||
|
id(new PhabricatorActionView())
|
||||||
|
->setName(pht('Move Tab Right'))
|
||||||
|
->setIcon('fa-chevron-right')
|
||||||
|
->setHref($next_uri)
|
||||||
|
->setWorkflow(true)
|
||||||
|
->setDisabled(($next_key === null) || !$can_edit));
|
||||||
|
|
||||||
$dropdown_menu->addAction(
|
$dropdown_menu->addAction(
|
||||||
id(new PhabricatorActionView())
|
id(new PhabricatorActionView())
|
||||||
->setName(pht('Remove Tab'))
|
->setName(pht('Remove Tab'))
|
||||||
|
@ -177,15 +221,16 @@ final class PhabricatorDashboardTabsPanelType
|
||||||
}
|
}
|
||||||
|
|
||||||
$list->addMenuItem($tab_view);
|
$list->addMenuItem($tab_view);
|
||||||
|
|
||||||
$last_idx = $idx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ($is_edit) {
|
if ($is_edit) {
|
||||||
$actions = id(new PhabricatorActionListView())
|
$actions = id(new PhabricatorActionListView())
|
||||||
->setViewer($viewer);
|
->setViewer($viewer);
|
||||||
|
|
||||||
$add_last_uri = clone $add_uri;
|
$add_last_uri = clone $add_uri;
|
||||||
|
|
||||||
|
$last_idx = last_key($config);
|
||||||
if ($last_idx) {
|
if ($last_idx) {
|
||||||
$add_last_uri->replaceQueryParam('after', $last_idx);
|
$add_last_uri->replaceQueryParam('after', $last_idx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,7 @@ final class PhabricatorNotificationClearController
|
||||||
if ($request->isDialogFormPost()) {
|
if ($request->isDialogFormPost()) {
|
||||||
$should_clear = true;
|
$should_clear = true;
|
||||||
} else {
|
} else {
|
||||||
try {
|
$should_clear = $request->hasCSRF();
|
||||||
$request->validateCSRF();
|
|
||||||
$should_clear = true;
|
|
||||||
} catch (AphrontMalformedRequestException $ex) {
|
|
||||||
$should_clear = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($should_clear) {
|
if ($should_clear) {
|
||||||
|
|
Loading…
Reference in a new issue