Skip to content

Commit 2361488

Browse files
authored
Merge pull request #33 from fleetbase/dev-v0.2.9
v0.2.9 - Improved Webhooks UI
2 parents 2ba75a3 + 8257847 commit 2361488

5 files changed

Lines changed: 184 additions & 81 deletions

File tree

addon/components/webhook/attempts.hbs

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,61 @@
11
<div class="content-panel" ...attributes>
22
<div class="content-panel-header">
3-
<div class="flex items-center">
4-
<div>
5-
<h3 class="mb-1 mr-4 text-xl font-bold dark:text-gray-100">
6-
{{t "developers.component.webhook.attempts.webhook-header"}}
7-
</h3>
8-
<p class="dark:text-gray-100 text-sm">
9-
{{t "developers.component.webhook.attempts.webhook-message"}}
10-
</p>
3+
<div class="flex-1">
4+
<div class="flex items-center mb-4">
5+
<div>
6+
<h3 class="mb-1 mr-4 text-xl font-bold dark:text-gray-100">
7+
{{t "developers.component.webhook.attempts.webhook-header"}}
8+
</h3>
9+
<p class="dark:text-gray-100 text-sm">
10+
{{t "developers.component.webhook.attempts.webhook-message"}}
11+
</p>
12+
</div>
1113
</div>
12-
</div>
13-
14-
<div class="flex items-center section-header-actions">
15-
<div class="rounded-lg border borer-gray-300 dark:border-gray-700 shadow-sm">
16-
<div class="rounded-lg flex items-center justify-between px-2 py-1 text-sm bg-white dark:bg-gray-900">
17-
<a href="javascript:;" class="mx-4 no-underline text-gray-400 {{if this.noAttemptStatus 'font-semibold text-blue-400'}}" {{on "click" this.changeAttemptStatus}}>
18-
{{t "developers.common.all"}}
19-
</a>
20-
<a
21-
href="javascript:;"
22-
class="mx-4 no-underline text-gray-400 {{if (eq this.attemptStatus 'successful') 'font-semibold text-blue-400'}}"
23-
{{on "click" (fn this.changeAttemptStatus "successful")}}
24-
>
25-
{{t "developers.common.succeeded"}}
26-
</a>
27-
<a
28-
href="javascript:;"
29-
class="mx-4 no-underline text-gray-400 {{if (eq this.attemptStatus 'failed') 'font-semibold text-blue-400'}}"
30-
{{on "click" (fn this.changeAttemptStatus "failed")}}
31-
>
32-
{{t "developers.common.failed"}}
33-
</a>
14+
<div class="flex items-center section-header-actions space-x-2">
15+
<div class="rounded-lg border borer-gray-300 dark:border-gray-700 shadow-sm">
16+
<div class="rounded-lg flex items-center justify-between px-2 py-1 text-sm bg-white dark:bg-gray-900">
17+
<a href="javascript:;" class="mx-4 no-underline {{unless this.attemptStatus 'font-semibold text-blue-400' 'text-gray-400'}}" {{on "click" this.changeAttemptStatus}}>
18+
{{t "developers.common.all"}}
19+
</a>
20+
<a
21+
href="javascript:;"
22+
class="mx-4 no-underline {{if (eq this.attemptStatus 'successful') 'font-semibold text-blue-400' 'text-gray-400'}}"
23+
{{on "click" (fn this.changeAttemptStatus "successful")}}
24+
>
25+
{{t "developers.common.succeeded"}}
26+
</a>
27+
<a
28+
href="javascript:;"
29+
class="mx-4 no-underline {{if (eq this.attemptStatus 'failed') 'font-semibold text-blue-400' 'text-gray-400'}}"
30+
{{on "click" (fn this.changeAttemptStatus "failed")}}
31+
>
32+
{{t "developers.common.failed"}}
33+
</a>
34+
</div>
35+
</div>
36+
<div class="rounded-lg border borer-gray-300 dark:border-gray-700 shadow-sm">
37+
<div class="webhook-attempts-date-filter-container">
38+
<div class="date-filter-label">Filter by date:</div>
39+
<DatePicker @value={{this.date}} @onSelect={{this.filterByDate}} placeholder="Filter by date" class="form-input-sm" />
40+
{{#if this.date}}
41+
<Button @type="link" @icon="times" @helpText="Clear date" @onClick={{this.clearDate}} />
42+
{{/if}}
43+
</div>
3444
</div>
3545
</div>
3646
</div>
47+
<div class="flex-1">
48+
{{#if this.webhookRequestLogs.meta}}
49+
<Pagination
50+
@meta={{this.webhookRequestLogs.meta}}
51+
@currentPage={{this.page}}
52+
@onPageChange={{this.changePage}}
53+
@isLoading={{this.getWebhookRequestLogs.isRunning}}
54+
@metaInfoClass="hidden"
55+
class="webhook-attempts-pagination"
56+
/>
57+
{{/if}}
58+
</div>
3759
</div>
3860
<div class="content-panel-body table-wrapper table-fluid">
3961
<Table @rows={{this.webhookRequestLogs}} @columns={{this.columns}} @canExpand={{true}} as |Table|>

addon/components/webhook/attempts.js

Lines changed: 81 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,41 +2,25 @@ import Component from '@glimmer/component';
22
import { inject as service } from '@ember/service';
33
import { tracked } from '@glimmer/tracking';
44
import { action } from '@ember/object';
5-
import { none } from '@ember/object/computed';
5+
import { task } from 'ember-concurrency';
66
import copyToClipboard from '@fleetbase/ember-core/utils/copy-to-clipboard';
77

8+
function filterParams(obj) {
9+
// eslint-disable-next-line no-unused-vars
10+
return Object.fromEntries(Object.entries(obj).filter(([_, value]) => value !== null && value !== undefined));
11+
}
12+
813
export default class WebhookAttemptsComponent extends Component {
914
@service store;
1015
@service intl;
1116
@service hostRouter;
12-
13-
/**
14-
* The current viewing webhook status
15-
*
16-
* @var {String}
17-
*/
17+
@service notifications;
18+
@service urlSearchParams;
1819
@tracked attemptStatus = null;
19-
20-
/**
21-
* The webhook request logs for this endpoint.
22-
*
23-
* @var {String}
24-
*/
2520
@tracked webhookRequestLogs = [];
26-
27-
/**
28-
* The loading state for webhook request logs.
29-
*
30-
* @var {Boolean}
31-
*/
32-
@tracked isLoading = false;
33-
34-
/**
35-
* If not attempt status is set
36-
*
37-
* @var {Boolean}
38-
*/
39-
@none('attemptStatus') noAttemptStatus;
21+
@tracked webhook;
22+
@tracked page = 1;
23+
@tracked date = null;
4024

4125
/**
4226
* All columns applicable for orders
@@ -89,29 +73,78 @@ export default class WebhookAttemptsComponent extends Component {
8973
* Creates an instance of WebhookAttemptsComponent.
9074
* @memberof WebhookAttemptsComponent
9175
*/
92-
constructor() {
76+
constructor(owner, { webhook }) {
9377
super(...arguments);
94-
this.loadWebhookRequestLogs();
78+
this.webhook = webhook;
79+
this.restoreParams();
80+
this.getWebhookRequestLogs.perform();
81+
}
82+
83+
restoreParams() {
84+
if (this.urlSearchParams.has('page')) {
85+
this.page = new Number(this.urlSearchParams.get('page'));
86+
}
87+
88+
if (this.urlSearchParams.has('status')) {
89+
this.status = this.urlSearchParams.get('status');
90+
}
91+
92+
if (this.urlSearchParams.has('date')) {
93+
this.status = this.urlSearchParams.get('date');
94+
}
95+
}
96+
97+
/**
98+
* Load webhook request logs.
99+
*
100+
* @param {Object} [params={}]
101+
* @param {Object} [options={}]
102+
* @memberof WebhookAttemptsComponent
103+
*/
104+
@task *getWebhookRequestLogs(params = {}, options = {}) {
105+
params = filterParams({ ...params, created_at: this.date, status: this.attemptStatus, page: this.page });
106+
107+
try {
108+
this.webhookRequestLogs = yield this.store.query('webhook-request-log', { limit: 12, sort: '-created_at', webhook_uuid: this.webhook.id, page: this.page, ...params }, options);
109+
} catch (error) {
110+
this.notifications.serverError(error);
111+
}
95112
}
96113

97114
/**
98-
* Load webhook request logs for this webhook
115+
* Filter webhook attempt logs by date.
99116
*
117+
* @param {Object} { formattedDate }
100118
* @memberof WebhookAttemptsComponent
101119
*/
102-
@action loadWebhookRequestLogs(params = {}, options = {}) {
103-
const { webhook } = this.args;
104-
105-
this.isLoading = true;
106-
107-
return this.store
108-
.query('webhook-request-log', { limit: -1, webhook_uuid: webhook.id, ...params }, options)
109-
.then((webhookRequestLogs) => {
110-
this.webhookRequestLogs = webhookRequestLogs;
111-
})
112-
.finally(() => {
113-
this.isLoading = false;
114-
});
120+
@action filterByDate({ formattedDate }) {
121+
this.date = formattedDate;
122+
this.urlSearchParams.addParamToCurrentUrl('date', formattedDate);
123+
this.getWebhookRequestLogs.perform();
124+
}
125+
126+
/**
127+
* Clear date filter.
128+
*
129+
* @memberof WebhookAttemptsComponent
130+
*/
131+
@action clearDate() {
132+
this.date = null;
133+
this.urlSearchParams.removeParamFromCurrentUrl('date');
134+
this.getWebhookRequestLogs.perform();
135+
}
136+
137+
/**
138+
* Handle page change.
139+
*
140+
* @param {number} [page=1]
141+
* @memberof WebhookAttemptsComponent
142+
* @void
143+
*/
144+
@action changePage(page = 1) {
145+
this.page = page;
146+
this.urlSearchParams.addParamToCurrentUrl('page', page);
147+
this.getWebhookRequestLogs.perform();
115148
}
116149

117150
/**
@@ -136,10 +169,12 @@ export default class WebhookAttemptsComponent extends Component {
136169
status = typeof status === 'string' ? status : null;
137170

138171
this.attemptStatus = status;
139-
140-
if (status) {
141-
this.loadWebhookRequestLogs({ status });
172+
if (status === null) {
173+
this.urlSearchParams.removeParamFromCurrentUrl('status');
174+
} else {
175+
this.urlSearchParams.addParamToCurrentUrl('status', status);
142176
}
177+
this.getWebhookRequestLogs.perform();
143178
}
144179

145180
/**

addon/styles/dev-engine.css

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
.webhook-attempts-pagination.fleetbase-pagination,
2+
.webhook-attempts-pagination {
3+
padding-top: 0;
4+
justify-content: end;
5+
}
6+
7+
.webhook-attempts-pagination > .fleetbase-pagination-meta-info-wrapper {
8+
flex: none;
9+
}
10+
11+
.webhook-attempts-date-filter-container {
12+
display: flex;
13+
flex-direction: row;
14+
align-items: center;
15+
position: relative;
16+
font-size: 0.875rem;
17+
line-height: 1.25rem;
18+
padding: 0.25rem 0.75rem;
19+
}
20+
21+
.webhook-attempts-date-filter-container > .date-picker-container input.fleetbase-date-picker {
22+
width: 100%;
23+
flex: 1;
24+
padding: 0;
25+
box-shadow: 0;
26+
background-color: transparent;
27+
font-size: 0.875rem;
28+
line-height: 1.25rem;
29+
border: 0;
30+
outline: 0;
31+
}
32+
33+
.webhook-attempts-date-filter-container > .date-picker-container input.fleetbase-date-picker:focus {
34+
box-shadow: none;
35+
border: 0;
36+
outline: 0;
37+
}
38+
39+
.webhook-attempts-date-filter-container > .date-filter-label {
40+
margin-right: 0.25rem;
41+
color: #000;
42+
}
43+
44+
body[data-theme='dark'] .webhook-attempts-date-filter-container > .date-filter-label {
45+
color: #9ca3af;
46+
}

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@fleetbase/dev-engine",
3-
"version": "0.2.8",
3+
"version": "0.2.9",
44
"description": "Fleetbase Developers extension provides a module for managing developer resources such as API keys, webhooks, sockets, events and logs.",
55
"fleetbase": {
66
"route": "developers"
@@ -42,8 +42,8 @@
4242
},
4343
"dependencies": {
4444
"@babel/core": "^7.23.2",
45-
"@fleetbase/ember-core": "^0.2.21",
46-
"@fleetbase/ember-ui": "^0.2.35",
45+
"@fleetbase/ember-core": "latest",
46+
"@fleetbase/ember-ui": "latest",
4747
"@fortawesome/ember-fontawesome": "^2.0.0",
4848
"@fortawesome/fontawesome-svg-core": "6.4.0",
4949
"@fortawesome/free-brands-svg-icons": "6.4.0",

pnpm-lock.yaml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)