mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-18 12:52:42 +01:00
Remove application small/hidden tiles
Summary: Ref T5176. This paves the way for the redesign by making the homepage editor thing a little more manageable/coherent. Not perfect, but we can clean it up a bit after the new design. Test Plan: Home page: {F162093} New "Pinned Applications" settings panel (this supports drag-and-drop to reorder): {F162094} Pin an app: {F162095} Unpin an app: {F162096} Reviewers: btrahan, chad Reviewed By: chad Subscribers: epriestley Maniphest Tasks: T5176 Differential Revision: https://secure.phabricator.com/D9332
This commit is contained in:
parent
09a3506821
commit
24eacaa032
7 changed files with 263 additions and 289 deletions
|
@ -100,7 +100,6 @@ return array(
|
|||
'rsrc/css/application/releeph/releeph-request-differential-create-dialog.css' => '8d8b92cd',
|
||||
'rsrc/css/application/releeph/releeph-request-typeahead.css' => '667a48ae',
|
||||
'rsrc/css/application/search/search-results.css' => 'f240504c',
|
||||
'rsrc/css/application/settings/settings.css' => 'ea8f5915',
|
||||
'rsrc/css/application/slowvote/slowvote.css' => '266df6a1',
|
||||
'rsrc/css/application/subscriptions/subscribers-list.css' => '5bb30c78',
|
||||
'rsrc/css/application/tokens/tokens.css' => '3d0f239e',
|
||||
|
@ -468,6 +467,7 @@ return array(
|
|||
'rsrc/js/core/behavior-phabricator-remarkup-assist.js' => 'c021950a',
|
||||
'rsrc/js/core/behavior-refresh-csrf.js' => '7814b593',
|
||||
'rsrc/js/core/behavior-remarkup-preview.js' => 'f7379f45',
|
||||
'rsrc/js/core/behavior-reorder-applications.js' => 'a8e3795d',
|
||||
'rsrc/js/core/behavior-reveal-content.js' => '8f24abfc',
|
||||
'rsrc/js/core/behavior-search-typeahead.js' => '86549ee3',
|
||||
'rsrc/js/core/behavior-select-on-click.js' => '0e34ca02',
|
||||
|
@ -629,6 +629,7 @@ return array(
|
|||
'javelin-behavior-releeph-request-state-change' => 'd259e7c9',
|
||||
'javelin-behavior-releeph-request-typeahead' => 'cd9e7094',
|
||||
'javelin-behavior-remarkup-preview' => 'f7379f45',
|
||||
'javelin-behavior-reorder-applications' => 'a8e3795d',
|
||||
'javelin-behavior-repository-crossreference' => '8ab282be',
|
||||
'javelin-behavior-search-reorder-queries' => '37871df4',
|
||||
'javelin-behavior-select-on-click' => '0e34ca02',
|
||||
|
@ -720,7 +721,6 @@ return array(
|
|||
'phabricator-project-tag-css' => '095c9404',
|
||||
'phabricator-remarkup-css' => '80c3a48c',
|
||||
'phabricator-search-results-css' => 'f240504c',
|
||||
'phabricator-settings-css' => 'ea8f5915',
|
||||
'phabricator-shaped-request' => '7cbe244b',
|
||||
'phabricator-side-menu-view-css' => 'c1986b85',
|
||||
'phabricator-slowvote-css' => '266df6a1',
|
||||
|
@ -1612,6 +1612,14 @@ return array(
|
|||
1 => 'javelin-dom',
|
||||
2 => 'javelin-stratcom',
|
||||
),
|
||||
'a8e3795d' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
1 => 'javelin-stratcom',
|
||||
2 => 'javelin-workflow',
|
||||
3 => 'javelin-dom',
|
||||
4 => 'phabricator-draggable-list',
|
||||
),
|
||||
'a9aaba0c' =>
|
||||
array(
|
||||
0 => 'javelin-behavior',
|
||||
|
|
|
@ -25,13 +25,10 @@ abstract class PhabricatorHomeController extends PhabricatorController {
|
|||
->setViewer($user)
|
||||
->withInstalled(true)
|
||||
->withUnlisted(false)
|
||||
->withLaunchable(true)
|
||||
->execute();
|
||||
|
||||
foreach ($applications as $key => $application) {
|
||||
if (!$application->shouldAppearInLaunchView()) {
|
||||
// Remove hidden applications (usually internal stuff).
|
||||
unset($applications[$key]);
|
||||
}
|
||||
$invisible = PhabricatorApplication::TILE_INVISIBLE;
|
||||
if ($application->getDefaultTileDisplay($user) == $invisible) {
|
||||
// Remove invisible applications (e.g., admin apps for non-admins).
|
||||
|
@ -39,115 +36,45 @@ abstract class PhabricatorHomeController extends PhabricatorController {
|
|||
}
|
||||
}
|
||||
|
||||
$status = array();
|
||||
foreach ($applications as $key => $application) {
|
||||
$status[get_class($application)] = $application->loadStatus($user);
|
||||
}
|
||||
$pinned = $user->loadPreferences()->getPinnedApplications(
|
||||
$applications,
|
||||
$user);
|
||||
|
||||
$tile_groups = array();
|
||||
$prefs = $user->loadPreferences()->getPreference(
|
||||
PhabricatorUserPreferences::PREFERENCE_APP_TILES,
|
||||
array());
|
||||
foreach ($applications as $key => $application) {
|
||||
$display = idx(
|
||||
$prefs,
|
||||
get_class($application),
|
||||
$application->getDefaultTileDisplay($user));
|
||||
$tile_groups[$display][] = $application;
|
||||
}
|
||||
// Put "Applications" at the bottom.
|
||||
$meta_app = 'PhabricatorApplicationApplications';
|
||||
$pinned = array_fuse($pinned);
|
||||
unset($pinned[$meta_app]);
|
||||
$pinned[$meta_app] = $meta_app;
|
||||
|
||||
$tile_groups = array_select_keys(
|
||||
$tile_groups,
|
||||
array(
|
||||
PhabricatorApplication::TILE_FULL,
|
||||
PhabricatorApplication::TILE_SHOW,
|
||||
PhabricatorApplication::TILE_HIDE,
|
||||
));
|
||||
|
||||
foreach ($tile_groups as $tile_display => $tile_group) {
|
||||
if (!$tile_group) {
|
||||
$tiles = array();
|
||||
foreach ($pinned as $pinned_application) {
|
||||
if (empty($applications[$pinned_application])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$is_small_tiles = ($tile_display == PhabricatorApplication::TILE_SHOW) ||
|
||||
($tile_display == PhabricatorApplication::TILE_HIDE);
|
||||
$application = $applications[$pinned_application];
|
||||
|
||||
if ($is_small_tiles) {
|
||||
$groups = PhabricatorApplication::getApplicationGroups();
|
||||
$tile_group = mgroup($tile_group, 'getApplicationGroup');
|
||||
$tile_group = array_select_keys($tile_group, array_keys($groups));
|
||||
} else {
|
||||
$tile_group = array($tile_group);
|
||||
}
|
||||
$tile = id(new PhabricatorApplicationLaunchView())
|
||||
->setApplication($application)
|
||||
->setApplicationStatus($application->loadStatus($user))
|
||||
->setUser($user);
|
||||
|
||||
$is_hide = ($tile_display == PhabricatorApplication::TILE_HIDE);
|
||||
if ($is_hide) {
|
||||
$show_item_id = celerity_generate_unique_node_id();
|
||||
$hide_item_id = celerity_generate_unique_node_id();
|
||||
|
||||
$show_item = id(new PHUIListItemView())
|
||||
->setName(pht('Show More Applications'))
|
||||
->setHref('#')
|
||||
->addSigil('reveal-content')
|
||||
->setID($show_item_id);
|
||||
|
||||
$hide_item = id(new PHUIListItemView())
|
||||
->setName(pht('Show Fewer Applications'))
|
||||
->setHref('#')
|
||||
->setStyle('display: none')
|
||||
->setID($hide_item_id)
|
||||
->addSigil('reveal-content');
|
||||
|
||||
$nav->addMenuItem($show_item);
|
||||
$tile_ids = array($hide_item_id);
|
||||
}
|
||||
|
||||
foreach ($tile_group as $group => $application_list) {
|
||||
$tiles = array();
|
||||
foreach ($application_list as $key => $application) {
|
||||
$tile = id(new PhabricatorApplicationLaunchView())
|
||||
->setApplication($application)
|
||||
->setApplicationStatus(
|
||||
idx($status, get_class($application), array()))
|
||||
->setUser($user);
|
||||
|
||||
$tiles[] = $tile;
|
||||
}
|
||||
|
||||
$group_id = celerity_generate_unique_node_id();
|
||||
$tile_ids[] = $group_id;
|
||||
$nav->addCustomBlock(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'application-tile-group',
|
||||
'id' => $group_id,
|
||||
'style' => ($is_hide ? 'display: none' : null),
|
||||
),
|
||||
mpull($tiles, 'render')));
|
||||
}
|
||||
|
||||
if ($is_hide) {
|
||||
Javelin::initBehavior('phabricator-reveal-content');
|
||||
|
||||
$show_item->setMetadata(
|
||||
array(
|
||||
'showIDs' => $tile_ids,
|
||||
'hideIDs' => array($show_item_id),
|
||||
));
|
||||
$hide_item->setMetadata(
|
||||
array(
|
||||
'showIDs' => array($show_item_id),
|
||||
'hideIDs' => $tile_ids,
|
||||
));
|
||||
$nav->addMenuItem($hide_item);
|
||||
}
|
||||
$tiles[] = $tile;
|
||||
}
|
||||
|
||||
$nav->addCustomBlock(
|
||||
phutil_tag(
|
||||
'div',
|
||||
array(
|
||||
'class' => 'application-tile-group',
|
||||
),
|
||||
$tiles));
|
||||
|
||||
$nav->addFilter(
|
||||
'',
|
||||
pht('Customize Applications...'),
|
||||
'/settings/panel/home/');
|
||||
|
||||
$nav->addClass('phabricator-side-menu-home');
|
||||
$nav->selectFilter(null);
|
||||
|
||||
|
|
|
@ -19,194 +19,179 @@ final class PhabricatorSettingsPanelHomePreferences
|
|||
$user = $request->getUser();
|
||||
$preferences = $user->loadPreferences();
|
||||
|
||||
require_celerity_resource('phabricator-settings-css');
|
||||
|
||||
$apps = id(new PhabricatorApplicationQuery())
|
||||
->setViewer($user)
|
||||
->withInstalled(true)
|
||||
->withUnlisted(false)
|
||||
->withLaunchable(true)
|
||||
->execute();
|
||||
|
||||
$pref_tiles = PhabricatorUserPreferences::PREFERENCE_APP_TILES;
|
||||
$tiles = $preferences->getPreference($pref_tiles, array());
|
||||
$pinned = $preferences->getPinnedApplications($apps, $user);
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$values = $request->getArr('tile');
|
||||
$app_list = array();
|
||||
foreach ($pinned as $app) {
|
||||
if (isset($apps[$app])) {
|
||||
$app_list[$app] = $apps[$app];
|
||||
}
|
||||
}
|
||||
|
||||
if ($request->getBool('add')) {
|
||||
$options = array();
|
||||
foreach ($apps as $app) {
|
||||
$key = get_class($app);
|
||||
$value = idx($values, $key);
|
||||
switch ($value) {
|
||||
case PhabricatorApplication::TILE_FULL:
|
||||
case PhabricatorApplication::TILE_SHOW:
|
||||
case PhabricatorApplication::TILE_HIDE:
|
||||
$tiles[$key] = $value;
|
||||
break;
|
||||
default:
|
||||
unset($tiles[$key]);
|
||||
break;
|
||||
$options[get_class($app)] = $app->getName();
|
||||
}
|
||||
asort($options);
|
||||
|
||||
unset($options['PhabricatorApplicationApplications']);
|
||||
|
||||
if ($request->isFormPost()) {
|
||||
$pin = $request->getStr('pin');
|
||||
if (isset($options[$pin]) && !in_array($pin, $pinned)) {
|
||||
$pinned[] = $pin;
|
||||
$preferences->setPreference(
|
||||
PhabricatorUserPreferences::PREFERENCE_APP_PINNED,
|
||||
$pinned);
|
||||
$preferences->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getPanelURI());
|
||||
}
|
||||
}
|
||||
$preferences->setPreference($pref_tiles, $tiles);
|
||||
|
||||
$options_control = id(new AphrontFormSelectControl())
|
||||
->setName('pin')
|
||||
->setLabel(pht('Application'))
|
||||
->setOptions($options)
|
||||
->setDisabledOptions(array_keys($app_list));
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($user)
|
||||
->addHiddenInput('add', 'true')
|
||||
->appendRemarkupInstructions(
|
||||
pht('Choose an application to pin to your home page.'))
|
||||
->appendChild($options_control);
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->setWidth(AphrontDialogView::WIDTH_FORM)
|
||||
->setTitle(pht('Pin Application'))
|
||||
->appendChild($form->buildLayoutView())
|
||||
->addSubmitButton(pht('Pin Application'))
|
||||
->addCancelButton($this->getPanelURI());
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
|
||||
$unpin = $request->getStr('unpin');
|
||||
if ($unpin) {
|
||||
$app = idx($apps, $unpin);
|
||||
if ($app) {
|
||||
if ($request->isFormPost()) {
|
||||
$pinned = array_diff($pinned, array($unpin));
|
||||
$preferences->setPreference(
|
||||
PhabricatorUserPreferences::PREFERENCE_APP_PINNED,
|
||||
$pinned);
|
||||
$preferences->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getPanelURI());
|
||||
}
|
||||
|
||||
$dialog = id(new AphrontDialogView())
|
||||
->setUser($user)
|
||||
->setTitle(pht('Unpin Application'))
|
||||
->appendParagraph(
|
||||
pht(
|
||||
'Unpin the %s application from your home page?',
|
||||
phutil_tag('strong', array(), $app->getName())))
|
||||
->addSubmitButton(pht('Unpin Application'))
|
||||
->addCanceLButton($this->getPanelURI());
|
||||
|
||||
return id(new AphrontDialogResponse())->setDialog($dialog);
|
||||
}
|
||||
}
|
||||
|
||||
$order = $request->getStrList('order');
|
||||
if ($order && $request->validateCSRF()) {
|
||||
$preferences->setPreference(
|
||||
PhabricatorUserPreferences::PREFERENCE_APP_PINNED,
|
||||
$order);
|
||||
$preferences->save();
|
||||
|
||||
return id(new AphrontRedirectResponse())
|
||||
->setURI($this->getPanelURI('?saved=true'));
|
||||
->setURI($this->getPanelURI());
|
||||
}
|
||||
|
||||
$form = id(new AphrontFormView())
|
||||
->setUser($user);
|
||||
$list_id = celerity_generate_unique_node_id();
|
||||
|
||||
$group_map = PhabricatorApplication::getApplicationGroups();
|
||||
$list = id(new PHUIObjectItemListView())
|
||||
->setUser($user)
|
||||
->setID($list_id)
|
||||
->setFlush(true);
|
||||
|
||||
$output = array();
|
||||
Javelin::initBehavior(
|
||||
'reorder-applications',
|
||||
array(
|
||||
'listID' => $list_id,
|
||||
'panelURI' => $this->getPanelURI(),
|
||||
));
|
||||
|
||||
$app_groups = mgroup($apps, 'getApplicationGroup');
|
||||
$app_groups = array_select_keys($app_groups, array_keys($group_map));
|
||||
|
||||
foreach ($app_groups as $group => $apps) {
|
||||
$group_name = $group_map[$group];
|
||||
$rows = array();
|
||||
|
||||
foreach ($apps as $app) {
|
||||
if (!$app->shouldAppearInLaunchView()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$default = $app->getDefaultTileDisplay($user);
|
||||
if ($default == PhabricatorApplication::TILE_INVISIBLE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$default_name = PhabricatorApplication::getTileDisplayName($default);
|
||||
|
||||
$hide = PhabricatorApplication::TILE_HIDE;
|
||||
$show = PhabricatorApplication::TILE_SHOW;
|
||||
$full = PhabricatorApplication::TILE_FULL;
|
||||
|
||||
$key = get_class($app);
|
||||
|
||||
$default_radio_button_status =
|
||||
(idx($tiles, $key, 'default') == 'default') ? 'checked' : null;
|
||||
|
||||
$hide_radio_button_status =
|
||||
(idx($tiles, $key, 'default') == $hide) ? 'checked' : null;
|
||||
|
||||
$show_radio_button_status =
|
||||
(idx($tiles, $key, 'default') == $show) ? 'checked' : null;
|
||||
|
||||
$full_radio_button_status =
|
||||
(idx($tiles, $key, 'default') == $full) ? 'checked' : null;
|
||||
|
||||
|
||||
$default_radio_button = phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'radio',
|
||||
'name' => 'tile['.$key.']',
|
||||
'value' => 'default',
|
||||
'checked' => $default_radio_button_status,
|
||||
));
|
||||
|
||||
$hide_radio_button = phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'radio',
|
||||
'name' => 'tile['.$key.']',
|
||||
'value' => $hide,
|
||||
'checked' => $hide_radio_button_status,
|
||||
));
|
||||
|
||||
$show_radio_button = phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'radio',
|
||||
'name' => 'tile['.$key.']',
|
||||
'value' => $show,
|
||||
'checked' => $show_radio_button_status,
|
||||
));
|
||||
|
||||
$full_radio_button = phutil_tag(
|
||||
'input',
|
||||
array(
|
||||
'type' => 'radio',
|
||||
'name' => 'tile['.$key.']',
|
||||
'value' => $full,
|
||||
'checked' => $full_radio_button_status,
|
||||
));
|
||||
|
||||
$desc = $app->getShortDescription();
|
||||
$app_column = hsprintf(
|
||||
"<strong>%s</strong><br/ >%s, <em>Default: %s</em>",
|
||||
$app->getName(), $desc, $default_name);
|
||||
|
||||
$rows[] = array(
|
||||
$app_column,
|
||||
$default_radio_button,
|
||||
$hide_radio_button,
|
||||
$show_radio_button,
|
||||
$full_radio_button,
|
||||
);
|
||||
}
|
||||
|
||||
if (empty($rows)) {
|
||||
foreach ($app_list as $key => $application) {
|
||||
if ($key == 'PhabricatorApplicationApplications') {
|
||||
continue;
|
||||
}
|
||||
|
||||
$table = new AphrontTableView($rows);
|
||||
$icon = $application->getIconName();
|
||||
if (!$icon) {
|
||||
$icon = 'application';
|
||||
}
|
||||
|
||||
$table
|
||||
->setClassName('phabricator-settings-homepagetable')
|
||||
->setHeaders(
|
||||
array(
|
||||
pht('Applications'),
|
||||
pht('Default'),
|
||||
pht('Hidden'),
|
||||
pht('Small'),
|
||||
pht('Large'),
|
||||
))
|
||||
->setColumnClasses(
|
||||
array(
|
||||
'',
|
||||
'fixed',
|
||||
'fixed',
|
||||
'fixed',
|
||||
'fixed',
|
||||
));
|
||||
$icon_view = javelin_tag(
|
||||
'span',
|
||||
array(
|
||||
'class' => 'phui-icon-view '.
|
||||
'sprite-apps-large apps-'.$icon.'-dark-large',
|
||||
'aural' => false,
|
||||
),
|
||||
'');
|
||||
|
||||
$item = id(new PHUIObjectItemView())
|
||||
->setHeader($application->getName())
|
||||
->setImageIcon($icon_view)
|
||||
->addAttribute($application->getShortDescription())
|
||||
->setGrippable(true);
|
||||
|
||||
$panel = id(new PHUIObjectBoxView())
|
||||
->setHeaderText($group_name)
|
||||
->appendChild($table);
|
||||
$item->addAction(
|
||||
id(new PHUIListItemView())
|
||||
->setIcon('fa-times')
|
||||
->setHref($this->getPanelURI().'?unpin='.$key)
|
||||
->setWorkflow(true));
|
||||
|
||||
$output[] = $panel;
|
||||
}
|
||||
$item->addSigil('pinned-application');
|
||||
$item->setMetadata(
|
||||
array(
|
||||
'applicationClass' => $key,
|
||||
));
|
||||
|
||||
$save_button =
|
||||
id(new AphrontFormSubmitControl())
|
||||
->setValue(pht('Save Preferences'));
|
||||
|
||||
$output[] = id(new PHUIBoxView())
|
||||
->addPadding(PHUI::PADDING_LARGE)
|
||||
->addClass('phabricator-settings-homepagetable-button')
|
||||
->appendChild($save_button);
|
||||
|
||||
$form->appendChild($output);
|
||||
|
||||
$error_view = null;
|
||||
if ($request->getStr('saved') === 'true') {
|
||||
$error_view = id(new AphrontErrorView())
|
||||
->setTitle(pht('Preferences Saved'))
|
||||
->setSeverity(AphrontErrorView::SEVERITY_NOTICE)
|
||||
->setErrors(array(pht('Your preferences have been saved.')));
|
||||
$list->addItem($item);
|
||||
}
|
||||
|
||||
$header = id(new PHUIHeaderView())
|
||||
->setHeader(pht('Home Page Preferences'));
|
||||
->setHeader(pht('Pinned Applications'))
|
||||
->addActionLink(
|
||||
id(new PHUIButtonView())
|
||||
->setTag('a')
|
||||
->setText(pht('Pin Application'))
|
||||
->setHref($this->getPanelURI().'?add=true')
|
||||
->setWorkflow(true)
|
||||
->setIcon(
|
||||
id(new PHUIIconView())
|
||||
->setIconFont('fa-thumb-tack')));
|
||||
|
||||
$form = id(new PHUIBoxView())
|
||||
->addClass('phabricator-settings-homepagetable-wrap')
|
||||
->appendChild($form);
|
||||
$box = id(new PHUIObjectBoxView())
|
||||
->setHeader($header)
|
||||
->appendChild($list);
|
||||
|
||||
return array($header, $error_view, $form);
|
||||
return $box;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ final class PhabricatorUserPreferences extends PhabricatorUserDAO {
|
|||
const PREFERENCE_NAV_COLLAPSED = 'nav-collapsed';
|
||||
const PREFERENCE_NAV_WIDTH = 'nav-width';
|
||||
const PREFERENCE_APP_TILES = 'app-tiles';
|
||||
const PREFERENCE_APP_PINNED = 'app-pinned';
|
||||
|
||||
const PREFERENCE_DIFF_FILETREE = 'diff-filetree';
|
||||
|
||||
|
@ -55,4 +56,31 @@ final class PhabricatorUserPreferences extends PhabricatorUserDAO {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getPinnedApplications(array $apps, PhabricatorUser $viewer) {
|
||||
$pref_pinned = PhabricatorUserPreferences::PREFERENCE_APP_PINNED;
|
||||
$pinned = $this->getPreference($pref_pinned);
|
||||
|
||||
if ($pinned) {
|
||||
return $pinned;
|
||||
}
|
||||
|
||||
$pref_tiles = PhabricatorUserPreferences::PREFERENCE_APP_TILES;
|
||||
$tiles = $this->getPreference($pref_tiles, array());
|
||||
|
||||
$large = array();
|
||||
foreach ($apps as $app) {
|
||||
$tile = $app->getDefaultTileDisplay($viewer);
|
||||
|
||||
if (isset($tiles[get_class($app)])) {
|
||||
$tile = $tiles[get_class($app)];
|
||||
}
|
||||
|
||||
if ($tile == PhabricatorApplication::TILE_FULL) {
|
||||
$large[] = get_class($app);
|
||||
}
|
||||
}
|
||||
|
||||
return $large;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ final class AphrontFormSelectControl extends AphrontFormControl {
|
|||
}
|
||||
|
||||
private $options;
|
||||
private $disabledOptions = array();
|
||||
|
||||
public function setOptions(array $options) {
|
||||
$this->options = $options;
|
||||
|
@ -17,6 +18,11 @@ final class AphrontFormSelectControl extends AphrontFormControl {
|
|||
return $this->options;
|
||||
}
|
||||
|
||||
public function setDisabledOptions(array $disabled) {
|
||||
$this->disabledOptions = $disabled;
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function renderInput() {
|
||||
return self::renderSelectTag(
|
||||
$this->getValue(),
|
||||
|
@ -25,15 +31,17 @@ final class AphrontFormSelectControl extends AphrontFormControl {
|
|||
'name' => $this->getName(),
|
||||
'disabled' => $this->getDisabled() ? 'disabled' : null,
|
||||
'id' => $this->getID(),
|
||||
));
|
||||
),
|
||||
$this->disabledOptions);
|
||||
}
|
||||
|
||||
public static function renderSelectTag(
|
||||
$selected,
|
||||
array $options,
|
||||
array $attrs = array()) {
|
||||
array $attrs = array(),
|
||||
array $disabled = array()) {
|
||||
|
||||
$option_tags = self::renderOptions($selected, $options);
|
||||
$option_tags = self::renderOptions($selected, $options, $disabled);
|
||||
|
||||
return javelin_tag(
|
||||
'select',
|
||||
|
@ -41,7 +49,12 @@ final class AphrontFormSelectControl extends AphrontFormControl {
|
|||
$option_tags);
|
||||
}
|
||||
|
||||
private static function renderOptions($selected, array $options) {
|
||||
private static function renderOptions(
|
||||
$selected,
|
||||
array $options,
|
||||
array $disabled = array()) {
|
||||
$disabled = array_fuse($disabled);
|
||||
|
||||
$tags = array();
|
||||
foreach ($options as $value => $thing) {
|
||||
if (is_array($thing)) {
|
||||
|
@ -57,6 +70,7 @@ final class AphrontFormSelectControl extends AphrontFormControl {
|
|||
array(
|
||||
'selected' => ($value == $selected) ? 'selected' : null,
|
||||
'value' => $value,
|
||||
'disabled' => isset($disabled[$value]) ? 'disabled' : null,
|
||||
),
|
||||
$thing);
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/**
|
||||
* @provides phabricator-settings-css
|
||||
*/
|
||||
|
||||
.phabricator-settings-homepagetable .fixed {
|
||||
width: 48px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.phabricator-settings-homepagetable td em {
|
||||
color: {$lightgreytext};
|
||||
}
|
||||
|
||||
.phabricator-settings-homepagetable-button .aphront-form-input {
|
||||
margin: 0;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.phabricator-settings-homepagetable-button .aphront-form-control {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.phabricator-settings-homepagetable-wrap .phui-form-view {
|
||||
padding: 0;
|
||||
}
|
37
webroot/rsrc/js/core/behavior-reorder-applications.js
Normal file
37
webroot/rsrc/js/core/behavior-reorder-applications.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @provides javelin-behavior-reorder-applications
|
||||
* @requires javelin-behavior
|
||||
* javelin-stratcom
|
||||
* javelin-workflow
|
||||
* javelin-dom
|
||||
* phabricator-draggable-list
|
||||
*/
|
||||
|
||||
JX.behavior('reorder-applications', function(config) {
|
||||
|
||||
var root = JX.$(config.listID);
|
||||
|
||||
var list = new JX.DraggableList('pinned-application', root)
|
||||
.setFindItemsHandler(function() {
|
||||
return JX.DOM.scry(root, 'li', 'pinned-application');
|
||||
});
|
||||
|
||||
list.listen('didDrop', function(node, after) {
|
||||
var nodes = list.findItems();
|
||||
var order = [];
|
||||
var key;
|
||||
for (var ii = 0; ii < nodes.length; ii++) {
|
||||
key = JX.Stratcom.getData(nodes[ii]).applicationClass;
|
||||
if (key) {
|
||||
order.push(key);
|
||||
}
|
||||
}
|
||||
|
||||
list.lock();
|
||||
JX.DOM.alterClass(node, 'drag-sending', true);
|
||||
|
||||
new JX.Workflow(config.panelURI, {order: order.join()})
|
||||
.start();
|
||||
});
|
||||
|
||||
});
|
Loading…
Reference in a new issue