mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-01 19:22:42 +01:00
AphrontPagerView and UIExamples.
This commit is contained in:
parent
d3766cad98
commit
f76c3bbc22
15 changed files with 590 additions and 18 deletions
|
@ -61,6 +61,15 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/css/aphront/headsup-action-list-view.css',
|
'disk' => '/rsrc/css/aphront/headsup-action-list-view.css',
|
||||||
),
|
),
|
||||||
|
'aphront-pager-view-css' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/73ec8cd5/rsrc/css/aphront/pager-view.css',
|
||||||
|
'type' => 'css',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/css/aphront/pager-view.css',
|
||||||
|
),
|
||||||
'aphront-panel-view-css' =>
|
'aphront-panel-view-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/63672373/rsrc/css/aphront/panel-view.css',
|
'uri' => '/res/63672373/rsrc/css/aphront/panel-view.css',
|
||||||
|
@ -90,7 +99,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'aphront-table-view-css' =>
|
'aphront-table-view-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/7bf17fb8/rsrc/css/aphront/table-view.css',
|
'uri' => '/res/03724b05/rsrc/css/aphront/table-view.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -288,6 +297,15 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'disk' => '/rsrc/css/application/people/profile.css',
|
'disk' => '/rsrc/css/application/people/profile.css',
|
||||||
),
|
),
|
||||||
|
'phabricator-ui-example-css' =>
|
||||||
|
array(
|
||||||
|
'uri' => '/res/b2593f53/rsrc/css/application/uiexample/example.css',
|
||||||
|
'type' => 'css',
|
||||||
|
'requires' =>
|
||||||
|
array(
|
||||||
|
),
|
||||||
|
'disk' => '/rsrc/css/application/uiexample/example.css',
|
||||||
|
),
|
||||||
'phabricator-core-buttons-css' =>
|
'phabricator-core-buttons-css' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/53b4f712/rsrc/css/core/buttons.css',
|
'uri' => '/res/53b4f712/rsrc/css/core/buttons.css',
|
||||||
|
@ -455,7 +473,7 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'javelin-behavior-diffusion-pull-lastmodified' =>
|
'javelin-behavior-diffusion-pull-lastmodified' =>
|
||||||
array(
|
array(
|
||||||
'uri' => '/res/1c95a58e/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
|
'uri' => '/res/6a5e7374/rsrc/js/application/diffusion/behavior-pull-lastmodified.js',
|
||||||
'type' => 'js',
|
'type' => 'js',
|
||||||
'requires' =>
|
'requires' =>
|
||||||
array(
|
array(
|
||||||
|
@ -571,7 +589,7 @@ celerity_register_resource_map(array(
|
||||||
), array (
|
), array (
|
||||||
'packages' =>
|
'packages' =>
|
||||||
array (
|
array (
|
||||||
'aa9bbfd1' =>
|
'930fd839' =>
|
||||||
array (
|
array (
|
||||||
'name' => 'core.pkg.css',
|
'name' => 'core.pkg.css',
|
||||||
'symbols' =>
|
'symbols' =>
|
||||||
|
@ -591,7 +609,7 @@ celerity_register_resource_map(array(
|
||||||
12 => 'phabricator-remarkup-css',
|
12 => 'phabricator-remarkup-css',
|
||||||
13 => 'syntax-highlighting-css',
|
13 => 'syntax-highlighting-css',
|
||||||
),
|
),
|
||||||
'uri' => '/res/pkg/aa9bbfd1/core.pkg.css',
|
'uri' => '/res/pkg/930fd839/core.pkg.css',
|
||||||
'type' => 'css',
|
'type' => 'css',
|
||||||
),
|
),
|
||||||
'76f3c1f8' =>
|
'76f3c1f8' =>
|
||||||
|
@ -638,20 +656,20 @@ celerity_register_resource_map(array(
|
||||||
),
|
),
|
||||||
'reverse' =>
|
'reverse' =>
|
||||||
array (
|
array (
|
||||||
'phabricator-core-css' => 'aa9bbfd1',
|
'phabricator-core-css' => '930fd839',
|
||||||
'phabricator-core-buttons-css' => 'aa9bbfd1',
|
'phabricator-core-buttons-css' => '930fd839',
|
||||||
'phabricator-standard-page-view' => 'aa9bbfd1',
|
'phabricator-standard-page-view' => '930fd839',
|
||||||
'aphront-dialog-view-css' => 'aa9bbfd1',
|
'aphront-dialog-view-css' => '930fd839',
|
||||||
'aphront-form-view-css' => 'aa9bbfd1',
|
'aphront-form-view-css' => '930fd839',
|
||||||
'aphront-panel-view-css' => 'aa9bbfd1',
|
'aphront-panel-view-css' => '930fd839',
|
||||||
'aphront-side-nav-view-css' => 'aa9bbfd1',
|
'aphront-side-nav-view-css' => '930fd839',
|
||||||
'aphront-table-view-css' => 'aa9bbfd1',
|
'aphront-table-view-css' => '930fd839',
|
||||||
'aphront-crumbs-view-css' => 'aa9bbfd1',
|
'aphront-crumbs-view-css' => '930fd839',
|
||||||
'aphront-tokenizer-control-css' => 'aa9bbfd1',
|
'aphront-tokenizer-control-css' => '930fd839',
|
||||||
'aphront-typeahead-control-css' => 'aa9bbfd1',
|
'aphront-typeahead-control-css' => '930fd839',
|
||||||
'phabricator-directory-css' => 'aa9bbfd1',
|
'phabricator-directory-css' => '930fd839',
|
||||||
'phabricator-remarkup-css' => 'aa9bbfd1',
|
'phabricator-remarkup-css' => '930fd839',
|
||||||
'syntax-highlighting-css' => 'aa9bbfd1',
|
'syntax-highlighting-css' => '930fd839',
|
||||||
'differential-core-view-css' => '76f3c1f8',
|
'differential-core-view-css' => '76f3c1f8',
|
||||||
'differential-changeset-view-css' => '76f3c1f8',
|
'differential-changeset-view-css' => '76f3c1f8',
|
||||||
'differential-revision-detail-css' => '76f3c1f8',
|
'differential-revision-detail-css' => '76f3c1f8',
|
||||||
|
|
|
@ -41,6 +41,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
|
'AphrontMySQLDatabaseConnection' => 'storage/connection/mysql',
|
||||||
'AphrontNullView' => 'view/null',
|
'AphrontNullView' => 'view/null',
|
||||||
'AphrontPageView' => 'view/page/base',
|
'AphrontPageView' => 'view/page/base',
|
||||||
|
'AphrontPagerView' => 'view/control/pager',
|
||||||
'AphrontPanelView' => 'view/layout/panel',
|
'AphrontPanelView' => 'view/layout/panel',
|
||||||
'AphrontQueryConnectionException' => 'storage/exception/connection',
|
'AphrontQueryConnectionException' => 'storage/exception/connection',
|
||||||
'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost',
|
'AphrontQueryConnectionLostException' => 'storage/exception/connectionlost',
|
||||||
|
@ -385,6 +386,10 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/iterator',
|
'PhabricatorTimelineIterator' => 'infrastructure/daemon/timeline/cursor/iterator',
|
||||||
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
|
'PhabricatorTypeaheadCommonDatasourceController' => 'applications/typeahead/controller/common',
|
||||||
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
|
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/base',
|
||||||
|
'PhabricatorUIExample' => 'applications/uiexample/examples/base',
|
||||||
|
'PhabricatorUIExampleController' => 'applications/uiexample/controller/base',
|
||||||
|
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/render',
|
||||||
|
'PhabricatorUIPagerExample' => 'applications/uiexample/examples/pager',
|
||||||
'PhabricatorUser' => 'applications/people/storage/user',
|
'PhabricatorUser' => 'applications/people/storage/user',
|
||||||
'PhabricatorUserDAO' => 'applications/people/storage/base',
|
'PhabricatorUserDAO' => 'applications/people/storage/base',
|
||||||
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
|
'PhabricatorUserOAuthInfo' => 'applications/people/storage/useroauthinfo',
|
||||||
|
@ -453,6 +458,7 @@ phutil_register_library_map(array(
|
||||||
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
|
'AphrontMySQLDatabaseConnection' => 'AphrontDatabaseConnection',
|
||||||
'AphrontNullView' => 'AphrontView',
|
'AphrontNullView' => 'AphrontView',
|
||||||
'AphrontPageView' => 'AphrontView',
|
'AphrontPageView' => 'AphrontView',
|
||||||
|
'AphrontPagerView' => 'AphrontView',
|
||||||
'AphrontPanelView' => 'AphrontView',
|
'AphrontPanelView' => 'AphrontView',
|
||||||
'AphrontQueryConnectionException' => 'AphrontQueryException',
|
'AphrontQueryConnectionException' => 'AphrontQueryException',
|
||||||
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
|
'AphrontQueryConnectionLostException' => 'AphrontQueryRecoverableException',
|
||||||
|
@ -714,6 +720,9 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
|
'PhabricatorTimelineEventData' => 'PhabricatorTimelineDAO',
|
||||||
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
|
'PhabricatorTypeaheadCommonDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
|
||||||
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
|
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
|
||||||
|
'PhabricatorUIExampleController' => 'PhabricatorController',
|
||||||
|
'PhabricatorUIExampleRenderController' => 'PhabricatorUIExampleController',
|
||||||
|
'PhabricatorUIPagerExample' => 'PhabricatorUIExample',
|
||||||
'PhabricatorUser' => 'PhabricatorUserDAO',
|
'PhabricatorUser' => 'PhabricatorUserDAO',
|
||||||
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
|
'PhabricatorUserDAO' => 'PhabricatorLiskDAO',
|
||||||
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
|
'PhabricatorUserOAuthInfo' => 'PhabricatorUserDAO',
|
||||||
|
|
|
@ -245,6 +245,12 @@ class AphrontDefaultApplicationConfiguration
|
||||||
'/preferences/' => array(
|
'/preferences/' => array(
|
||||||
'$' => 'PhabricatorEditPreferencesController'
|
'$' => 'PhabricatorEditPreferencesController'
|
||||||
),
|
),
|
||||||
|
|
||||||
|
'/uiexample/' => array(
|
||||||
|
'$' => 'PhabricatorUIExampleRenderController',
|
||||||
|
'view/(?P<class>[^/]+)/$' => 'PhabricatorUIExampleRenderController',
|
||||||
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorUIExampleController extends PhabricatorController {
|
||||||
|
|
||||||
|
public function buildStandardPageResponse($view, array $data) {
|
||||||
|
$page = $this->buildStandardPageView();
|
||||||
|
|
||||||
|
$page->setApplicationName('UI Examples');
|
||||||
|
$page->setBaseURI('/uiexample/');
|
||||||
|
$page->setTitle(idx($data, 'title'));
|
||||||
|
$page->setGlyph("\xE2\x8F\x9A");
|
||||||
|
$page->appendChild($view);
|
||||||
|
|
||||||
|
$response = new AphrontWebpageResponse();
|
||||||
|
return $response->setContent($page->render());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/applications/uiexample/controller/base/__init__.php
Normal file
15
src/applications/uiexample/controller/base/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||||
|
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorUIExampleController.php');
|
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorUIExampleRenderController
|
||||||
|
extends PhabricatorUIExampleController {
|
||||||
|
|
||||||
|
private $class;
|
||||||
|
|
||||||
|
public function willProcessRequest(array $data) {
|
||||||
|
$this->class = idx($data, 'class');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function processRequest() {
|
||||||
|
|
||||||
|
$classes = id(new PhutilSymbolLoader())
|
||||||
|
->setAncestorClass('PhabricatorUIExample')
|
||||||
|
->selectAndLoadSymbols();
|
||||||
|
$classes = ipull($classes, 'name', 'name');
|
||||||
|
|
||||||
|
$selected = null;
|
||||||
|
foreach ($classes as $class => $ignored) {
|
||||||
|
$classes[$class] = newv($class, array());
|
||||||
|
if ($this->class == $class) {
|
||||||
|
$selected = $class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$selected) {
|
||||||
|
reset($classes);
|
||||||
|
$selected = key($classes);
|
||||||
|
}
|
||||||
|
|
||||||
|
$nav = new AphrontSideNavView();
|
||||||
|
|
||||||
|
foreach ($classes as $class => $obj) {
|
||||||
|
$name = $obj->getName();
|
||||||
|
|
||||||
|
$nav->addNavItem(
|
||||||
|
phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => '/uiexample/view/'.$name.'/',
|
||||||
|
'class' => ($selected == $class)
|
||||||
|
? 'aphront-side-nav-selected'
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
phutil_escape_html($obj->getName())));
|
||||||
|
}
|
||||||
|
|
||||||
|
require_celerity_resource('phabricator-ui-example-css');
|
||||||
|
|
||||||
|
$example = $classes[$selected];
|
||||||
|
$example->setRequest($this->getRequest());
|
||||||
|
|
||||||
|
|
||||||
|
$nav->appendChild(
|
||||||
|
'<div class="phabricator-ui-example-header">'.
|
||||||
|
'<h1 class="phabricator-ui-example-name">'.
|
||||||
|
phutil_escape_html($example->getName()).
|
||||||
|
' ('.get_class($example).')'.
|
||||||
|
'</h1>'.
|
||||||
|
'<p class="phabricator-ui-example-description">'
|
||||||
|
.$example->getDescription().
|
||||||
|
'</p>'.
|
||||||
|
'</div>');
|
||||||
|
|
||||||
|
$nav->appendChild($example->renderExample());
|
||||||
|
|
||||||
|
return $this->buildStandardPageResponse(
|
||||||
|
$nav,
|
||||||
|
array(
|
||||||
|
'title' => 'UI Example',
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
18
src/applications/uiexample/controller/render/__init__.php
Normal file
18
src/applications/uiexample/controller/render/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/uiexample/controller/base');
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/sidenav');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
phutil_require_module('phutil', 'symbols');
|
||||||
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorUIExampleRenderController.php');
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
abstract class PhabricatorUIExample {
|
||||||
|
|
||||||
|
private $request;
|
||||||
|
|
||||||
|
public function setRequest($request) {
|
||||||
|
$this->request = $request;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequest() {
|
||||||
|
return $this->request;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract public function getName();
|
||||||
|
abstract public function getDescription();
|
||||||
|
abstract public function renderExample();
|
||||||
|
|
||||||
|
}
|
10
src/applications/uiexample/examples/base/__init__.php
Normal file
10
src/applications/uiexample/examples/base/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorUIExample.php');
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PhabricatorUIPagerExample extends PhabricatorUIExample {
|
||||||
|
|
||||||
|
public function getName() {
|
||||||
|
return 'Pager';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDescription() {
|
||||||
|
return 'Use <tt>AphrontPagerView</tt> to create a control which allows '.
|
||||||
|
'users to paginate through large amounts of content.';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderExample() {
|
||||||
|
|
||||||
|
$request = $this->getRequest();
|
||||||
|
|
||||||
|
$offset = (int)$request->getInt('offset');
|
||||||
|
$page_size = 20;
|
||||||
|
$item_count = 173;
|
||||||
|
|
||||||
|
$rows = array();
|
||||||
|
for ($ii = $offset; $ii < min($item_count, $offset + $page_size); $ii++) {
|
||||||
|
$rows[] = array(
|
||||||
|
'Item #'.($ii + 1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table = new AphrontTableView($rows);
|
||||||
|
$table->setHeaders(
|
||||||
|
array(
|
||||||
|
'Item',
|
||||||
|
));
|
||||||
|
$panel = new AphrontPanelView();
|
||||||
|
$panel->appendChild($table);
|
||||||
|
|
||||||
|
$panel->appendChild(
|
||||||
|
'<p class="phabricator-ui-example-note">'.
|
||||||
|
'Use <tt>AphrontPagerView</tt> to render a pager element.'.
|
||||||
|
'</p>');
|
||||||
|
|
||||||
|
$pager = new AphrontPagerView();
|
||||||
|
$pager->setPageSize($page_size);
|
||||||
|
$pager->setOffset($offset);
|
||||||
|
$pager->setCount($item_count);
|
||||||
|
$pager->setURI($request->getRequestURI(), 'offset');
|
||||||
|
$panel->appendChild($pager);
|
||||||
|
|
||||||
|
$panel->appendChild(
|
||||||
|
'<p class="phabricator-ui-example-note">'.
|
||||||
|
'You can show more or fewer pages of surrounding context.'.
|
||||||
|
'</p>');
|
||||||
|
|
||||||
|
$many_pages_pager = new AphrontPagerView();
|
||||||
|
$many_pages_pager->setPageSize($page_size);
|
||||||
|
$many_pages_pager->setOffset($offset);
|
||||||
|
$many_pages_pager->setCount($item_count);
|
||||||
|
$many_pages_pager->setURI($request->getRequestURI(), 'offset');
|
||||||
|
$many_pages_pager->setSurroundingPages(7);
|
||||||
|
$panel->appendChild($many_pages_pager);
|
||||||
|
|
||||||
|
$panel->appendChild(
|
||||||
|
'<p class="phabricator-ui-example-note">'.
|
||||||
|
'When it is prohibitively expensive or complex to attain a complete '.
|
||||||
|
'count of the items, you can select one extra item and set '.
|
||||||
|
'<tt>hasMorePages(true)</tt> if it exists, creating an inexact pager.'.
|
||||||
|
'</p>');
|
||||||
|
|
||||||
|
$inexact_pager = new AphrontPagerView();
|
||||||
|
$inexact_pager->setPageSize($page_size);
|
||||||
|
$inexact_pager->setOffset($offset);
|
||||||
|
$inexact_pager->setHasMorePages($offset < ($item_count - $page_size));
|
||||||
|
$inexact_pager->setURI($request->getRequestURI(), 'offset');
|
||||||
|
$panel->appendChild($inexact_pager);
|
||||||
|
|
||||||
|
return $panel;
|
||||||
|
}
|
||||||
|
}
|
15
src/applications/uiexample/examples/pager/__init__.php
Normal file
15
src/applications/uiexample/examples/pager/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'applications/uiexample/examples/base');
|
||||||
|
phutil_require_module('phabricator', 'view/control/pager');
|
||||||
|
phutil_require_module('phabricator', 'view/control/table');
|
||||||
|
phutil_require_module('phabricator', 'view/layout/panel');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('PhabricatorUIPagerExample.php');
|
171
src/view/control/pager/AphrontPagerView.php
Normal file
171
src/view/control/pager/AphrontPagerView.php
Normal file
|
@ -0,0 +1,171 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
final class AphrontPagerView extends AphrontView {
|
||||||
|
|
||||||
|
private $offset;
|
||||||
|
private $pageSize;
|
||||||
|
|
||||||
|
private $count;
|
||||||
|
private $hasMorePages;
|
||||||
|
|
||||||
|
private $uri;
|
||||||
|
private $pagingParameter;
|
||||||
|
private $surroundingPages = 2;
|
||||||
|
|
||||||
|
final public function setPageSize($page_size) {
|
||||||
|
$this->pageSize = max(1, $page_size);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setOffset($offset) {
|
||||||
|
$this->offset = max(0, $offset);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getOffset() {
|
||||||
|
return $this->offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getPageSize() {
|
||||||
|
return $this->pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setCount($count) {
|
||||||
|
$this->count = $count;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setHasMorePages($has_more) {
|
||||||
|
$this->hasMorePages = $has_more;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setURI(PhutilURI $uri, $paging_parameter) {
|
||||||
|
$this->uri = $uri;
|
||||||
|
$this->pagingParameter = $paging_parameter;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setSurroundingPages($pages) {
|
||||||
|
$this->surroundingPages = max(0, $pages);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function computeCount() {
|
||||||
|
if ($this->count !== null) {
|
||||||
|
return $this->count;
|
||||||
|
}
|
||||||
|
return $this->getOffset()
|
||||||
|
+ $this->getPageSize()
|
||||||
|
+ ($this->hasMorePages ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function isExactCountKnown() {
|
||||||
|
return $this->count !== null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render() {
|
||||||
|
|
||||||
|
require_celerity_resource('aphront-pager-view-css');
|
||||||
|
|
||||||
|
$page = (int)floor($this->getOffset() / $this->getPageSize());
|
||||||
|
$last = ((int)ceil($this->computeCount() / $this->getPageSize())) - 1;
|
||||||
|
$near = $this->surroundingPages;
|
||||||
|
|
||||||
|
$min = $page - $near;
|
||||||
|
$max = $page + $near;
|
||||||
|
|
||||||
|
// Limit the window size to no larger than the number of available pages.
|
||||||
|
if ($max - $min > $last) {
|
||||||
|
$max = $min + $last;
|
||||||
|
if ($max == $min) {
|
||||||
|
return '<div class="aphront-pager-view"></div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slide the window so it is entirely over displayable pages.
|
||||||
|
if ($min < 0) {
|
||||||
|
$max += 0 - $min;
|
||||||
|
$min += 0 - $min;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($max > $last) {
|
||||||
|
$min -= $max - $last;
|
||||||
|
$max -= $max - $last;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Build up a list of <index, label, css-class> tuples which describe the
|
||||||
|
// links we'll display, then render them all at once.
|
||||||
|
|
||||||
|
$links = array();
|
||||||
|
|
||||||
|
if ($min > 0) {
|
||||||
|
$links[] = array(0, 'First', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($page > 0) {
|
||||||
|
$links[] = array($page - 1, 'Prev', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($ii = $min; $ii <= $max; $ii++) {
|
||||||
|
$links[] = array($ii, $ii + 1, ($ii == $page) ? 'current' : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($page < $last && $last > 0) {
|
||||||
|
$links[] = array($page + 1, 'Next', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($max < ($last - 1)) {
|
||||||
|
$links[] = array($last, 'Last', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
$base_uri = $this->uri;
|
||||||
|
$parameter = $this->pagingParameter;
|
||||||
|
$page_size = $this->getPageSize();
|
||||||
|
|
||||||
|
// Convert tuples into rendered nodes.
|
||||||
|
$rendered_links = array();
|
||||||
|
foreach ($links as $link) {
|
||||||
|
list($index, $label, $class) = $link;
|
||||||
|
// Use a 1-based sequence for display so that the number in the URI is
|
||||||
|
// the same as the page number you're on.
|
||||||
|
if ($index == 0) {
|
||||||
|
// No need for the first page to say page=1.
|
||||||
|
$display_index = null;
|
||||||
|
} else {
|
||||||
|
$display_index = $index * $page_size;
|
||||||
|
}
|
||||||
|
$link = $base_uri->alter($parameter, $display_index);
|
||||||
|
$rendered_links[] = phutil_render_tag(
|
||||||
|
'a',
|
||||||
|
array(
|
||||||
|
'href' => $link,
|
||||||
|
'class' => $class,
|
||||||
|
),
|
||||||
|
$label);
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
'<div class="aphront-pager-view">'.
|
||||||
|
implode('', $rendered_links).
|
||||||
|
'</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
src/view/control/pager/__init__.php
Normal file
15
src/view/control/pager/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('phabricator', 'infrastructure/celerity/api');
|
||||||
|
phutil_require_module('phabricator', 'view/base');
|
||||||
|
|
||||||
|
phutil_require_module('phutil', 'markup');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('AphrontPagerView.php');
|
18
webroot/rsrc/css/aphront/pager-view.css
Normal file
18
webroot/rsrc/css/aphront/pager-view.css
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/**
|
||||||
|
* @provides aphront-pager-view-css
|
||||||
|
*/
|
||||||
|
|
||||||
|
.aphront-pager-view {
|
||||||
|
clear: both;
|
||||||
|
text-align: right;
|
||||||
|
padding: 8px 4px 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aphront-pager-view a {
|
||||||
|
padding: 2px 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aphront-pager-view a.current {
|
||||||
|
border-bottom: 2px solid;
|
||||||
|
}
|
22
webroot/rsrc/css/application/uiexample/example.css
Normal file
22
webroot/rsrc/css/application/uiexample/example.css
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @provides phabricator-ui-example-css
|
||||||
|
*/
|
||||||
|
|
||||||
|
.phabricator-ui-example-note {
|
||||||
|
padding: .5em;
|
||||||
|
margin: 2em 1em 0.5em;
|
||||||
|
background: #ffffdd;
|
||||||
|
border: 1px solid #f5e178;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-ui-example-note tt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-ui-example-header {
|
||||||
|
margin: 1em 2em 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phabricator-ui-example-description {
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
Loading…
Reference in a new issue