From 533a86e7c27135b975ce9d1ca64a1ba1d744d089 Mon Sep 17 00:00:00 2001 From: Alexandre Capt Date: Wed, 25 Sep 2024 14:52:44 +0200 Subject: [PATCH 1/3] feat: no reload --- tools/rum/slicer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/rum/slicer.js b/tools/rum/slicer.js index a791a57c..c0e69c36 100644 --- a/tools/rum/slicer.js +++ b/tools/rum/slicer.js @@ -384,7 +384,7 @@ const io = new IntersectionObserver((entries) => { elems.viewSelect.addEventListener('change', () => { updateState(); - window.location.reload(); + draw(); }); if (params.get('metrics') === 'all') { From 5400a3affaecbb9b8f0eabbe1b77c4df29b8dbc4 Mon Sep 17 00:00:00 2001 From: Alexandre Capt Date: Tue, 1 Oct 2024 14:34:20 +0200 Subject: [PATCH 2/3] feat: reload data if needed + loading spinner --- tools/rum/charts/skyline.js | 10 +++++++ tools/rum/explorer.html | 3 +++ tools/rum/rum-slicer.css | 41 ++++++++++++++++++++++++++++ tools/rum/slicer.js | 54 ++++++++++++++++++++++++++++++------- 4 files changed, 98 insertions(+), 10 deletions(-) diff --git a/tools/rum/charts/skyline.js b/tools/rum/charts/skyline.js index c0b903db..ef28d780 100644 --- a/tools/rum/charts/skyline.js +++ b/tools/rum/charts/skyline.js @@ -628,5 +628,15 @@ export default class SkylineChart extends AbstractChart { this.lcpAlreadyLabeled = false; this.chart.update(); + + this.loaded(); + } + + loading() { + this.elems.loading.ariaHidden = 'false'; + } + + loaded() { + this.elems.loading.ariaHidden = 'true'; } } diff --git a/tools/rum/explorer.html b/tools/rum/explorer.html index 477b257b..80b330a1 100644 --- a/tools/rum/explorer.html +++ b/tools/rum/explorer.html @@ -97,6 +97,9 @@

TTFB

+
+ +
diff --git a/tools/rum/rum-slicer.css b/tools/rum/rum-slicer.css index d6483323..9a693ee4 100644 --- a/tools/rum/rum-slicer.css +++ b/tools/rum/rum-slicer.css @@ -935,3 +935,44 @@ facet-sidebar[aria-disabled="true"] div.quick-filter { footer.footer-wrapper.appear { display: none; } + +#loading { + position: absolute; + width: 100%; + z-index: 10; + height: 100%; + opacity: 0.9; + background: var(--gray-100); +} + +#loading[aria-hidden="true"] { + display: none; +} + +#loading[aria-hidden="false"] { + display: unset; +} + +#loading .spinner { + position: relative; + top: calc(50% - 24px); + left: calc(50% - 24px); + width: 48px; + height: 48px; + border: 5px solid #FFF; + border-bottom-color: transparent; + border-radius: 50%; + display: inline-block; + box-sizing: border-box; + animation: rotation 1s linear infinite; +} + +@keyframes rotation { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} \ No newline at end of file diff --git a/tools/rum/slicer.js b/tools/rum/slicer.js index c0e69c36..e8f346a3 100644 --- a/tools/rum/slicer.js +++ b/tools/rum/slicer.js @@ -290,14 +290,35 @@ async function loadData(config) { } export function updateState() { + // reload needed if data must be reloaded. This is the case if the domain or view / date changes + let reloadNeeded = false; + const url = new URL(window.location.href.split('?')[0]); const { searchParams } = new URL(window.location.href); + + if (searchParams.get('domain') !== DOMAIN) { + reloadNeeded = true; + } + url.searchParams.set('domain', DOMAIN); url.searchParams.set('filter', elems.filterInput.value); const viewConfig = elems.viewSelect.value; + + if (searchParams.get('view') !== viewConfig.value) { + reloadNeeded = true; + } + url.searchParams.set('view', viewConfig.value); if (viewConfig.value === 'custom') { + if (searchParams.get('startDate') !== viewConfig.from) { + reloadNeeded = true; + } + + if (searchParams.get('endDate') !== viewConfig.to) { + reloadNeeded = true; + } + url.searchParams.set('startDate', viewConfig.from); url.searchParams.set('endDate', viewConfig.to); } @@ -313,6 +334,23 @@ export function updateState() { window.history.replaceState({}, '', url); document.dispatchEvent(new CustomEvent('urlstatechange', { detail: url })); + + return reloadNeeded; +} + +export async function refresh(state = true) { + herochart.loading(); + + let reload = true; + if (state) { + reload = updateState(); + } + + if (reload) { + await loadData(elems.viewSelect.value); + } + + draw(); } const section = document.querySelector('main > div'); @@ -327,13 +365,12 @@ const io = new IntersectionObserver((entries) => { elems.sidebar = sidebar; sidebar.addEventListener('facetchange', () => { - // console.log('sidebar change'); - updateState(); - draw(); + refresh(); }); elems.viewSelect = document.getElementById('view'); elems.canvas = document.getElementById('time-series'); + elems.loading = document.getElementById('loading'); elems.timezoneElement = document.getElementById('timezone'); elems.lowDataWarning = document.getElementById('low-data-warning'); elems.incognito = document.querySelector('incognito-checkbox'); @@ -355,8 +392,7 @@ const io = new IntersectionObserver((entries) => { elems.incognito.addEventListener('change', async () => { loader.domainKey = elems.incognito.getAttribute('domainkey'); - await loadData(elems.viewSelect.value); - draw(); + refresh(false); }); herochart.render(); @@ -374,17 +410,15 @@ const io = new IntersectionObserver((entries) => { elems.timezoneElement.textContent = timezone; if (elems.incognito.getAttribute('domainkey')) { - loadData(elems.viewSelect.value).then(draw); + refresh(false); } elems.filterInput.addEventListener('input', () => { - updateState(); - draw(); + refresh(); }); elems.viewSelect.addEventListener('change', () => { - updateState(); - draw(); + refresh(); }); if (params.get('metrics') === 'all') { From 520d1bcabdc5258b341905e5a6acd1bd6dc627a7 Mon Sep 17 00:00:00 2001 From: Alexandre Capt Date: Tue, 1 Oct 2024 14:51:01 +0200 Subject: [PATCH 3/3] feat: disable facets --- tools/rum/elements/facetsidebar.js | 26 ++++++++++++++++++++++++++ tools/rum/slicer.js | 2 ++ 2 files changed, 28 insertions(+) diff --git a/tools/rum/elements/facetsidebar.js b/tools/rum/elements/facetsidebar.js index 329ba677..2c09fa15 100644 --- a/tools/rum/elements/facetsidebar.js +++ b/tools/rum/elements/facetsidebar.js @@ -75,4 +75,30 @@ export default class FacetSidebar extends HTMLElement { if (facetEl) this.elems.facetsElement.append(facetEl); }); } + + enableFacets() { + const existingFacetElements = Array.from(this.elems.facetsElement.children); + existingFacetElements.forEach((facet) => { + if (facet.enable) { + facet.enable(); + } else { + facet.querySelectorAll('input').forEach((input) => { + input.disabled = false; + }); + } + }); + } + + disableFacets() { + const existingFacetElements = Array.from(this.elems.facetsElement.children); + existingFacetElements.forEach((facet) => { + if (facet.disable) { + facet.disable(); + } else { + facet.querySelectorAll('input').forEach((input) => { + input.disabled = true; + }); + } + }); + } } diff --git a/tools/rum/slicer.js b/tools/rum/slicer.js index e8f346a3..3236ab53 100644 --- a/tools/rum/slicer.js +++ b/tools/rum/slicer.js @@ -340,6 +340,7 @@ export function updateState() { export async function refresh(state = true) { herochart.loading(); + elems.sidebar.disableFacets(); let reload = true; if (state) { @@ -351,6 +352,7 @@ export async function refresh(state = true) { } draw(); + elems.sidebar.enableFacets(); } const section = document.querySelector('main > div');