瀏覽代碼

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
Andrew Collington 4 年之前
父節點
當前提交
bb8e29dbc9
共有 9 個文件被更改,包括 86 次插入22 次删除
  1. 3 0
      README.md
  2. 51 8
      build/_frontend/interface.jsx
  3. 17 0
      build/_frontend/interface.scss
  4. 1 1
      build/build.php
  5. 1 1
      build/template.phps
  6. 2 1
      composer.json
  7. 4 4
      index.php
  8. 5 5
      package.json
  9. 2 2
      src/Opcache/Service.php

+ 3 - 0
README.md

@@ -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.
 

+ 51 - 8
build/_frontend/interface.jsx

@@ -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>

+ 17 - 0
build/_frontend/interface.scss

@@ -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;

+ 1 - 1
build/build.php

@@ -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/
  */

+ 1 - 1
build/template.phps

@@ -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/
  */

+ 2 - 1
composer.json

@@ -22,7 +22,8 @@
   },
   "require": {
     "ext-Zend-OPcache": "*",
-    "php": ">=7.1.0"
+    "php": ">=7.1.0",
+      "ext-json": "*"
   },
   "autoload": {
     "psr-4" : {

文件差異過大導致無法顯示
+ 4 - 4
index.php


+ 5 - 5
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"
   }
 }

+ 2 - 2
src/Opcache/Service.php

@@ -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;
         }
 

部分文件因文件數量過多而無法顯示