Skip to content

Commit 454e729

Browse files
committed
feat(RunsDetail): preload alerts
1 parent 6c3c3bc commit 454e729

File tree

7 files changed

+159
-61
lines changed

7 files changed

+159
-61
lines changed

assets/scripts/cachedFetch.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const cache = new Map();
2+
3+
export const cachedFetch = async ( url ) => {
4+
if ( cache.has( url ) ) {
5+
return cache.get( url );
6+
}
7+
8+
const response = await fetch( url );
9+
const data = await response.text();
10+
11+
cache.set( url, data );
12+
13+
return data;
14+
};
15+
16+
export const clearFetchCache = ( url ) => {
17+
if ( url ) {
18+
cache.delete( url );
19+
} else {
20+
cache.clear();
21+
}
22+
};
23+
24+
export const setFetchCache = ( url, data ) => {
25+
cache.set( url, data );
26+
};

assets/scripts/ric.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
export function requestIdleCallback( callback, options = {} ) {
2+
if ( typeof window.requestIdleCallback === 'function' ) {
3+
return window.requestIdleCallback( callback, options );
4+
}
5+
6+
const timeout = options.timeout || 50;
7+
const start = Date.now();
8+
9+
return setTimeout( () => {
10+
callback( {
11+
didTimeout: false,
12+
timeRemaining: () =>
13+
Math.max( 0, timeout - ( Date.now() - start ) ),
14+
} );
15+
}, 1 );
16+
}
17+
18+
export function cancelIdleCallback( id ) {
19+
if ( typeof window.cancelIdleCallback === 'function' ) {
20+
return window.cancelIdleCallback( id );
21+
}
22+
23+
clearTimeout( id );
24+
}

components/alert-actions/index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use Vrts\Core\Utilities\Url_Helpers;
44

55
?>
6-
<vrts-alert-actions class="vrts-alert-actions">
6+
<vrts-alert-actions class="vrts-alert-actions" data-vrts-alert-url="<?php echo esc_url( Url_Helpers::get_alert_page( $data['alert']->id, $data['alert']->test_run_id ) ) ?>">
77
<button type="button" data-vrts-dropdown-open class="vrts-alert-actions__trigger" aria-expanded="false" aria-controls="vrts-alert-actions-dropdown">
88
<?php vrts()->icon( 'more-horizontal' ); ?>
99
</button>

components/alert-actions/script.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Dropdown from '../../assets/scripts/dropdown';
2+
import { clearFetchCache, setFetchCache } from 'scripts/cachedFetch';
23

34
class VrtsAlertActions extends window.HTMLElement {
45
constructor() {
@@ -74,6 +75,8 @@ class VrtsAlertActions extends window.HTMLElement {
7475
const $form = e.currentTarget;
7576
const formData = new window.FormData( $form );
7677
const postId = formData.get( 'post_id' );
78+
const $actions = $form.closest( 'vrts-alert-actions' );
79+
const alertUrl = $actions.getAttribute( 'data-vrts-alert-url' );
7780

7881
this.$spinner.classList.add( 'is-active' );
7982
this.$success.classList.remove( 'is-active' );
@@ -86,11 +89,15 @@ class VrtsAlertActions extends window.HTMLElement {
8689
body: new URLSearchParams( formData ),
8790
} )
8891
.then( ( response ) => {
92+
if ( alertUrl ) {
93+
clearFetchCache( alertUrl );
94+
}
8995
return response.json();
9096
} )
9197
.then( () => {
9298
this.$spinner.classList.remove( 'is-active' );
9399
this.$success.classList.add( 'is-active' );
100+
setFetchCache( alertUrl, document.body.innerHTML );
94101
} );
95102
}
96103

@@ -117,6 +124,8 @@ class VrtsAlertActions extends window.HTMLElement {
117124
handleAction( action, $el, id, shouldSetAction ) {
118125
const restEndpoint = `${ window.vrts_admin_vars.rest_url }/alerts/${ id }/${ action }`;
119126
const method = shouldSetAction ? 'POST' : 'DELETE';
127+
const $actions = $el.closest( 'vrts-alert-actions' );
128+
const alertUrl = $actions.getAttribute( 'data-vrts-alert-url' );
120129

121130
let loadingElapsedTime = 0;
122131
let interval = null;
@@ -136,6 +145,9 @@ class VrtsAlertActions extends window.HTMLElement {
136145
},
137146
} )
138147
.then( ( response ) => {
148+
if ( alertUrl ) {
149+
clearFetchCache( alertUrl );
150+
}
139151
return response.json();
140152
} )
141153
.then( () => {
@@ -171,6 +183,7 @@ class VrtsAlertActions extends window.HTMLElement {
171183
);
172184
}
173185
}
186+
setFetchCache( alertUrl, document.body.innerHTML );
174187
}, loadingTimeoutTime );
175188

176189
clearTimeout( timeout );

components/test-run-alerts/script.js

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
import {
2+
cachedFetch,
3+
clearFetchCache,
4+
setFetchCache,
5+
} from 'scripts/cachedFetch';
6+
import { requestIdleCallback } from 'scripts/ric';
7+
18
class VrtsTestRunAlerts extends window.HTMLElement {
29
constructor() {
310
super();
@@ -36,11 +43,13 @@ class VrtsTestRunAlerts extends window.HTMLElement {
3643
this.handleAlertClick = this.handleAlertClick.bind( this );
3744
this.handleActionClick = this.handleActionClick.bind( this );
3845
this.updateRunsCount = this.updateRunsCount.bind( this );
46+
this.handleAlertHover = this.handleAlertHover.bind( this );
3947
}
4048

4149
bindEvents() {
4250
this.$alerts?.forEach( ( item ) => {
4351
item.addEventListener( 'click', this.handleAlertClick );
52+
item.addEventListener( 'pointerenter', this.handleAlertHover );
4453
} );
4554
this.$actionButtons?.forEach( ( item ) => {
4655
item.addEventListener( 'click', this.handleActionClick );
@@ -144,6 +153,19 @@ class VrtsTestRunAlerts extends window.HTMLElement {
144153
} );
145154
}
146155

156+
handleAlertHover( e ) {
157+
const $el = e.currentTarget;
158+
const isCurrent = $el.getAttribute( 'data-vrts-current' ) === 'true';
159+
160+
if ( isCurrent ) {
161+
return;
162+
}
163+
164+
const href = $el.getAttribute( 'href' );
165+
166+
requestIdleCallback( () => cachedFetch( href ) );
167+
}
168+
147169
handleAlertClick( e ) {
148170
e.preventDefault();
149171
const $el = e.currentTarget;
@@ -171,35 +193,31 @@ class VrtsTestRunAlerts extends window.HTMLElement {
171193
$content.setAttribute( 'data-vrts-loading', 'true' );
172194
}, 200 );
173195

174-
fetch( href )
175-
.then( ( response ) => {
176-
return response.text();
177-
} )
178-
.then( ( data ) => {
179-
const parser = new window.DOMParser();
180-
const $html = parser.parseFromString( data, 'text/html' );
196+
cachedFetch( href ).then( ( data ) => {
197+
const parser = new window.DOMParser();
198+
const $html = parser.parseFromString( data, 'text/html' );
181199

182-
const $newContent =
183-
$html.querySelector( 'vrts-comparisons' ) ||
184-
$html.querySelector( 'vrts-test-run-success' );
185-
const $newPagination = $html.querySelector(
186-
'vrts-test-run-pagination'
187-
);
200+
const $newContent =
201+
$html.querySelector( 'vrts-comparisons' ) ||
202+
$html.querySelector( 'vrts-test-run-success' );
203+
const $newPagination = $html.querySelector(
204+
'vrts-test-run-pagination'
205+
);
188206

189-
window.history.replaceState( {}, '', href );
207+
window.history.replaceState( {}, '', href );
190208

191-
this.scrollTo( $content.offsetTop - 62 );
209+
this.scrollTo( $content.offsetTop - 62 );
192210

193-
if ( $newContent ) {
194-
$content.replaceWith( $newContent );
195-
}
211+
if ( $newContent ) {
212+
$content.replaceWith( $newContent );
213+
}
196214

197-
if ( $newPagination ) {
198-
$pagination.replaceWith( $newPagination );
199-
}
215+
if ( $newPagination ) {
216+
$pagination.replaceWith( $newPagination );
217+
}
200218

201-
clearTimeout( timeout );
202-
} );
219+
clearTimeout( timeout );
220+
} );
203221
}
204222

205223
handleActionClick( e ) {
@@ -240,6 +258,7 @@ class VrtsTestRunAlerts extends window.HTMLElement {
240258
},
241259
} )
242260
.then( ( response ) => {
261+
clearFetchCache();
243262
return response.json();
244263
} )
245264
.then( () => {
@@ -264,6 +283,10 @@ class VrtsTestRunAlerts extends window.HTMLElement {
264283
shouldSetAction ? 'read' : 'unread'
265284
);
266285
} );
286+
setFetchCache(
287+
window.location.href,
288+
document.body.innerHTML
289+
);
267290
}, loadingTimeoutTime );
268291

269292
clearTimeout( timeout );
@@ -287,6 +310,7 @@ class VrtsTestRunAlerts extends window.HTMLElement {
287310
disconnectedCallback() {
288311
this.$alerts?.forEach( ( item ) => {
289312
item.removeEventListener( 'click', this.handleAlertClick );
313+
item.removeEventListener( 'pointerenter', this.handleAlertHover );
290314
} );
291315
this.$actionButtons?.forEach( ( item ) => {
292316
item.removeEventListener( 'click', this.handleActionClick );

components/test-run-page/script.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import { setFetchCache } from 'scripts/cachedFetch';
12
class VrtsTestRunPage extends window.HTMLElement {
23
constructor() {
34
super();
45
this.bindFunctions();
56
this.bindEvents();
7+
setFetchCache( window.location.href, document.body.innerHTML );
68
this.isScrolling = false;
79
}
810

components/test-run-pagination/script.js

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import { cachedFetch } from 'scripts/cachedFetch';
2+
import { requestIdleCallback } from 'scripts/ric';
3+
14
class VrtsTestRunPagination extends window.HTMLElement {
25
constructor() {
36
super();
47
this.resolveElements();
58
this.bindFunctions();
69
this.bindEvents();
10+
requestIdleCallback( () => this.preloadCache() );
711
}
812

913
resolveElements() {
@@ -73,43 +77,39 @@ class VrtsTestRunPagination extends window.HTMLElement {
7377
behavior: 'smooth',
7478
} );
7579

76-
fetch( href )
77-
.then( ( response ) => {
78-
return response.text();
79-
} )
80-
.then( ( data ) => {
81-
const parser = new window.DOMParser();
82-
const $html = parser.parseFromString( data, 'text/html' );
83-
84-
const $newContent =
85-
$html.querySelector( 'vrts-comparisons' ) ||
86-
$html.querySelector( 'vrts-test-run-success' );
87-
const $newPagination = $html.querySelector(
88-
'vrts-test-run-pagination'
89-
);
90-
91-
window.history.replaceState( {}, '', href );
92-
93-
this.scrollTo( $content.offsetTop - 62 );
94-
95-
const loadingTimeoutTime =
96-
loadingElapsedTime > 0
97-
? Math.abs( loadingElapsedTime - 400 )
98-
: 0;
99-
100-
setTimeout( () => {
101-
if ( $newContent ) {
102-
$content.replaceWith( $newContent );
103-
}
104-
105-
if ( $newPagination ) {
106-
this.replaceWith( $newPagination );
107-
}
108-
}, loadingTimeoutTime );
109-
110-
clearTimeout( timeout );
111-
clearInterval( interval );
112-
} );
80+
cachedFetch( href ).then( ( data ) => {
81+
const parser = new window.DOMParser();
82+
const $html = parser.parseFromString( data, 'text/html' );
83+
84+
const $newContent =
85+
$html.querySelector( 'vrts-comparisons' ) ||
86+
$html.querySelector( 'vrts-test-run-success' );
87+
const $newPagination = $html.querySelector(
88+
'vrts-test-run-pagination'
89+
);
90+
91+
window.history.replaceState( {}, '', href );
92+
93+
this.scrollTo( $content.offsetTop - 62 );
94+
95+
const loadingTimeoutTime =
96+
loadingElapsedTime > 0
97+
? Math.abs( loadingElapsedTime - 400 )
98+
: 0;
99+
100+
setTimeout( () => {
101+
if ( $newContent ) {
102+
$content.replaceWith( $newContent );
103+
}
104+
105+
if ( $newPagination ) {
106+
this.replaceWith( $newPagination );
107+
}
108+
}, loadingTimeoutTime );
109+
110+
clearTimeout( timeout );
111+
clearInterval( interval );
112+
} );
113113
}
114114

115115
handleKeyDown( e ) {
@@ -137,6 +137,15 @@ class VrtsTestRunPagination extends window.HTMLElement {
137137
} );
138138
}
139139

140+
preloadCache() {
141+
this.$buttons?.forEach( ( item ) => {
142+
const href = item.getAttribute( 'href' );
143+
if ( href ) {
144+
cachedFetch( href );
145+
}
146+
} );
147+
}
148+
140149
disconnectedCallback() {
141150
this.$buttons?.forEach( ( item ) => {
142151
item.removeEventListener( 'click', this.handleClick );

0 commit comments

Comments
 (0)