Added sorting to cached file list (#62)
* Added ext-json to composer.json as it's a required funciton. * Added filtering option for files list * Updated version numbers
This commit is contained in:
parent
a4e37c66ae
commit
bb8e29dbc9
9 changed files with 144 additions and 26 deletions
|
@ -158,6 +158,9 @@ When the real-time updates are active the interface will automatically update al
|
|||
|
||||
## Releases
|
||||
|
||||
**Version 3.1.0**\
|
||||
Added the ability to sort the cached file list in a variety of ways.
|
||||
|
||||
**Version 3.0.1**\
|
||||
A minor update that will use http or https to get the javascript libraries, depending on what you're using.
|
||||
|
||||
|
|
|
@ -657,7 +657,9 @@ class CachedFiles extends React.Component {
|
|||
this.state = {
|
||||
currentPage: 1,
|
||||
searchTerm: props.searchTerm,
|
||||
refreshPagination: 0
|
||||
refreshPagination: 0,
|
||||
sortBy: `last_used_timestamp`,
|
||||
sortDir: `desc`
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -684,6 +686,30 @@ class CachedFiles extends React.Component {
|
|||
}
|
||||
}
|
||||
|
||||
changeSort = e => {
|
||||
this.setState({ [e.target.name]: e.target.value });
|
||||
}
|
||||
|
||||
compareValues = (key, order = 'asc') => {
|
||||
return function innerSort(a, b) {
|
||||
if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
|
||||
return 0;
|
||||
}
|
||||
const varA = (typeof a[key] === 'string') ? a[key].toUpperCase() : a[key];
|
||||
const varB = (typeof b[key] === 'string') ? b[key].toUpperCase() : b[key];
|
||||
|
||||
let comparison = 0;
|
||||
if (varA > varB) {
|
||||
comparison = 1;
|
||||
} else if (varA < varB) {
|
||||
comparison = -1;
|
||||
}
|
||||
return (
|
||||
(order === 'desc') ? (comparison * -1) : comparison
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.props.allow.fileList) {
|
||||
return null;
|
||||
|
@ -701,6 +727,9 @@ class CachedFiles extends React.Component {
|
|||
})
|
||||
: this.props.allFiles
|
||||
);
|
||||
|
||||
filesInSearch.sort(this.compareValues(this.state.sortBy, this.state.sortDir));
|
||||
|
||||
const filesInPage = (this.doPagination
|
||||
? filesInSearch.slice(offset, offset + this.props.perPageLimit)
|
||||
: filesInSearch
|
||||
|
@ -721,13 +750,27 @@ class CachedFiles extends React.Component {
|
|||
<p><a href={`?invalidate_searched=${encodeURIComponent(this.state.searchTerm)}`} onClick={this.handleInvalidate}>Invalidate all matching files</a></p>
|
||||
}
|
||||
|
||||
{this.doPagination && <Pagination
|
||||
totalRecords={filesInSearch.length}
|
||||
pageLimit={this.props.perPageLimit}
|
||||
pageNeighbours={2}
|
||||
onPageChanged={this.onPageChanged}
|
||||
refresh={this.state.refreshPagination}
|
||||
/>}
|
||||
<div className="paginate-filter">
|
||||
{this.doPagination && <Pagination
|
||||
totalRecords={filesInSearch.length}
|
||||
pageLimit={this.props.perPageLimit}
|
||||
pageNeighbours={2}
|
||||
onPageChanged={this.onPageChanged}
|
||||
refresh={this.state.refreshPagination}
|
||||
/>}
|
||||
<nav className="filter" aria-label="Sort order">
|
||||
<select name="sortBy" onChange={this.changeSort} value={this.state.sortBy}>
|
||||
<option value="last_used_timestamp">Last used</option>
|
||||
<option value="full_path">Path</option>
|
||||
<option value="hits">Number of hits</option>
|
||||
<option value="memory_consumption">Memory consumption</option>
|
||||
</select>
|
||||
<select name="sortDir" onChange={this.changeSort} value={this.state.sortDir}>
|
||||
<option value="desc">Descending</option>
|
||||
<option value="asc">Ascending</option>
|
||||
</select>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<table className="tables cached-list-table">
|
||||
<thead>
|
||||
|
|
|
@ -304,6 +304,23 @@ $footer-border-color: #CCC;
|
|||
margin-top: 0;
|
||||
}
|
||||
|
||||
.paginate-filter {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.filter > * {
|
||||
padding: 3px;
|
||||
margin-left: 3px;
|
||||
|
||||
@media screen and (max-width: 550px) {
|
||||
padding: 3px;
|
||||
margin: 3px 3px 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* OPcache GUI - build script
|
||||
*
|
||||
* @author Andrew Collington, andy@amnuts.com
|
||||
* @version 3.0.1
|
||||
* @version 3.1.0
|
||||
* @link https://github.com/amnuts/opcache-gui
|
||||
* @license MIT, http://acollington.mit-license.org/
|
||||
*/
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace Amnuts\Opcache;
|
|||
* A simple but effective single-file GUI for the OPcache PHP extension.
|
||||
*
|
||||
* @author Andrew Collington, andy@amnuts.com
|
||||
* @version 3.0.1
|
||||
* @version 3.1.0
|
||||
* @link https://github.com/amnuts/opcache-gui
|
||||
* @license MIT, http://acollington.mit-license.org/
|
||||
*/
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
},
|
||||
"require": {
|
||||
"ext-Zend-OPcache": "*",
|
||||
"php": ">=7.1.0"
|
||||
"php": ">=7.1.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4" : {
|
||||
|
|
70
index.php
70
index.php
File diff suppressed because one or more lines are too long
10
package.json
10
package.json
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "opcache-gui",
|
||||
"description": "A clean and responsive interface for Zend OPcache information, showing statistics, settings and cached files, and providing a real-time update for the information (using jQuery and React).",
|
||||
"version": "3.0.1",
|
||||
"version": "3.1.0",
|
||||
"main": "index.js",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.0.0",
|
||||
"@babel/core": "^7.0.0",
|
||||
"@babel/preset-react": "^7.9.4",
|
||||
"@babel/cli": "^7.12.8",
|
||||
"@babel/core": "^7.12.9",
|
||||
"@babel/preset-react": "^7.12.7",
|
||||
"node-sass": "^4.14.1"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -25,6 +25,6 @@
|
|||
},
|
||||
"homepage": "https://github.com/amnuts/opcache-gui#readme",
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.4"
|
||||
"@babel/plugin-proposal-class-properties": "^7.12.1"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace Amnuts\Opcache;
|
|||
|
||||
class Service
|
||||
{
|
||||
const VERSION = '3.0.1';
|
||||
const VERSION = '3.1.0';
|
||||
|
||||
protected $data;
|
||||
protected $options;
|
||||
|
@ -81,7 +81,7 @@ class Service
|
|||
} else if (isset($_GET['invalidate_searched']) && $this->getOption('allow_invalidate')) {
|
||||
$response($this->resetSearched($_GET['invalidate_searched']));
|
||||
} else if ($this->isJsonRequest() && $this->getOption('allow_realtime')) {
|
||||
echo json_encode($this->getData((empty($_GET['section']) ? null : $_GET['section'])));
|
||||
echo json_encode($this->getData($_GET['section'] ?? null));
|
||||
exit;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue