Page MenuHomePhabricator

D20475.diff
No OneTemporary

D20475.diff

diff --git a/src/aphront/AphrontRequest.php b/src/aphront/AphrontRequest.php
--- a/src/aphront/AphrontRequest.php
+++ b/src/aphront/AphrontRequest.php
@@ -383,6 +383,15 @@
return $this->validateCSRF();
}
+ public function hasCSRF() {
+ try {
+ $this->validateCSRF();
+ return true;
+ } catch (AphrontMalformedRequestException $ex) {
+ return false;
+ }
+ }
+
public function isFormOrHisecPost() {
$post = $this->getExists(self::TYPE_FORM) &&
$this->isHTTPPost();
diff --git a/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php
--- a/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php
+++ b/src/applications/dashboard/controller/panel/PhabricatorDashboardPanelTabsController.php
@@ -140,7 +140,7 @@
case 'remove':
return $this->handleRemoveOperation($panel, $target, $cancel_uri);
case 'move':
- break;
+ return $this->handleMoveOperation($panel, $target, $after, $cancel_uri);
case 'rename':
return $this->handleRenameOperation($panel, $target, $cancel_uri);
}
@@ -298,6 +298,89 @@
->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(
PhabricatorDashboardPanel $panel,
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
@@ -87,7 +87,15 @@
$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) {
$panel_id = idx($tab_spec, 'panelID');
$subpanel = idx($panels, $panel_id);
@@ -145,6 +153,42 @@
->setHref($rename_tab_uri)
->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(
id(new PhabricatorActionView())
->setName(pht('Remove Tab'))
@@ -177,15 +221,16 @@
}
$list->addMenuItem($tab_view);
-
- $last_idx = $idx;
}
+
if ($is_edit) {
$actions = id(new PhabricatorActionListView())
->setViewer($viewer);
$add_last_uri = clone $add_uri;
+
+ $last_idx = last_key($config);
if ($last_idx) {
$add_last_uri->replaceQueryParam('after', $last_idx);
}
diff --git a/src/applications/notification/controller/PhabricatorNotificationClearController.php b/src/applications/notification/controller/PhabricatorNotificationClearController.php
--- a/src/applications/notification/controller/PhabricatorNotificationClearController.php
+++ b/src/applications/notification/controller/PhabricatorNotificationClearController.php
@@ -10,12 +10,7 @@
if ($request->isDialogFormPost()) {
$should_clear = true;
} else {
- try {
- $request->validateCSRF();
- $should_clear = true;
- } catch (AphrontMalformedRequestException $ex) {
- $should_clear = false;
- }
+ $should_clear = $request->hasCSRF();
}
if ($should_clear) {

File Metadata

Mime Type
text/plain
Expires
Thu, May 9, 9:24 PM (4 w, 17 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6277907
Default Alt Text
D20475.diff (7 KB)

Event Timeline