Skip to content
This repository has been archived by the owner on May 20, 2024. It is now read-only.

Adds support to multiple queues #50

Merged
merged 9 commits into from
May 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion public/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"/app.js": "/app.js?id=8df81318cb7cf0948b6e",
"/app.js": "/app.js?id=af19d42f41eae5529e9f",
"/app.css": "/app.css?id=fbb793d795cfb9fe09b2"
}
9 changes: 0 additions & 9 deletions resources/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,9 @@ export default {
* Returns an moment instance.
*/
moment() {
// moment.updateLocale('en');

return moment;
},

/**
* Returns the list of the log types.
*/
logTypes() {
return App.logTypes;
},

/**
* Creates a debounced function that delays invoking a callback.
*/
Expand Down
10 changes: 10 additions & 0 deletions resources/js/components/Search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -219,8 +219,14 @@
<script>
import axios from 'axios';
import moment from 'moment';
import JobMixin from './../mixins/job';

export default {
/**
* The component's mixins.
*/
mixins: [JobMixin],

/**
* The component's data.
*/
Expand Down Expand Up @@ -303,6 +309,10 @@ export default {
this.page = 0;
this.cursor = null;

if (this.$route.meta.resource === 'jobs' && this.filters.queue == undefined) {
this.filters.queue = Object.keys(this.queues())[0];
}

/**
* Finally, we perform the request.
*/
Expand Down
11 changes: 11 additions & 0 deletions resources/js/mixins/job.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,16 @@ export default {
jobColor(displayName) {
return 'red';
},

/**
* Returns the queue names.
*/
queues() {
let queues = {};

VaporUi.queues.forEach((queue) => (queues[queue] = queue));

return queues;
},
},
};
35 changes: 33 additions & 2 deletions resources/js/screens/jobs/index.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
<template>
<search>
<template slot="filters" slot-scope="{ filters, loadEntries }"></template>

<template slot="filters" slot-scope="{ filters, loadEntries }">
<div class="mt-6 flex space-x-3 md:mt-0 md:ml-4">
<div>
<label for="queue-input" class="block text-sm font-medium leading-5 text-gray-700">
Queue name
</label>
<select
id="queue-input"
v-model="filters.queue"
v-on:change="loadEntries"
class="
mt-1
form-select
block
w-full
pl-3
pr-10
py-2
text-base
leading-6
border-gray-300
focus:outline-none
focus:shadow-outline-blue
focus:border-blue-300
sm:text-sm
sm:leading-5
"
>
<option v-for="(label, value) in queues()" :value="value">{{ label }}</option>
</select>
</div>
</div>
</template>
<template slot="troubleshooting">
<p>It looks like there was an error. Please check your application logs.</p>

Expand Down
96 changes: 85 additions & 11 deletions resources/js/screens/jobs/metrics.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,46 @@
<template>
<main class="flex-1 relative pb-8 z-0 overflow-y-auto">
<div class="flex-1 relative pb-8 z-0 overflow-y-auto">
<div class="bg-white shadow">
<div class="px-4 sm:px-6 lg:max-w-6xl lg:mx-auto lg:px-8">
<div class="py-6 md:flex md:items-center md:justify-between lg:border-t lg:border-cool-gray-200">
<div class="flex-1 min-w-0"></div>
<div class="mt-6 flex space-x-3 md:mt-0 md:ml-4">
<div>
<label for="queue-input" class="block text-sm font-medium leading-5 text-gray-700">
Queue name
</label>
<select
id="queue-input"
v-model="filters.queue"
v-on:change="request"
class="
mt-1
form-select
block
w-full
pl-3
pr-10
py-2
text-base
leading-6
border-gray-300
focus:outline-none
focus:shadow-outline-blue
focus:border-blue-300
sm:text-sm
sm:leading-5
"
>
<option v-for="(label, value) in queues()" :value="value">{{ label }}</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>

<!-- Troubleshooting -->
<div class="m-8" v-if="troubleshooting">
<div class="px-6 py-4 bg-white shadow-md rounded-lg">
Expand Down Expand Up @@ -105,19 +146,21 @@
<script>
import axios from 'axios';
import InteractsWithMetrics from './../../mixins/interactsWithMetrics';
import JobMixin from './../../mixins/job';

export default {
/**
* The component's mixins.
*/
mixins: [InteractsWithMetrics],
mixins: [InteractsWithMetrics, JobMixin],

/**
* The component's data.
*/
data() {
return {
troubleshooting: false,
filters: {},
metrics: {
processed: {},
failed: {},
Expand All @@ -129,16 +172,47 @@ export default {
* Prepare the component.
*/
mounted() {
return axios
.get('/vapor-ui/api/jobs/metrics')
.then(({ data }) => {
this.metrics = data;
})
.catch(() => {
this.troubleshooting = true;

throw 'Server error.';
});
for (const [filter, value] of Object.entries(this.$route.query)) {
if (this.$route.query[filter]) {
this.filters[filter] = this.$route.query[filter];
}
}

return this.request();
},

/**
* The component's methods.
*/
methods: {
/**
* Performs a GET request on the current group.
*/
request() {
this.metrics = {
processed: {},
failed: {},
};

if (this.filters.queue == undefined) {
this.filters.queue = Object.keys(this.queues())[0];
}

this.$router.push({ query: Object.assign({}, this.$route.query, this.filters) }).catch(() => {});

return axios
.get('/vapor-ui/api/jobs/metrics', {
params: this.filters,
})
.then(({ data }) => {
this.metrics = data;
})
.catch(() => {
this.troubleshooting = true;

throw 'Server error.';
});
},
},
};
</script>
7 changes: 7 additions & 0 deletions resources/views/layout.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,13 @@ class="group flex items-center px-2 py-2 text-sm leading-5 font-medium text-gray
<router-view></router-view>
</div>

<!-- Global Telescope Object -->
<script>
window.VaporUi = @json([
'queues' => $queues,
]);
</script>

<script src="{{ asset(mix('app.js', 'vendor/vapor-ui')) }}"></script>
</body>
</html>
5 changes: 4 additions & 1 deletion src/Http/Controllers/HomeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Laravel\VaporUi\Http\Controllers;

use Illuminate\View\View;
use Laravel\VaporUi\Support\Cloud;

class HomeController
{
Expand All @@ -13,6 +14,8 @@ class HomeController
*/
public function __invoke()
{
return view('vapor-ui::layout');
return view('vapor-ui::layout', [
'queues' => Cloud::queues(),
]);
}
}
11 changes: 10 additions & 1 deletion src/Http/Controllers/JobMetricController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Laravel\VaporUi\Http\Controllers;

use Laravel\VaporUi\Http\Requests\JobMetricRequest;
use Laravel\VaporUi\Repositories\JobsMetricsRepository;

class JobMetricController
Expand Down Expand Up @@ -30,8 +31,16 @@ public function __construct(JobsMetricsRepository $metrics)
*
* @return array
*/
public function index()
public function index(JobMetricRequest $request)
{
tap($request->get('queue'), function ($queue) {
if ($queue) {
$this->metrics->resolveQueueUsing(function () use ($queue) {
return $queue;
});
}
});

return [
'failed' => [
'timeseries' => $this->metrics->failedTimeseries(),
Expand Down
20 changes: 20 additions & 0 deletions src/Http/Requests/JobMetricRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Laravel\VaporUi\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class JobMetricRequest extends FormRequest
{
/**
* Get the validation rules that apply to the job metric request.
*
* @return array
*/
public function rules()
{
return [
'queue' => ['string'],
];
}
}
1 change: 1 addition & 0 deletions src/Http/Requests/JobRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public function rules()
'query' => ['nullable', 'string'],
'startTime' => ['required', 'integer'],
'cursor' => ['nullable', 'string'],
'queue' => ['string'],
];
}
}
Loading