1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 00:42:41 +01:00

Modernize pinned homepage applications settings

Summary:
Ref T4103. A few bits here:

  - We have an ancient "tiles" preference which was just a fallback from 2-3 years ago. Throw that away.
  - Modenize the other pinned stuff. We should likely revisit this after the next homepage update but I just left the actual defaults alone for now.
  - Lightly prepare for global default editing.
  - Add a "reset to defaults" option.

Test Plan:
  - Pinned, unpinned, reordered and reset application homepage order.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T4103

Differential Revision: https://secure.phabricator.com/D16028
This commit is contained in:
epriestley 2016-06-03 09:53:01 -07:00
parent 44e88f186c
commit 64d6593e9c
7 changed files with 131 additions and 73 deletions

View file

@ -3008,6 +3008,7 @@ phutil_register_library_map(array(
'PhabricatorPhurlURLTransactionComment' => 'applications/phurl/storage/PhabricatorPhurlURLTransactionComment.php', 'PhabricatorPhurlURLTransactionComment' => 'applications/phurl/storage/PhabricatorPhurlURLTransactionComment.php',
'PhabricatorPhurlURLTransactionQuery' => 'applications/phurl/query/PhabricatorPhurlURLTransactionQuery.php', 'PhabricatorPhurlURLTransactionQuery' => 'applications/phurl/query/PhabricatorPhurlURLTransactionQuery.php',
'PhabricatorPhurlURLViewController' => 'applications/phurl/controller/PhabricatorPhurlURLViewController.php', 'PhabricatorPhurlURLViewController' => 'applications/phurl/controller/PhabricatorPhurlURLViewController.php',
'PhabricatorPinnedApplicationsSetting' => 'applications/settings/setting/PhabricatorPinnedApplicationsSetting.php',
'PhabricatorPirateEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorPirateEnglishTranslation.php', 'PhabricatorPirateEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorPirateEnglishTranslation.php',
'PhabricatorPlatformSite' => 'aphront/site/PhabricatorPlatformSite.php', 'PhabricatorPlatformSite' => 'aphront/site/PhabricatorPlatformSite.php',
'PhabricatorPointsEditField' => 'applications/transactions/editfield/PhabricatorPointsEditField.php', 'PhabricatorPointsEditField' => 'applications/transactions/editfield/PhabricatorPointsEditField.php',
@ -7680,6 +7681,7 @@ phutil_register_library_map(array(
'PhabricatorPhurlURLTransactionComment' => 'PhabricatorApplicationTransactionComment', 'PhabricatorPhurlURLTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorPhurlURLTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorPhurlURLTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
'PhabricatorPhurlURLViewController' => 'PhabricatorPhurlController', 'PhabricatorPhurlURLViewController' => 'PhabricatorPhurlController',
'PhabricatorPinnedApplicationsSetting' => 'PhabricatorInternalSetting',
'PhabricatorPirateEnglishTranslation' => 'PhutilTranslation', 'PhabricatorPirateEnglishTranslation' => 'PhutilTranslation',
'PhabricatorPlatformSite' => 'PhabricatorSite', 'PhabricatorPlatformSite' => 'PhabricatorSite',
'PhabricatorPointsEditField' => 'PhabricatorEditField', 'PhabricatorPointsEditField' => 'PhabricatorEditField',

View file

@ -15,9 +15,8 @@ abstract class PhabricatorHomeController extends PhabricatorController {
->withLaunchable(true) ->withLaunchable(true)
->execute(); ->execute();
$pinned = $user->loadPreferences()->getPinnedApplications( $pinned = $user->getUserSetting(
$applications, PhabricatorPinnedApplicationsSetting::SETTINGKEY);
$user);
// Force "Applications" to appear at the bottom. // Force "Applications" to appear at the bottom.
$meta_app = 'PhabricatorApplicationsApplication'; $meta_app = 'PhabricatorApplicationsApplication';

View file

@ -26,12 +26,7 @@ abstract class PhabricatorEditEngineSettingsPanel
->setIsSelfEdit($is_self) ->setIsSelfEdit($is_self)
->setProfileURI($profile_uri); ->setProfileURI($profile_uri);
$preferences = $user->loadPreferences(); $preferences = $this->loadTargetPreferences();
PhabricatorPolicyFilter::requireCapability(
$viewer,
$preferences,
PhabricatorPolicyCapability::CAN_EDIT);
$engine->setTargetObject($preferences); $engine->setTargetObject($preferences);

View file

@ -16,18 +16,19 @@ final class PhabricatorHomePreferencesSettingsPanel
} }
public function processRequest(AphrontRequest $request) { public function processRequest(AphrontRequest $request) {
$user = $request->getUser(); $viewer = $this->getViewer();
$preferences = $user->loadPreferences(); $preferences = $this->loadTargetPreferences();
$pinned_key = PhabricatorPinnedApplicationsSetting::SETTINGKEY;
$pinned = $preferences->getSettingValue($pinned_key);
$apps = id(new PhabricatorApplicationQuery()) $apps = id(new PhabricatorApplicationQuery())
->setViewer($user) ->setViewer($viewer)
->withInstalled(true) ->withInstalled(true)
->withUnlisted(false) ->withUnlisted(false)
->withLaunchable(true) ->withLaunchable(true)
->execute(); ->execute();
$pinned = $preferences->getPinnedApplications($apps, $user);
$app_list = array(); $app_list = array();
foreach ($pinned as $app) { foreach ($pinned as $app) {
if (isset($apps[$app])) { if (isset($apps[$app])) {
@ -35,6 +36,23 @@ final class PhabricatorHomePreferencesSettingsPanel
} }
} }
if ($request->getBool('reset')) {
if ($request->isFormPost()) {
$this->writePinnedApplications($preferences, null);
return id(new AphrontRedirectResponse())
->setURI($this->getPanelURI());
}
return $this->newDialog()
->setTitle(pht('Reset Applications'))
->addHiddenInput('reset', 'true')
->appendParagraph(
pht('Reset pinned applications to their defaults?'))
->addSubmitButton(pht('Reset Applications'))
->addCancelButton($this->getPanelURI());
}
if ($request->getBool('add')) { if ($request->getBool('add')) {
$options = array(); $options = array();
foreach ($apps as $app) { foreach ($apps as $app) {
@ -48,10 +66,8 @@ final class PhabricatorHomePreferencesSettingsPanel
$pin = $request->getStr('pin'); $pin = $request->getStr('pin');
if (isset($options[$pin]) && !in_array($pin, $pinned)) { if (isset($options[$pin]) && !in_array($pin, $pinned)) {
$pinned[] = $pin; $pinned[] = $pin;
$preferences->setPreference(
PhabricatorUserPreferences::PREFERENCE_APP_PINNED, $this->writePinnedApplications($preferences, $pinned);
$pinned);
$preferences->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI($this->getPanelURI()); ->setURI($this->getPanelURI());
@ -65,21 +81,18 @@ final class PhabricatorHomePreferencesSettingsPanel
->setDisabledOptions(array_keys($app_list)); ->setDisabledOptions(array_keys($app_list));
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setUser($user) ->setViewer($viewer)
->addHiddenInput('add', 'true') ->addHiddenInput('add', 'true')
->appendRemarkupInstructions( ->appendRemarkupInstructions(
pht('Choose an application to pin to your home page.')) pht('Choose an application to pin to your home page.'))
->appendChild($options_control); ->appendChild($options_control);
$dialog = id(new AphrontDialogView()) return $this->newDialog()
->setUser($user)
->setWidth(AphrontDialogView::WIDTH_FORM) ->setWidth(AphrontDialogView::WIDTH_FORM)
->setTitle(pht('Pin Application')) ->setTitle(pht('Pin Application'))
->appendChild($form->buildLayoutView()) ->appendChild($form->buildLayoutView())
->addSubmitButton(pht('Pin Application')) ->addSubmitButton(pht('Pin Application'))
->addCancelButton($this->getPanelURI()); ->addCancelButton($this->getPanelURI());
return id(new AphrontDialogResponse())->setDialog($dialog);
} }
$unpin = $request->getStr('unpin'); $unpin = $request->getStr('unpin');
@ -88,35 +101,28 @@ final class PhabricatorHomePreferencesSettingsPanel
if ($app) { if ($app) {
if ($request->isFormPost()) { if ($request->isFormPost()) {
$pinned = array_diff($pinned, array($unpin)); $pinned = array_diff($pinned, array($unpin));
$preferences->setPreference(
PhabricatorUserPreferences::PREFERENCE_APP_PINNED, $this->writePinnedApplications($preferences, $pinned);
$pinned);
$preferences->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI($this->getPanelURI()); ->setURI($this->getPanelURI());
} }
$dialog = id(new AphrontDialogView()) return $this->newDialog()
->setUser($user)
->setTitle(pht('Unpin Application')) ->setTitle(pht('Unpin Application'))
->addHiddenInput('unpin', $unpin)
->appendParagraph( ->appendParagraph(
pht( pht(
'Unpin the %s application from your home page?', 'Unpin the %s application from your home page?',
phutil_tag('strong', array(), $app->getName()))) phutil_tag('strong', array(), $app->getName())))
->addSubmitButton(pht('Unpin Application')) ->addSubmitButton(pht('Unpin Application'))
->addCanceLButton($this->getPanelURI()); ->addCancelButton($this->getPanelURI());
return id(new AphrontDialogResponse())->setDialog($dialog);
} }
} }
$order = $request->getStrList('order'); $order = $request->getStrList('order');
if ($order && $request->validateCSRF()) { if ($order && $request->validateCSRF()) {
$preferences->setPreference( $this->writePinnedApplications($preferences, $order);
PhabricatorUserPreferences::PREFERENCE_APP_PINNED,
$order);
$preferences->save();
return id(new AphrontRedirectResponse()) return id(new AphrontRedirectResponse())
->setURI($this->getPanelURI()); ->setURI($this->getPanelURI());
@ -125,7 +131,7 @@ final class PhabricatorHomePreferencesSettingsPanel
$list_id = celerity_generate_unique_node_id(); $list_id = celerity_generate_unique_node_id();
$list = id(new PHUIObjectItemListView()) $list = id(new PHUIObjectItemListView())
->setUser($user) ->setViewer($viewer)
->setID($list_id); ->setID($list_id);
Javelin::initBehavior( Javelin::initBehavior(
@ -182,7 +188,14 @@ final class PhabricatorHomePreferencesSettingsPanel
->setText(pht('Pin Application')) ->setText(pht('Pin Application'))
->setHref($this->getPanelURI().'?add=true') ->setHref($this->getPanelURI().'?add=true')
->setWorkflow(true) ->setWorkflow(true)
->setIcon('fa-thumb-tack')); ->setIcon('fa-thumb-tack'))
->addActionLink(
id(new PHUIButtonView())
->setTag('a')
->setText(pht('Reset to Defaults'))
->setHref($this->getPanelURI().'?reset=true')
->setWorkflow(true)
->setIcon('fa-recycle'));
$box = id(new PHUIObjectBoxView()) $box = id(new PHUIObjectBoxView())
->setHeader($header) ->setHeader($header)
@ -191,4 +204,23 @@ final class PhabricatorHomePreferencesSettingsPanel
return $box; return $box;
} }
private function writePinnedApplications(
PhabricatorUserPreferences $preferences,
$pinned) {
$viewer = $this->getViewer();
$request = $this->getController()->getRequest();
$pinned_key = PhabricatorPinnedApplicationsSetting::SETTINGKEY;
$editor = id(new PhabricatorUserPreferencesEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true)
->setContinueOnMissingFields(true);
$xactions = array();
$xactions[] = $preferences->newTransaction($pinned_key, $pinned);
$editor->applyTransactions($preferences, $xactions);
}
} }

View file

@ -217,4 +217,22 @@ abstract class PhabricatorSettingsPanel extends Phobject {
->addString($this->getPanelName()); ->addString($this->getPanelName());
} }
protected function loadTargetPreferences() {
$viewer = $this->getViewer();
$user = $this->getUser();
$preferences = PhabricatorUserPreferences::loadUserPreferences($user);
PhabricatorPolicyFilter::requireCapability(
$viewer,
$preferences,
PhabricatorPolicyCapability::CAN_EDIT);
return $preferences;
}
protected function newDialog() {
return $this->getController()->newDialog();
}
} }

View file

@ -0,0 +1,33 @@
<?php
final class PhabricatorPinnedApplicationsSetting
extends PhabricatorInternalSetting {
const SETTINGKEY = 'app-pinned';
public function getSettingName() {
return pht('Pinned Applications');
}
public function getSettingDefaultValue() {
$viewer = $this->getViewer();
$applications = id(new PhabricatorApplicationQuery())
->setViewer($viewer)
->withInstalled(true)
->withUnlisted(false)
->withLaunchable(true)
->execute();
$pinned = array();
foreach ($applications as $application) {
if ($application->isPinnedByDefault($viewer)) {
$pinned[] = get_class($application);
}
}
return $pinned;
}
}

View file

@ -73,49 +73,28 @@ final class PhabricatorUserPreferences
return null; return null;
} }
$setting = id(clone $setting)
->setViewer($this->getUser());
return $setting->getSettingDefaultValue(); return $setting->getSettingDefaultValue();
} }
public function getSettingValue($key) {
if (array_key_exists($key, $this->preferences)) {
return $this->preferences[$key];
}
// TODO: If this setting set inherits from another preference set,
// we would look it up here.
return $this->getDefaultValue($key);
}
private static function getSettingObject($key) { private static function getSettingObject($key) {
$settings = PhabricatorSetting::getAllSettings(); $settings = PhabricatorSetting::getAllSettings();
return idx($settings, $key); return idx($settings, $key);
} }
public function getPinnedApplications(array $apps, PhabricatorUser $viewer) {
$pref_pinned = self::PREFERENCE_APP_PINNED;
$pinned = $this->getPreference($pref_pinned);
if ($pinned) {
return $pinned;
}
$pref_tiles = self::PREFERENCE_APP_TILES;
$tiles = $this->getPreference($pref_tiles, array());
$full_tile = 'full';
$large = array();
foreach ($apps as $app) {
$show = $app->isPinnedByDefault($viewer);
// TODO: This is legacy stuff, clean it up eventually. This approximately
// retains the old "tiles" preference.
if (isset($tiles[get_class($app)])) {
$show = ($tiles[get_class($app)] == $full_tile);
}
if ($show) {
$large[] = get_class($app);
}
}
return $large;
}
public static function filterMonospacedCSSRule($monospaced) {
// Prevent the user from doing dangerous things.
return preg_replace('([^a-z0-9 ,"./]+)i', '', $monospaced);
}
public function attachUser(PhabricatorUser $user = null) { public function attachUser(PhabricatorUser $user = null) {
$this->user = $user; $this->user = $user;
return $this; return $this;