//auxiliary function clears cache & refreshes sib-displays for a given resource ID function refreshSibDisplays(resourceId, clearCache = true) { let cacheCleared = false; Array.from(document.querySelectorAll("sib-display")) .filter(sibDisplay => sibDisplay.component.resourceId == resourceId) // keep only elements with resource == edited resource .forEach(async (e) => { //clear cache if we were unable to before if ((clearCache && !cacheCleared) && e.component.resource != null) { await e.component.resource.clearCache(); cacheCleared = true; } e.dataset.src = e.dataset.src; }); // and update them } async function updateSources(resource) { let res = resource.split('/'); res.splice(3, 0, 'sources'); let cacheCleared = false; if (event.target.component.resource != null) { await event.target.component.resource.clearCache(); cacheCleared = true; } refreshSibDisplays(res.join('/'),cacheCleared); } //auxiliary function updates displays using a given resource //NOTE: this is a temporary workaround and should be replaced by a reactive storage //https://git.startinblox.com/framework/sib-core/issues/524 async function refreshResource(event) { // if of the edited resource || id of the container of the created resource const resourceId = event.detail.resource["@id"] || event.target.dataset.src; updateSources(resourceId, event); let resource; try { resource = document .querySelector('[data-src="' + resourceId + '"]') .component.resource.getResourceData(); } catch (e) { try { resource = document .querySelector('[data-src="' + resourceId.replace('circle-members','circles').split('/').slice(0, 4).join('/') + '/"]') .component.resource.getResourceData(); } catch (e) { try { resource = document .querySelector('[nested-field="' + resourceId.split('/').slice(3, 4).join('').replace('circle-members','circles') + '"]') .component.resource.getResourceData(); } catch (e) { resource = undefined; } } } if(resource) { //special case: refresh circles/X/ from circle-members/Y/ let partnerId = null; if (resourceId.includes("circle-members")) { partnerId = resource["http://happy-dev.fr/owl/#circle"]["@id"]; } else if (resourceId.includes("project-members")) { partnerId = resource["http://happy-dev.fr/owl/#project"]["@id"]; } //refresh all resources using the partner ID if (partnerId != null) { refreshSibDisplays(partnerId); refreshSibDisplays(partnerId + "members/"); } } //special cases updating users/X/circles for the left-side-menu (leaving or joining circle) let user = await document.querySelector('sib-auth').getUser(); if(resourceId.includes('circle') && user != null) { let userId = user['@id']; refreshSibDisplays(userId + "circles/"); refreshSibDisplays(resourceId.replace('circle-members','circles').split('/').slice(0, 3).join('/') + '/circles/joinable/'); refreshSibDisplays(resourceId.replace('circle-members','circles').split('/').slice(0, 3).join('/') + '/sources/circlesjoinable/'); } if(resourceId.includes('users')) { refreshSibDisplays(resourceId.split('/').slice(0, 3).join('/') + '/users/'); refreshSibDisplays(resourceId.split('/').slice(0, 3).join('/') + '/sources/users/'); } //clear cache on this resource //NOTE: this is required because the cache is not refreshed after POSTing changes on the resource let cacheCleared = false; if (event.target.component.resource != null) { await event.target.component.resource.clearCache(); cacheCleared = true; } //update all displays which use this resource refreshSibDisplays(resourceId, cacheCleared); } //auxiliary function performs a redirect //NOTE: currently a sib-display is required to dispatch the requestNavigation event function performRedirect(route) { document.dispatchEvent( new CustomEvent("requestNavigation", { bubbles: true, detail: { route: route } }) ); } //auxiliary function redirects after leaving a project/circle //NOTE: this is a temporary workaround until the following issues are resolved: //https://git.startinblox.com/framework/sib-core/issues/476 //https://git.startinblox.com/framework/sib-core/issues/546 async function checkForPostLeaveRedirect(event) { //a redirect will only be required if I left in the information page of the resource if(!window.location.href.includes('-information')) { return; } //first need to get a sib-display with this resource id (to have access to the target Proxy, containing model fields) const resourceId = event.detail.resource['@id'] || event.target.dataset.src; let target = document.querySelector('[data-src="' + resourceId + '"]'); let resource = target.component.resource.getResourceData(); //no redirect is required for public circles let targetCircleId = resource["http://happy-dev.fr/owl/#circle"]; if(targetCircleId != undefined) { let targetCircle = document.querySelector('[data-src="' + targetCircleId["@id"] + '"]'); let targetCircleResource = targetCircle.component.resource.getResourceData(); if(targetCircleResource['http://happy-dev.fr/owl/#status'] == 'Public') { return; } } //a redirect will only be required if I've deleted myself let targetUser = resource['http://happy-dev.fr/owl/#user']; if(targetUser != undefined) { //compare with current user let user = await document.querySelector('sib-auth').getUser(); if(targetUser['@id'] != user['@id'] && targetUser['@id'] != undefined) { return; } } //perform the redirect if(resourceId.includes('circle')) { performRedirect('circle-left'); } else if(resourceId.includes('project')) { performRedirect('project-left'); } } document.addEventListener("DOMContentLoaded", function(event) { const menuWrappers = Array.from(document.querySelectorAll(".menu-wrapper")); //- Toggle sub-menus menuWrappers.forEach(menuWrapper => { const menu = menuWrapper.querySelector(".menu"); menu.addEventListener("click", e => { menuWrapper.classList.toggle("is-closed"); }); }); //- Watch every sib-forms & update data-src of linked sib-display document.querySelector("body").addEventListener("save", event => { refreshResource(event); }); document.querySelector("body").addEventListener("resourceDeleted", event => { //I might need to be redirected from this page checkForPostLeaveRedirect(event).then(refreshResource(event)); }); });