[go: up one dir, main page]

Page MenuHomePhabricator

Table: Add CSS-only pagination example
Closed, ResolvedPublic3 Estimated Story Points

Description

The table docs should include an example of how to use the CSS-only table with pagination. This will be server-side pagination by necessity (the example will not use JS).

The pagination elements will likely need to be wrapped in a <form> tag that can submit requests when the dropdown for "results per page" is changed (via a hidden input element) or when any of the pagination buttons are clicked. Every time to the user advances to a new page, a hard refresh happens and a new page is loaded (likely with different URL params).

Whether to enable/disable a given pagination button will need to be handled by the server.

Event Timeline

egardner set the point value for this task to 3.Jul 18 2024, 6:05 PM
CCiufo-WMF triaged this task as Medium priority.Jul 18 2024, 6:07 PM

Hi @Nunya, I see that you have claimed this task. We work in 2-week sprints and just started a new one here. This task is something we hope to complete between now and August 16. Does that seem doable to you? If so, then I'd say feel free to give this a shot, and we can review any patch you post in Gerrit. If you post questions on this task we will try to address them.

Currently the way we handle "CSS-only components" is we just provide copy/pastable markup in the docs page which can inherit the same styles that are already being used in the Vue.js version. There are some CSS-only versions of the Table component already which could be adapted here – the main thing that would need to be added is the pagination UI (which may need to be wrapped in a <form> element to be submittable without JS). You can see a similar example in the CSS-only Tabs component. I'd recommend using this example of a paginated table as the starting point: https://doc.wikimedia.org/codex/main/components/demos/table.html#with-pagination

If you want to proceed then let us know. If you have assigned yourself by mistake or don't think you can work on this in the next week or two, then I will re-assign. Thanks!

Hello @egardner, yes I would like to give it a shot. Plus the timeline works for me. I will post questions here if I have any. Thanks!

Hi @egardner , I have a question. The task states that "the example will not use JS". Does this only apply to when for example a pagination element is submitted (eg next page load) ? Or it also applies to generally using anything in the script tag. Asking this because I was wondering if I can use the "next ", "previous" icons (which would need importing).

Also just to clarify adding the pagination UI means writing out the HTML plus CSS classes markup to create a table structure with pagination right? Thanks

Nunya changed the task status from Open to In Progress.Aug 18 2024, 3:06 PM

Hey, @egardner saw your comments on my patch and addressed them. I'm not too sure how Gerrit works because I was expecting a "in review" kind of label on the task.

Hey, @egardner saw your comments on my patch and addressed them. I'm not too sure how Gerrit works because I was expecting a "in review" kind of label on the task.

Hi @Nunya, thanks for the patch! We don't have as much workflow automation as some other spaces might have. Typically one of us manually moves a task to the "code review" column on the current sprint board while a patch is in review in Gerrit. I will do that now (and will review your updated patch again later today).

Change #1063923 had a related patch set uploaded (by NunyaKlah; author: NunyaKlah):

[design/codex@main] Table: CSS-only Pagination

https://gerrit.wikimedia.org/r/1063923

Change #1063923 merged by jenkins-bot:

[design/codex@main] Table: CSS-only Pagination

https://gerrit.wikimedia.org/r/1063923

Change #1064134 had a related patch set uploaded (by Catrope; author: Catrope):

[mediawiki/core@master] Update Codex from v1.11.0 to v1.11.1

https://gerrit.wikimedia.org/r/1064134

Change #1064134 merged by jenkins-bot:

[mediawiki/core@master] Update Codex from v1.11.0 to v1.11.1

https://gerrit.wikimedia.org/r/1064134

@Nunya thanks for your contribution here! You've been added to the list of patch contributors in AUTHORS.txt. Feel free to reach out again if you're interested in making any further contributions to Codex!

@egardner, thank you for the support! I'm definitely interested in making further contributions to Codex. I noticed that all the tasks for this sprint have been assigned, but I'll keep an eye on the board for any new ones. I'm also open to any recommendations on tasks I could work on.

The Vue version (when running within MediaWiki) uses MediaWiki messages from rMW languages/i18n/codex/en.json. Is it safe for PHP code also running within MediaWiki to directly use those messages? Or, even better, will be there a PHP class in MediaWiki core that generates the necessary HTML (handling disabling/enabling buttons and showing the appropriate message based on its parameters)? Even if there won’t be a PHP equivalent of the Table Vue component, at least an equivalent of the TablePager component would be very useful.

The Vue version (when running within MediaWiki) uses MediaWiki messages from rMW languages/i18n/codex/en.json. Is it safe for PHP code also running within MediaWiki to directly use those messages? Or, even better, will be there a PHP class in MediaWiki core that generates the necessary HTML (handling disabling/enabling buttons and showing the appropriate message based on its parameters)? Even if there won’t be a PHP equivalent of the Table Vue component, at least an equivalent of the TablePager component would be very useful.

We are discussing a proposed introduction of PHP generated Codex components in T372811. The current proof-of-concept from T372759 does not yet implement a generator for the Codex Table though, and I'm not sure that it will. However, the TablePager class is something we plan to look at soon, captured in T366530.

@CCiufo-WMF, I’m actually working on that right now! I’m aiming to finish it today and will send a patch to the repository as soon as it's ready: repository.

@CCiufo-WMF, I finally finished it, and you can see my example below:

table-codex-example.png (1×2 px, 480 KB)

<?php

use Wikimedia\Codex\Codex;

$codex = new Codex();

$dsn = 'mysql:host=localhost;dbname=mw142alpha;charset=utf8mb4';
$username = 'root';
$password = 'root';

try {
	$db = new PDO( $dsn, $username, $password );
	$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
} catch ( PDOException $e ) {
	die( "Database connection failed: " . $e->getMessage() );
}

$limit = isset( $_GET['limit'] ) && (int)$_GET['limit'] !== 0 ? (int)$_GET['limit'] : 5;

$sort = $_GET['sort'] ?? 'page';
$asc = $_GET['asc'] ?? '';
$desc = $_GET['desc'] ?? '';
$dir = $_GET['dir'] ?? '';
$offset = $_GET['offset'] ?? '';

$order = $asc ? 'ASC' : 'DESC';

if ( $dir === 'prev' ) {
	$order = $order === 'ASC' ? 'DESC' : 'ASC';
}

$sortColumnMap = [
	'page' => 'page.page_title',
];
$sortColumn = $sortColumnMap[$sort] ?? 'page';

$conds = [ 'fp_pending_since IS NOT NULL' ];
if ( $offset !== '' ) {
	if ( $order === 'ASC' ) {
		$conds[] = "fp_pending_since > :offset";
	} else {
		$conds[] = "fp_pending_since < :offset";
	}
}

$query = "
    SELECT
        page.page_title,
        flaggedpages.fp_pending_since AS pending_since
    FROM
        page
    JOIN
        flaggedpages ON page.page_id = flaggedpages.fp_page_id
    WHERE
        " . implode( ' AND ', $conds ) . "
    ORDER BY
        $sortColumn $order
    LIMIT :limit
";

$stmt = $db->prepare( $query );
$stmt->bindParam( ':limit', $limit, PDO::PARAM_INT );
if ( $offset !== '' ) {
	$stmt->bindParam( ':offset', $offset );
}
$stmt->execute();

$pagerData = [];
$firstOffset = null;
$lastOffset = null;

while ( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ) {
	$pagerData[] = [
		'page' => htmlspecialchars( $row['page_title'] ),
		'pending_since' => htmlspecialchars( $row['pending_since'] ),
	];

	if ( !$firstOffset ) {
		$firstOffset = $row['pending_since'];
	}
	$lastOffset = $row['pending_since'];
}

$totalRecords = $db->query( "SELECT COUNT(*) FROM flaggedpages WHERE fp_pending_since IS NOT NULL" )->fetchColumn();
$totalPages = ceil( $totalRecords / $limit );

$pager = $codex->Pager()
			->create()
			->setUrl( $_SERVER['REQUEST_URI'] )
			->setCurrentPage( isset( $_GET['page'] ) ? (int)$_GET['page'] : 1 )
			->setTotalPages( $totalPages )
			->setTotalResults( $totalRecords )
			->setLimit( $limit )
			->setPaginationSizeOptions(
				[
					10,
					25,
					50,
					100,
				]
			)
			->setQueryParams( $_GET )
			->setOffset( $firstOffset );

$tableHtml = $codex->Table()
	->create()
	->setCaption( 'Articles' )
	->setHeaderContent('Articles with pending changes')
	->setColumns( [
		[
			'id' => 'page',
			'label' => 'Title',
			'sortable' => true,
		],
		[
			'id' => 'pending_since',
			'label' => 'Created',
			'sortable' => false,
		],
	] )
	->setData( $pagerData )
	->setPager( $pager )
	->setCurrentSortColumn( $sort )
	->setShowVerticalBorders( true )
	->setPaginationPosition( 'bottom' )
	->setFooter( 'Read more on Wikipedia.' )
	->build();

echo $tableHtml;