298 lines
7.3 KiB
JavaScript
298 lines
7.3 KiB
JavaScript
class VrtsTestRunAlerts extends window.HTMLElement {
|
|
constructor() {
|
|
super();
|
|
this.resolveElements();
|
|
this.bindFunctions();
|
|
this.bindEvents();
|
|
this.unreadAlerts = new Set();
|
|
this.initialUnreadAlerts = 0;
|
|
this.unreadRuns = parseInt(
|
|
this.getAttribute( 'data-vrts-unread-runs' ),
|
|
10
|
|
);
|
|
}
|
|
|
|
resolveElements() {
|
|
this.$heading = this.querySelector( '.vrts-test-run-alerts__heading' );
|
|
this.$alerts = this.querySelectorAll( '[data-vrts-alert]' );
|
|
this.$actionButtons = this.querySelectorAll(
|
|
'[data-vrts-test-run-action]'
|
|
);
|
|
|
|
this.$runsMenuItems = [
|
|
document.querySelector(
|
|
'.vrts-admin-header [href*="page=vrts-runs"]'
|
|
),
|
|
document.querySelector(
|
|
'#adminmenu .menu-top[href*="page=vrts"] .wp-menu-name'
|
|
),
|
|
document.querySelector(
|
|
'#adminmenu .wp-submenu a[href*="page=vrts-runs"]'
|
|
),
|
|
];
|
|
}
|
|
|
|
bindFunctions() {
|
|
this.handleAlertClick = this.handleAlertClick.bind( this );
|
|
this.handleActionClick = this.handleActionClick.bind( this );
|
|
this.updateRunsCount = this.updateRunsCount.bind( this );
|
|
}
|
|
|
|
bindEvents() {
|
|
this.$alerts?.forEach( ( item ) => {
|
|
item.addEventListener( 'click', this.handleAlertClick );
|
|
} );
|
|
this.$actionButtons?.forEach( ( item ) => {
|
|
item.addEventListener( 'click', this.handleActionClick );
|
|
} );
|
|
}
|
|
|
|
connectedCallback() {
|
|
this.checkHeadingSticky();
|
|
this.checkReadStatusChange();
|
|
|
|
this.$alerts.forEach( ( item ) => {
|
|
const isUnread =
|
|
item.getAttribute( 'data-vrts-state' ) === 'unread';
|
|
if ( isUnread ) {
|
|
this.unreadAlerts.add( item.getAttribute( 'data-vrts-alert' ) );
|
|
}
|
|
} );
|
|
|
|
this.initialUnreadAlerts = this.unreadAlerts.size;
|
|
}
|
|
|
|
checkHeadingSticky() {
|
|
const checkIsSticky = ( entries ) => {
|
|
const isSticky = ! entries[ 0 ].isIntersecting;
|
|
this.$heading.setAttribute( 'data-is-sticky', isSticky );
|
|
};
|
|
|
|
const observer = new window.IntersectionObserver( checkIsSticky, {
|
|
root: document,
|
|
threshold: [ 1 ],
|
|
} );
|
|
|
|
observer.observe( this.$heading );
|
|
}
|
|
|
|
checkReadStatusChange() {
|
|
const observer = new window.MutationObserver( ( mutations ) => {
|
|
mutations.forEach( ( mutation ) => {
|
|
if (
|
|
mutation.type === 'attributes' &&
|
|
mutation.attributeName === 'data-vrts-state'
|
|
) {
|
|
const id =
|
|
mutation.target.getAttribute( 'data-vrts-alert' );
|
|
const state =
|
|
mutation.target.getAttribute( 'data-vrts-state' );
|
|
|
|
if ( id === 'receipt' ) {
|
|
return;
|
|
}
|
|
|
|
if ( 'unread' === state ) {
|
|
this.unreadAlerts.add( id );
|
|
} else {
|
|
this.unreadAlerts.delete( id );
|
|
}
|
|
|
|
this.querySelector(
|
|
'[data-vrts-test-run-action="read-status"]'
|
|
).setAttribute(
|
|
'data-vrts-action-state',
|
|
this.unreadAlerts.size > 0 ? 'primary' : 'secondary'
|
|
);
|
|
|
|
this.updateRunsCount( this.unreadAlerts.size );
|
|
}
|
|
} );
|
|
} );
|
|
|
|
this.$alerts.forEach( ( item ) => {
|
|
observer.observe( item, {
|
|
attributes: true,
|
|
} );
|
|
} );
|
|
}
|
|
|
|
updateRunsCount( unreadAlerts ) {
|
|
let unreadRuns = this.unreadRuns;
|
|
|
|
if ( unreadAlerts > 0 && this.initialUnreadAlerts === 0 ) {
|
|
unreadRuns += 1;
|
|
} else if ( unreadAlerts === 0 && this.initialUnreadAlerts > 0 ) {
|
|
unreadRuns -= 1;
|
|
}
|
|
|
|
this.$runsMenuItems.forEach( ( item ) => {
|
|
if ( item ) {
|
|
item.querySelector( '.update-plugins' )?.remove();
|
|
item.textContent = item.textContent.replace( /\u00A0/g, '' );
|
|
|
|
if ( unreadRuns > 0 ) {
|
|
const $count = document.createElement( 'span' );
|
|
const nbsp = document.createTextNode( '\u00A0' );
|
|
$count.classList.add( 'update-plugins' );
|
|
$count.textContent = unreadRuns;
|
|
|
|
item.appendChild( nbsp );
|
|
item.appendChild( $count );
|
|
}
|
|
}
|
|
} );
|
|
}
|
|
|
|
handleAlertClick( e ) {
|
|
e.preventDefault();
|
|
const $el = e.currentTarget;
|
|
const isCurrent = $el.getAttribute( 'data-vrts-current' ) === 'true';
|
|
|
|
if ( isCurrent ) {
|
|
return;
|
|
}
|
|
|
|
const href = $el.getAttribute( 'href' );
|
|
const $content =
|
|
document.querySelector( 'vrts-comparisons' ) ||
|
|
document.querySelector( 'vrts-test-run-success' );
|
|
const $pagination = document.querySelector(
|
|
'vrts-test-run-pagination'
|
|
);
|
|
|
|
this.$alerts.forEach( ( item ) => {
|
|
item.setAttribute( 'data-vrts-current', 'false' );
|
|
} );
|
|
|
|
$el.setAttribute( 'data-vrts-current', 'true' );
|
|
|
|
const timeout = setTimeout( () => {
|
|
$content.setAttribute( 'data-vrts-loading', 'true' );
|
|
}, 200 );
|
|
|
|
fetch( href )
|
|
.then( ( response ) => {
|
|
return response.text();
|
|
} )
|
|
.then( ( data ) => {
|
|
const parser = new window.DOMParser();
|
|
const $html = parser.parseFromString( data, 'text/html' );
|
|
|
|
const $newContent =
|
|
$html.querySelector( 'vrts-comparisons' ) ||
|
|
$html.querySelector( 'vrts-test-run-success' );
|
|
const $newPagination = $html.querySelector(
|
|
'vrts-test-run-pagination'
|
|
);
|
|
|
|
window.history.replaceState( {}, '', href );
|
|
|
|
this.scrollTo( $content.offsetTop - 62 );
|
|
|
|
if ( $newContent ) {
|
|
$content.replaceWith( $newContent );
|
|
}
|
|
|
|
if ( $newPagination ) {
|
|
$pagination.replaceWith( $newPagination );
|
|
}
|
|
|
|
clearTimeout( timeout );
|
|
} );
|
|
}
|
|
|
|
handleActionClick( e ) {
|
|
const $el = e.currentTarget;
|
|
const isLoading = $el.getAttribute( 'data-vrts-loading' ) === 'true';
|
|
const state = $el.getAttribute( 'data-vrts-action-state' );
|
|
const isPrimary = state === 'primary';
|
|
|
|
if ( isLoading ) {
|
|
return;
|
|
}
|
|
|
|
const action = $el.getAttribute( 'data-vrts-test-run-action' );
|
|
const id = $el.getAttribute( 'data-vrts-test-run-id' );
|
|
|
|
this.handleAction( action, $el, id, isPrimary );
|
|
}
|
|
|
|
handleAction( action, $el, id, shouldSetAction ) {
|
|
const restEndpoint = `${ window.vrts_admin_vars.rest_url }/test-runs/${ id }/${ action }`;
|
|
const method = shouldSetAction ? 'POST' : 'DELETE';
|
|
|
|
let loadingElapsedTime = 0;
|
|
let interval = null;
|
|
|
|
const timeout = setTimeout( () => {
|
|
$el.setAttribute( 'data-vrts-loading', 'true' );
|
|
const loadingStartTime = window.Date.now();
|
|
interval = setInterval( () => {
|
|
loadingElapsedTime = window.Date.now() - loadingStartTime;
|
|
}, 50 );
|
|
}, 200 );
|
|
|
|
fetch( restEndpoint, {
|
|
method,
|
|
headers: {
|
|
'X-WP-Nonce': window.vrts_admin_vars.rest_nonce,
|
|
},
|
|
} )
|
|
.then( ( response ) => {
|
|
return response.json();
|
|
} )
|
|
.then( () => {
|
|
const loadingTimeoutTime =
|
|
loadingElapsedTime > 0
|
|
? Math.abs( loadingElapsedTime - 400 )
|
|
: 0;
|
|
|
|
setTimeout( () => {
|
|
$el.setAttribute( 'data-vrts-loading', 'false' );
|
|
$el.setAttribute(
|
|
'data-vrts-action-state',
|
|
shouldSetAction ? 'secondary' : 'primary'
|
|
);
|
|
|
|
const $alerts =
|
|
document.querySelectorAll( '[data-vrts-alert]' );
|
|
|
|
$alerts.forEach( ( item ) => {
|
|
item.setAttribute(
|
|
'data-vrts-state',
|
|
shouldSetAction ? 'read' : 'unread'
|
|
);
|
|
} );
|
|
}, loadingTimeoutTime );
|
|
|
|
clearTimeout( timeout );
|
|
clearInterval( interval );
|
|
} );
|
|
}
|
|
|
|
scrollTo( offset ) {
|
|
const $el =
|
|
document.fullscreenElement ||
|
|
document.webkitFullscreenElement ||
|
|
document.msFullscreenElement ||
|
|
window;
|
|
|
|
$el.scrollTo( {
|
|
top: offset,
|
|
behavior: 'smooth',
|
|
} );
|
|
}
|
|
|
|
disconnectedCallback() {
|
|
this.$alerts?.forEach( ( item ) => {
|
|
item.removeEventListener( 'click', this.handleAlertClick );
|
|
} );
|
|
this.$actionButtons?.forEach( ( item ) => {
|
|
item.removeEventListener( 'click', this.handleActionClick );
|
|
} );
|
|
}
|
|
}
|
|
|
|
window.customElements.define( 'vrts-test-run-alerts', VrtsTestRunAlerts );
|