More advanced task details with graph !
This commit is contained in:
parent
a78320344f
commit
4067a8448b
7 changed files with 482 additions and 31 deletions
|
@ -3,7 +3,9 @@
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use Exception;
|
||||
use \Carbon\Carbon;
|
||||
use App\Models\Task;
|
||||
use App\Models\TaskHistory;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
|
@ -69,14 +71,93 @@ class ApiController extends Controller
|
|||
}
|
||||
|
||||
|
||||
public function getTaskDetails($id) {
|
||||
public function getTaskGraph(Request $request, $id) {
|
||||
$days = ($request->input('days', 15) - 1);
|
||||
|
||||
// First, we get the first date of the stats
|
||||
// In this case, one month ago
|
||||
$date = $last_days = Carbon::now()->subDays($days);
|
||||
|
||||
// Then we get all history for the past month
|
||||
$results = TaskHistory::orderBy('created_at', 'asc')
|
||||
->where('created_at', '>', $last_days->toDateString())
|
||||
->where('task_id', '=', $id)
|
||||
->selectRaw('date(created_at) as date, status')
|
||||
->get()
|
||||
;
|
||||
|
||||
// Then we start building an array for the entire month
|
||||
$stats = [];
|
||||
do {
|
||||
$stats[$date->toDateString()] = [
|
||||
'up' => 0,
|
||||
'down' => 0
|
||||
];
|
||||
$date = $date->addDay();
|
||||
}
|
||||
while ($date->lt(Carbon::now()));
|
||||
|
||||
// Finally we populate the data
|
||||
if (! is_null($results)) {
|
||||
foreach ($results as $r) {
|
||||
if (empty($stats[$r->date])) {
|
||||
$stats[$r->date] = [
|
||||
'up' => 0,
|
||||
'down' => 0
|
||||
];
|
||||
}
|
||||
|
||||
if ($r->status == 1) {
|
||||
++$stats[$r->date]['up'];
|
||||
}
|
||||
else {
|
||||
++$stats[$r->date]['down'];
|
||||
}
|
||||
}
|
||||
}
|
||||
return response()->json($stats);
|
||||
}
|
||||
|
||||
|
||||
public function getTaskDetails(Request $request, $id) {
|
||||
$days = ($request->input('days', 15) - 1);
|
||||
|
||||
$task = Task::with(['group', 'history'])
|
||||
->find($id)
|
||||
;
|
||||
|
||||
if (! is_null($task)) {
|
||||
$limit = 100;
|
||||
|
||||
$results = $task
|
||||
->history()
|
||||
->orderBy('created_at', 'desc')
|
||||
->where('created_at', '>', \Carbon\Carbon::now()->subDay($days)->toDateString())
|
||||
->selectRaw('date(created_at) as `date`, created_at, status, output')
|
||||
->get()
|
||||
;
|
||||
|
||||
if (! is_null($results)) {
|
||||
$prev = null;
|
||||
$history = $averages = [];
|
||||
|
||||
foreach ($results as $h) {
|
||||
if ($h->status != $prev) {
|
||||
array_push($history, $h);
|
||||
}
|
||||
$prev = $h->status;
|
||||
|
||||
if (empty($averages[$h->date])) {
|
||||
$averages[$h->date] = [
|
||||
'sum' => 0,
|
||||
'count' => 0
|
||||
];
|
||||
}
|
||||
if ($h->status == 1) {
|
||||
$averages[$h->date]['sum'] ++;
|
||||
}
|
||||
$averages[$h->date]['count'] ++;
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(array_merge($task->toArray(), [
|
||||
$task,
|
||||
|
@ -84,9 +165,9 @@ class ApiController extends Controller
|
|||
'host' => $task->host,
|
||||
'status' => $task->status,
|
||||
'type' => $task->type,
|
||||
'history' => $task->history()->limit($limit)->orderBy('created_at', 'DESC')->get(),
|
||||
'group' => $task->group,
|
||||
'limit' => $limit
|
||||
'history' => $history,
|
||||
'averages' => $averages,
|
||||
'group' => $task->group
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
191
package-lock.json
generated
191
package-lock.json
generated
|
@ -1,13 +1,15 @@
|
|||
{
|
||||
"name": "web",
|
||||
"name": "monitolite",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"apexcharts": "^3.32.0",
|
||||
"axios": "^0.24.0",
|
||||
"moment": "^2.29.1",
|
||||
"vue": "^2.6.14",
|
||||
"vue-apexcharts": "^1.6.2",
|
||||
"vue-router": "^3.5.3",
|
||||
"vuex": "^3.6.2"
|
||||
},
|
||||
|
@ -2396,6 +2398,19 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/apexcharts": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.32.0.tgz",
|
||||
"integrity": "sha512-9VUyiTR2RgD4NIJOOdKxxi8tjzrKCBMr7HjWxsw+5lDPu/tZJLVudpgFhlNTIy3CbhxQ4edaiTttmbo6eDDgiA==",
|
||||
"dependencies": {
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
"svg.pathmorphing.js": "^0.1.3",
|
||||
"svg.resize.js": "^1.4.3",
|
||||
"svg.select.js": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
|
||||
|
@ -8539,6 +8554,89 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.draggable.js": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
|
||||
"integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.easing.js": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
|
||||
"integrity": "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=",
|
||||
"dependencies": {
|
||||
"svg.js": ">=2.3.x"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.filter.js": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
|
||||
"integrity": "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.js": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
|
||||
"integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
|
||||
},
|
||||
"node_modules/svg.pathmorphing.js": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
|
||||
"integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
|
||||
"integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5",
|
||||
"svg.select.js": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.resize.js/node_modules/svg.select.js": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
|
||||
"integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.2.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svg.select.js": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
|
||||
"integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
|
||||
"dependencies": {
|
||||
"svg.js": "^2.6.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/svgo": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
|
||||
|
@ -8906,6 +9004,14 @@
|
|||
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz",
|
||||
"integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ=="
|
||||
},
|
||||
"node_modules/vue-apexcharts": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-apexcharts/-/vue-apexcharts-1.6.2.tgz",
|
||||
"integrity": "sha512-9HS3scJwWgKjmkcWIf+ndNDR0WytUJD8Ju0V2ZYcjYtlTLwJAf2SKUlBZaQTkDmwje/zMgulvZRi+MXmi+WkKw==",
|
||||
"peerDependencies": {
|
||||
"apexcharts": "^3.26.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-hot-reload-api": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
||||
|
@ -11290,6 +11396,19 @@
|
|||
"picomatch": "^2.0.4"
|
||||
}
|
||||
},
|
||||
"apexcharts": {
|
||||
"version": "3.32.0",
|
||||
"resolved": "https://registry.npmjs.org/apexcharts/-/apexcharts-3.32.0.tgz",
|
||||
"integrity": "sha512-9VUyiTR2RgD4NIJOOdKxxi8tjzrKCBMr7HjWxsw+5lDPu/tZJLVudpgFhlNTIy3CbhxQ4edaiTttmbo6eDDgiA==",
|
||||
"requires": {
|
||||
"svg.draggable.js": "^2.2.2",
|
||||
"svg.easing.js": "^2.0.0",
|
||||
"svg.filter.js": "^2.0.2",
|
||||
"svg.pathmorphing.js": "^0.1.3",
|
||||
"svg.resize.js": "^1.4.3",
|
||||
"svg.select.js": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
|
||||
|
@ -15953,6 +16072,70 @@
|
|||
"has-flag": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"svg.draggable.js": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.draggable.js/-/svg.draggable.js-2.2.2.tgz",
|
||||
"integrity": "sha512-JzNHBc2fLQMzYCZ90KZHN2ohXL0BQJGQimK1kGk6AvSeibuKcIdDX9Kr0dT9+UJ5O8nYA0RB839Lhvk4CY4MZw==",
|
||||
"requires": {
|
||||
"svg.js": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"svg.easing.js": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/svg.easing.js/-/svg.easing.js-2.0.0.tgz",
|
||||
"integrity": "sha1-iqmUawqOJ4V6XEChDrpAkeVpHxI=",
|
||||
"requires": {
|
||||
"svg.js": ">=2.3.x"
|
||||
}
|
||||
},
|
||||
"svg.filter.js": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.filter.js/-/svg.filter.js-2.0.2.tgz",
|
||||
"integrity": "sha1-kQCOFROJ3ZIwd5/L5uLJo2LRwgM=",
|
||||
"requires": {
|
||||
"svg.js": "^2.2.5"
|
||||
}
|
||||
},
|
||||
"svg.js": {
|
||||
"version": "2.7.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.js/-/svg.js-2.7.1.tgz",
|
||||
"integrity": "sha512-ycbxpizEQktk3FYvn/8BH+6/EuWXg7ZpQREJvgacqn46gIddG24tNNe4Son6omdXCnSOaApnpZw6MPCBA1dODA=="
|
||||
},
|
||||
"svg.pathmorphing.js": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.pathmorphing.js/-/svg.pathmorphing.js-0.1.3.tgz",
|
||||
"integrity": "sha512-49HWI9X4XQR/JG1qXkSDV8xViuTLIWm/B/7YuQELV5KMOPtXjiwH4XPJvr/ghEDibmLQ9Oc22dpWpG0vUDDNww==",
|
||||
"requires": {
|
||||
"svg.js": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"svg.resize.js": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/svg.resize.js/-/svg.resize.js-1.4.3.tgz",
|
||||
"integrity": "sha512-9k5sXJuPKp+mVzXNvxz7U0uC9oVMQrrf7cFsETznzUDDm0x8+77dtZkWdMfRlmbkEEYvUn9btKuZ3n41oNA+uw==",
|
||||
"requires": {
|
||||
"svg.js": "^2.6.5",
|
||||
"svg.select.js": "^2.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"svg.select.js": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-2.1.2.tgz",
|
||||
"integrity": "sha512-tH6ABEyJsAOVAhwcCjF8mw4crjXSI1aa7j2VQR8ZuJ37H2MBUbyeqYr5nEO7sSN3cy9AR9DUwNg0t/962HlDbQ==",
|
||||
"requires": {
|
||||
"svg.js": "^2.2.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"svg.select.js": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/svg.select.js/-/svg.select.js-3.0.1.tgz",
|
||||
"integrity": "sha512-h5IS/hKkuVCbKSieR9uQCj9w+zLHoPh+ce19bBYyqF53g6mnPB8sAtIbe1s9dh2S2fCmYX2xel1Ln3PJBbK4kw==",
|
||||
"requires": {
|
||||
"svg.js": "^2.6.5"
|
||||
}
|
||||
},
|
||||
"svgo": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz",
|
||||
|
@ -16228,6 +16411,12 @@
|
|||
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz",
|
||||
"integrity": "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ=="
|
||||
},
|
||||
"vue-apexcharts": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-apexcharts/-/vue-apexcharts-1.6.2.tgz",
|
||||
"integrity": "sha512-9HS3scJwWgKjmkcWIf+ndNDR0WytUJD8Ju0V2ZYcjYtlTLwJAf2SKUlBZaQTkDmwje/zMgulvZRi+MXmi+WkKw==",
|
||||
"requires": {}
|
||||
},
|
||||
"vue-hot-reload-api": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
|
||||
|
|
|
@ -8,9 +8,11 @@
|
|||
"vue-template-compiler": "^2.6.14"
|
||||
},
|
||||
"dependencies": {
|
||||
"apexcharts": "^3.32.0",
|
||||
"axios": "^0.24.0",
|
||||
"moment": "^2.29.1",
|
||||
"vue": "^2.6.14",
|
||||
"vue-apexcharts": "^1.6.2",
|
||||
"vue-router": "^3.5.3",
|
||||
"vuex": "^3.6.2"
|
||||
}
|
||||
|
|
118
public/js/app.js
118
public/js/app.js
File diff suppressed because one or more lines are too long
|
@ -14,6 +14,9 @@ Vue.prototype.$http = axios
|
|||
import moment from 'moment'
|
||||
Vue.prototype.moment = moment
|
||||
|
||||
import VueApexCharts from 'vue-apexcharts'
|
||||
Vue.use(VueApexCharts)
|
||||
Vue.component('apexchart', VueApexCharts)
|
||||
|
||||
import Home from '../views/app.vue'
|
||||
import TaskDetails from '../views/taskdetails.vue'
|
||||
|
|
|
@ -8,14 +8,19 @@
|
|||
<!-- <p class="context-menu"><img src="/img/menu.svg" width="40" /></p> -->
|
||||
</h1>
|
||||
|
||||
<h3>Uptime: past {{ chart.days }} days</h3>
|
||||
<div id="chart">
|
||||
<apexchart v-if="chart.render" type="bar" height="350" :options="chartOptions" :series="series"></apexchart>
|
||||
</div>
|
||||
|
||||
<h3>History log</h3>
|
||||
<p>Showing the latest {{ task.limit }} history records</p>
|
||||
|
||||
<table id="tasks_tbl">
|
||||
<h3>Last {{ chart.days }} days history log</h3>
|
||||
<div v-if="task.history.length > 0">
|
||||
<p><i>Showing only records where status has changed</i></p>
|
||||
<table id="tasks_tbl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="20%">Date</th>
|
||||
<th width="20%">Time</th>
|
||||
<th width="*">Output</th>
|
||||
<th width="10%">Status</th>
|
||||
</tr>
|
||||
|
@ -24,9 +29,9 @@
|
|||
<tr
|
||||
v-for="history in task.history"
|
||||
v-bind:key="history.id"
|
||||
:class="task.active == 0 ? 'inactive' : ''"
|
||||
>
|
||||
<td>{{ moment(history.created_at).format('YYYY-MM-DD HH:mm:ss') }}</td>
|
||||
<td>{{ moment(history.date).format('YYYY-MM-DD') }}</td>
|
||||
<td>{{ moment(history.created_at).format('HH:mm:ss') }}</td>
|
||||
<td>
|
||||
<span v-if="history.output">
|
||||
{{ history.output }}
|
||||
|
@ -41,6 +46,8 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p v-else>No history to display here</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -50,7 +57,48 @@
|
|||
export default{
|
||||
data: function() {
|
||||
return {
|
||||
task: null
|
||||
task: null,
|
||||
|
||||
chart: {
|
||||
render: false,
|
||||
days: 15
|
||||
},
|
||||
|
||||
series: [{
|
||||
data: []
|
||||
}],
|
||||
noData: {
|
||||
text: 'Loading...'
|
||||
},
|
||||
chartOptions: {
|
||||
chart: {
|
||||
type: 'bar',
|
||||
height: 350,
|
||||
stacked: true,
|
||||
stackType: '100%'
|
||||
},
|
||||
responsive: [{
|
||||
breakpoint: 480,
|
||||
options: {
|
||||
legend: {
|
||||
position: 'bottom',
|
||||
offsetX: -10,
|
||||
offsetY: 0
|
||||
}
|
||||
}
|
||||
}],
|
||||
xaxis: {
|
||||
categories: [],
|
||||
},
|
||||
fill: {
|
||||
opacity: .9
|
||||
},
|
||||
legend: {
|
||||
position: 'right',
|
||||
offsetX: 0,
|
||||
offsetY: 50
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -71,9 +119,48 @@
|
|||
let task_id = this.$route.params.id ?? null
|
||||
|
||||
if (task_id != null) {
|
||||
this.$http.get('/api/getTask/'+task_id)
|
||||
this.$http.post('/api/getTask/'+task_id, {
|
||||
days: this.chart.days
|
||||
})
|
||||
.then(response => this.task = response.data)
|
||||
.then(() => {
|
||||
this.$http.post('/api/getTaskGraph/'+task_id, {
|
||||
days: this.chart.days
|
||||
})
|
||||
.then(response => {
|
||||
let xaxis = [];
|
||||
let new_data_a = [];
|
||||
let new_data_b = [];
|
||||
console.log(response.data)
|
||||
|
||||
for (let date in response.data) {
|
||||
xaxis.push(date)
|
||||
new_data_a.push(response.data[date]['up'])
|
||||
new_data_b.push(response.data[date]['down'])
|
||||
}
|
||||
|
||||
this.chartOptions.xaxis.categories = xaxis;
|
||||
this.series = [{
|
||||
name: 'UP',
|
||||
data: new_data_a,
|
||||
color: '#00955c'
|
||||
},
|
||||
{
|
||||
name: 'DOWN',
|
||||
data: new_data_b,
|
||||
color: '#ef3232'
|
||||
}]
|
||||
|
||||
this.chart.render = true
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#chart {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
</style>
|
|
@ -15,7 +15,8 @@
|
|||
|
||||
$router->group(['prefix' => 'api/'], function () use ($router) {
|
||||
$router->get('getTasks/', ['uses' => 'ApiController@getTasks']);
|
||||
$router->get('getTask/{id}', ['uses' => 'ApiController@getTaskDetails']);
|
||||
$router->post('getTask/{id}', ['uses' => 'ApiController@getTaskDetails']);
|
||||
$router->post('getTaskGraph/{id}', ['uses' => 'ApiController@getTaskGraph']);
|
||||
$router->patch('toggleTaskStatus/{id}', ['uses' => 'ApiController@toggleTaskStatus']);
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue