diff --git a/.env.example b/.env.example index ad3f919d..f58629b7 100644 --- a/.env.example +++ b/.env.example @@ -8,7 +8,7 @@ LOG_CHANNEL=stack DB_CONNECTION=sqlite # Use absolute paths to the database -DB_DATABASE=/absolute/path/to/database/directory/speed.sdb +DB_DATABASE=/absolute/path/to/database/directory/speed.db BROADCAST_DRIVER=log CACHE_DRIVER=file diff --git a/changelog.json b/changelog.json index 43e0492c..03427151 100644 --- a/changelog.json +++ b/changelog.json @@ -1,4 +1,10 @@ { + "1.2.2": [ + { + "description": "Added a table of all speedtests", + "link": "" + } + ], "1.2.1": [ { "description": "Fixed issue where changelog entry with a link wouldn't show.", diff --git a/config/speedtest.php b/config/speedtest.php index ac20a459..fc72b8d8 100644 --- a/config/speedtest.php +++ b/config/speedtest.php @@ -7,7 +7,7 @@ return [ |-------------------------------------------------------------------------- */ - 'version' => '1.2.1', + 'version' => '1.2.2', /* |-------------------------------------------------------------------------- diff --git a/public/css/main.css b/public/css/main.css index 09b012a1..80c6d5a7 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -47,3 +47,7 @@ .Toastify__toast--success { background: #28922b !important; } + +.mouse { + cursor: pointer; +} diff --git a/public/js/app.js b/public/js/app.js index 79840d20..554b68cc 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -126641,7 +126641,9 @@ var DataRow = /*#__PURE__*/function (_Component) { _createClass(DataRow, [{ key: "render", value: function render() { - return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Container"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Row"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], { + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Container"], { + className: "mb-4" + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Row"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_2__["Col"], { sm: { span: 12 }, @@ -127529,6 +127531,185 @@ if (document.getElementById('LatestResults')) { /***/ }), +/***/ "./resources/js/components/Graphics/TestsTable.js": +/*!********************************************************!*\ + !*** ./resources/js/components/Graphics/TestsTable.js ***! + \********************************************************/ +/*! exports provided: default */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TestsTable; }); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js"); +/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-dom */ "./node_modules/react-dom/index.js"); +/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! axios */ "./node_modules/axios/index.js"); +/* harmony import */ var axios__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(axios__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var react_bootstrap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-bootstrap */ "./node_modules/react-bootstrap/esm/index.js"); +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + + + + + + +var TestsTable = /*#__PURE__*/function (_Component) { + _inherits(TestsTable, _Component); + + var _super = _createSuper(TestsTable); + + function TestsTable(props) { + var _this; + + _classCallCheck(this, TestsTable); + + _this = _super.call(this, props); + + _defineProperty(_assertThisInitialized(_this), "getData", function () { + var page = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this.state.page; + var url = '/api/speedtest/?page=' + page; + axios__WEBPACK_IMPORTED_MODULE_2___default.a.get(url).then(function (resp) { + var data = resp.data.data.data; + data = _this.state.data.concat(data); + var page = resp.data.data.current_page; + var lastPage = resp.data.data.last_page; + + _this.setState({ + data: data, + page: page, + lastPage: lastPage + }); + })["catch"](function (err) { + console.log(err); + }); + }); + + _defineProperty(_assertThisInitialized(_this), "getMoreData", function () { + var page = _this.state.page; + page = page + 1; + + _this.getData(page); + }); + + _defineProperty(_assertThisInitialized(_this), "toggleCollapse", function () { + var show = _this.state.showTable; + + if (show) { + _this.setState({ + showTable: false + }); + } else { + _this.setState({ + showTable: true + }); + } + }); + + _this.state = { + page: 1, + lastPage: 1, + data: [], + showTable: false + }; + return _this; + } + + _createClass(TestsTable, [{ + key: "componentDidMount", + value: function componentDidMount() { + this.getData(); + } + }, { + key: "render", + value: function render() { + var page = this.state.page; + var lastPage = this.state.lastPage; + var data = this.state.data; + var show = this.state.showTable; + + if (data.length > 0) { + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Container"], { + className: "mb-4 mt-4", + fluid: true + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Row"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Col"], { + sm: { + span: 12 + }, + className: "mb-3 text-center" + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { + className: "mouse", + "aria-controls": "testsTable", + onClick: this.toggleCollapse, + "aria-expanded": show + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("h4", { + className: "d-inline mr-2" + }, "All tests"), show ? /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", { + className: "ti-angle-up" + }) : /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", { + className: "ti-angle-down" + })))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Collapse"], { + "in": show + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Row"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Col"], { + sm: { + span: 12 + }, + id: "testsTable" + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Table"], { + responsive: true + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("thead", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("tr", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("th", null, "ID"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("th", null, "Time"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("th", null, "Download (Mbit/s)"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("th", null, "Upload (Mbit/s)"), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("th", null, "Ping (ms)"))), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("tbody", null, data.map(function (e, i) { + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("tr", { + key: e.id + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("td", null, e.id), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("td", null, new Date(e.created_at).toLocaleString()), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("td", null, e.download), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("td", null, e.upload), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("td", null, e.ping)); + }))))), page <= lastPage && /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Row"], null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Col"], { + sm: { + span: 12 + }, + className: "text-center" + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react_bootstrap__WEBPACK_IMPORTED_MODULE_3__["Button"], { + variant: "primary", + onClick: this.getMoreData + }, "Show more")))))); + } else { + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null); + } + } + }]); + + return TestsTable; +}(react__WEBPACK_IMPORTED_MODULE_0__["Component"]); + + + +if (document.getElementById('TestsTable')) { + react_dom__WEBPACK_IMPORTED_MODULE_1___default.a.render( /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(TestsTable, null), document.getElementById('TestsTable')); +} + +/***/ }), + /***/ "./resources/js/components/Graphics/Widget.js": /*!****************************************************!*\ !*** ./resources/js/components/Graphics/Widget.js ***! @@ -127757,6 +127938,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _Graphics_LatestResults__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Graphics/LatestResults */ "./resources/js/components/Graphics/LatestResults.js"); /* harmony import */ var _Footer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./Footer */ "./resources/js/components/Home/Footer.js"); /* harmony import */ var _Data_DataRow__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Data/DataRow */ "./resources/js/components/Data/DataRow.js"); +/* harmony import */ var _Graphics_TestsTable__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../Graphics/TestsTable */ "./resources/js/components/Graphics/TestsTable.js"); function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } @@ -127786,6 +127968,7 @@ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || func + var HomePage = /*#__PURE__*/function (_Component) { _inherits(HomePage, _Component); @@ -127802,7 +127985,7 @@ var HomePage = /*#__PURE__*/function (_Component) { value: function render() { return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", null, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", { className: "my-4" - }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Graphics_LatestResults__WEBPACK_IMPORTED_MODULE_3__["default"], null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Graphics_HistoryGraph__WEBPACK_IMPORTED_MODULE_2__["default"], null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Data_DataRow__WEBPACK_IMPORTED_MODULE_5__["default"], null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Footer__WEBPACK_IMPORTED_MODULE_4__["default"], null)); + }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Graphics_LatestResults__WEBPACK_IMPORTED_MODULE_3__["default"], null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Graphics_HistoryGraph__WEBPACK_IMPORTED_MODULE_2__["default"], null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Graphics_TestsTable__WEBPACK_IMPORTED_MODULE_6__["default"], null), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Data_DataRow__WEBPACK_IMPORTED_MODULE_5__["default"], null)), /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(_Footer__WEBPACK_IMPORTED_MODULE_4__["default"], null)); } }]); @@ -127928,16 +128111,14 @@ var Version = /*#__PURE__*/function (_Component) { react_toastify__WEBPACK_IMPORTED_MODULE_3__["toast"].info('Applying update'); axios__WEBPACK_IMPORTED_MODULE_2___default.a.get('/api/update/move').then(function (resp) { - axios__WEBPACK_IMPORTED_MODULE_2___default.a.get('/api/update/move').then(function (resp) { - _this.setState({ - updateProgress: 100 - }); - - react_toastify__WEBPACK_IMPORTED_MODULE_3__["toast"].success('Update successful. Refreshing your page...'); - setTimeout(function () { - location.reload(true); - }, 5000); + _this.setState({ + updateProgress: 100 }); + + react_toastify__WEBPACK_IMPORTED_MODULE_3__["toast"].success('Update successful. Refreshing your page...'); + setTimeout(function () { + location.reload(true); + }, 5000); }); }); })["catch"](function (err) { @@ -127958,8 +128139,7 @@ var Version = /*#__PURE__*/function (_Component) { _createClass(Version, [{ key: "componentDidMount", - value: function componentDidMount() { - this.checkForUpdates(); + value: function componentDidMount() {// this.checkForUpdates(); } }, { key: "render", @@ -127994,8 +128174,7 @@ var Version = /*#__PURE__*/function (_Component) { key: i }, e.description); } else { - /*#__PURE__*/ - react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("li", { + return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("li", { key: i }, /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("a", { href: e.link, diff --git a/resources/js/components/Data/DataRow.js b/resources/js/components/Data/DataRow.js index 65d1dbbf..7577d34b 100644 --- a/resources/js/components/Data/DataRow.js +++ b/resources/js/components/Data/DataRow.js @@ -9,7 +9,7 @@ import Restore from './Restore'; export default class DataRow extends Component { render() { return ( - +

Use these buttons to backup/restore your data

diff --git a/resources/js/components/Graphics/TestsTable.js b/resources/js/components/Graphics/TestsTable.js new file mode 100644 index 00000000..42160345 --- /dev/null +++ b/resources/js/components/Graphics/TestsTable.js @@ -0,0 +1,136 @@ +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; +import Axios from 'axios'; +import { Container, Row, Table, Col, Collapse, Button } from 'react-bootstrap'; + +export default class TestsTable extends Component { + constructor(props) { + super(props) + + this.state = { + page: 1, + lastPage: 1, + data: [], + showTable: false, + } + } + + componentDidMount() { + this.getData(); + } + + getData = (page = this.state.page) => { + var url = '/api/speedtest/?page=' + page; + + Axios.get(url) + .then((resp) => { + var data = resp.data.data.data; + data = this.state.data.concat(data); + var page = resp.data.data.current_page; + var lastPage = resp.data.data.last_page; + this.setState({ + data: data, + page: page, + lastPage: lastPage, + }); + }) + .catch((err) => { + console.log(err); + }) + } + + getMoreData = () => { + var page = this.state.page; + page = page + 1; + + this.getData(page); + } + + toggleCollapse = () => { + var show = this.state.showTable; + + if(show) { + this.setState({ + showTable: false + }); + } else { + this.setState({ + showTable: true + }); + } + } + + render() { + var page = this.state.page; + var lastPage = this.state.lastPage; + var data = this.state.data; + var show = this.state.showTable; + + if(data.length > 0) { + return ( + + + +
+

All tests

+ {(show) ? + + : + + } +
+ +
+ +
+ + + + + + + + + + + + + + {data.map((e,i) => { + return ( + + + + + + + + ); + })} + +
IDTimeDownload (Mbit/s)Upload (Mbit/s)Ping (ms)
{e.id}{new Date(e.created_at).toLocaleString()}{e.download}{e.upload}{e.ping}
+ +
+ {page <= lastPage && + + + + + + } +
+
+
+ ); + } else { + return ( + <> + + ) + } + } +} + +if (document.getElementById('TestsTable')) { + ReactDOM.render(, document.getElementById('TestsTable')); +} diff --git a/resources/js/components/Home/HomePage.js b/resources/js/components/Home/HomePage.js index c2c9730e..ca4a8c1f 100644 --- a/resources/js/components/Home/HomePage.js +++ b/resources/js/components/Home/HomePage.js @@ -4,6 +4,7 @@ import HistoryGraph from '../Graphics/HistoryGraph'; import LatestResults from '../Graphics/LatestResults'; import Footer from './Footer'; import DataRow from '../Data/DataRow'; +import TestsTable from '../Graphics/TestsTable'; export default class HomePage extends Component { @@ -13,6 +14,7 @@ export default class HomePage extends Component {
+