Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • applications/etuc/hubl
  • applications/hubl
  • decentral1se/hubl
  • rngadam/hubl
  • jvtrudel/hubl
  • 3wc/hubl
6 results
Show changes
Showing
with 1071 additions and 482 deletions
function applyAdapt(prefix, sibDisplay, user) {
//- Allow to bind-user on selected attribute
if (sibDisplay.getAttribute(prefix + "-user-id")) {
sibDisplay.setAttribute(
sibDisplay.getAttribute(prefix + "-user-id"),
user["@id"]
);
}
//- Allow to set data-src to a children sib-form
if (sibDisplay.getAttribute(prefix + "-bind-resources")) {
let form = sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-resources") + " sib-form"
);
if (form) {
form.setAttribute(
"data-src",
sibDisplay.component.resourceId.replace("members/", "")
);
}
}
//- Allow to put user on a targetted search field
if (sibDisplay.getAttribute(prefix + "-bind-user2input")) {
sibDisplay.querySelector(
sibDisplay.getAttribute(prefix + "-bind-user2input")
).value = user["@id"];
}
}
function recursiveAdaptWidgets(prefix, element, user) {
element.addEventListener("populate", () => {
//- This function is a workaround for the currently unworking populate
//- Feel free to see examples on page-circles-
element.querySelectorAll("[" + prefix + "-user-id]").forEach(el => {
el.setAttribute(el.getAttribute(prefix + "-user-id"), user["@id"]);
});
applyAdapt(prefix, element, user);
document.querySelectorAll('sib-display, sib-form').forEach(sibDisplay => {
applyAdapt(prefix, sibDisplay, user);
});
});
}
// auxiliary function closes the user profile menu
function closeUserControls() {
let userControls = document.querySelector("#user-controls");
if (userControls) userControls.removeAttribute("open");
}
function closeLeftMenu() {
let leftMenu = document.querySelector("#main__menu");
if (leftMenu) leftMenu.removeAttribute("open");
}
function closeRightMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
if (Array.from(rightMenu).filter(el => el.hasAttribute("open")).length > 0) {
Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
vC.classList.toggle("sidebar-is-closed")
);
Array.from(rightMenu).forEach(el => el.removeAttribute("open"));
}
}
function openRightMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
Array.from(rightMenu).forEach(el => el.setAttribute("open", ""));
Array.from(document.querySelectorAll(".views-container")).forEach(vC =>
vC.classList.toggle("sidebar-is-closed")
);
}
//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(e => {
//clear cache if we were unable to before
if ((clearCache && !cacheCleared) && e.component.resource != null) {
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) {
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.happy-dev.fr/startinblox/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 = document
.querySelector('[data-src="' + resourceId + '"]')
.component.resource.getResourceData();
//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.split('/').slice(0,4).join('/')+'/joinable/');
}
//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) {
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.happy-dev.fr/startinblox/framework/sib-core/issues/476
//https://git.happy-dev.fr/startinblox/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"]["@id"];
if(targetCircleId != undefined) {
let targetCircle = document.querySelector('[data-src="' + targetCircleId + '"]');
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'];
//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');
}
//- Update badges from notifications list
async function updateBadges(element) {
const unreadNotifications = new Map();
const notifications = element.component.resource;
if (!notifications) return;
// Generate unread map
for (let notification of notifications['ldp:contains']) {
if (await notification['unread']) {
const object = await notification['object'];
unreadNotifications.set(object['@id'], (unreadNotifications.get(object['@id']) || 0) + 1);
}
}
// update badges
unreadNotifications.forEach((notifNumber, objectId) => {
const badge = document.querySelector(`sib-fix-badge[data-src="${objectId}"]`);
if (badge) {
badge.innerText = notifNumber || '';
badge.style.display = notifNumber ? 'block' : 'none';
}
})
}
document.addEventListener("DOMContentLoaded", function(event) {
const menuWrappers = Array.from(document.querySelectorAll(".menu-wrapper"));
//- View change event
window.addEventListener("navigate", event => {
closeLeftMenu();
closeUserControls();
});
//- 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));
});
document
.querySelector("sib-auth")
.getUser()
.then(user => {
if (user !== null) {
document
.querySelectorAll(".notLoggedIn")
.forEach(el => (el.style.visibility = "visible"));
// Hide login button if already logged
document
.querySelector('.loggedIn')
.setAttribute("style", "display:none !important");
document.querySelectorAll('sib-display, sib-form').forEach(element => {
// Set current user id on set-user-id of sib-display
recursiveAdaptWidgets("hd-inherit", element, user);
});
for (leaveBtn of document.querySelectorAll(
"admin-circle-leave > sib-ac-checker:not([hidden])"
)) {
leaveBtn.parentNode.parentNode.parentNode.nextElementSibling.setAttribute(
"style",
"display:none !important"
); // Hide Join button
}
} else {
document.querySelector('sib-auth').login();
}
})
.catch(error => console.log(error));
// Document -> close menu
document.addEventListener("click", event => {
if (!event.target.closest("#user-controls")) {
closeUserControls();
}
if (
!event.target.closest("#main__menu") &&
event.target.id != "toggleMainMenu"
) {
closeLeftMenu();
}
if (
!event.target.className.includes("jsMobileSidebarOpenButton") &&
!event.target.className.includes("jsOffsiteToggle")
) {
closeRightMenu();
}
});
document.querySelector("#toggleMainMenu").addEventListener("click", event => {
let leftMenu = document.querySelector("#main__menu");
if (leftMenu.hasAttribute("open")) {
closeLeftMenu();
} else {
leftMenu.setAttribute("open", "");
}
});
Array.from(document.querySelectorAll(".jsMobileSidebarOpenButton")).forEach(
el => {
el.addEventListener("click", event => {
openRightMenu();
});
}
);
const rightMenus = Array.from(document.querySelectorAll("nav.jsRightMenu"));
rightMenus.forEach(rightMenu => {
const btnRightMenu = rightMenu.querySelector("li.jsOffsiteToggle");
btnRightMenu.addEventListener("click", e => {
if (rightMenu.hasAttribute("open")) {
closeRightMenu();
} else {
openRightMenu();
}
});
});
// listen for keypress
document.onkeydown = e => {
e = e || window.event;
if (e.key === "Escape" || e.key === "Esc") {
closeUserControls();
closeLeftMenu();
closeRightMenu();
}
};
//- Fix badges performances
// on load time
const checkNotificationMenuExist = setInterval(function () { // wait for notification menu to exist
const notifsMenu = document.getElementById('notifications-list');
if (notifsMenu) {
clearInterval(checkNotificationMenuExist);
notifsMenu.addEventListener('populate', (event) => {
const checkExist = setInterval(function () { // wait for left menus to exist
const subMenus = document.querySelectorAll('.sub-menu > sib-display > div');
if (subMenus.length >= 2) {
updateBadges(event.target);
clearInterval(checkExist);
}
}, 500);
}, { once: true });
}
}, 500);
// on refresh notification list
window.addEventListener('notificationsRefresh', () => {
document.getElementById('notifications-list').addEventListener('populate', (event) => {
updateBadges(event.target);
}, { once: true });
});
// on read notification
window.addEventListener('read', (event) => {
if (event.detail && event.detail.resource && event.detail.resource['@id']) {
const badge = document.querySelector(`sib-fix-badge[data-src="${event.detail.resource['@id']}"]`);
if (badge) badge.style.display = "none";
}
});
});
/**
* Iterates over federations and register them in sibStore if available.
*/
document.addEventListener("DOMContentLoaded", () => {
const feds = [];
for (const [uniq, federation] of Object.entries(federations)) {
if (sibStore && "setLocalData" in sibStore) {
feds.push(sibStore.setLocalData(federation, uniq));
}
}
Promise.all(feds).then(() => {
window.orbit.federationsReady = true;
document.dispatchEvent(new CustomEvent("federations-ready"));
});
});
import {
getComponent,
getComponentFromRoute,
getDefaultRoute,
getRoute,
Swal,
} from "@helpers/utils";
window.orbit = {
...window.orbit,
client,
components,
componentSet: new Set(componentSet),
federations,
federationsReady: false,
npm,
getDefaultRoute,
getComponent,
getComponentFromRoute,
getRoute,
//TODO: Legacies:
defaultRoute: getDefaultRoute(),
Swal,
};
document.addEventListener("federations-ready", () => {
window.orbit.federationsReady = true;
});
// document.addEventListener("DOMContentLoaded", () => {
// if (typeof Sentry !== 'undefined') {
// Sentry.init({
// dsn: "https://TBD@sentry.startinblox.com/TBD",
// environment: document.location.hostname,
// integrations: [
// Sentry.browserTracingIntegration({ tracingOrigins: ["*"] }),
// Sentry.replayIntegration(),
// ],
// tracesSampleRate: 0.2,
// replaysSessionSampleRate: 0.1,
// replaysOnErrorSampleRate: 1.0,
// });
// window.orbit.sentry = Sentry;
// }
// });
/*
Geocoord helper using Nominatim
Usage:
const madrid = await orbit.geocoord('Madrid');
madrid == ["-3.7035825", "40.4167047"]
*/
window.orbit.geocoord = async (address = false) => {
if (address) {
const nominatim = await fetch(
`https://nominatim.openstreetmap.org/?format=geocodejson&limit=1&q=${encodeURI(address)}`,
);
const response = await nominatim.json();
if (response.features[0]) {
const coords = response.features[0].geometry.coordinates;
if (coords[0] && coords[1]) {
return [String(coords[0]), String(coords[1])];
}
} else {
console.error("Address not found");
}
} else {
console.error("Missing address");
}
return ["-47.15", "-123.716667"];
};
window.orbit.geocalc = (element) => {
const editionForm =
element.parentElement.parentElement.parentElement.parentElement;
window.orbit
.geocoord(
`${editionForm.querySelector('input[name="address_line1"]').value} ${editionForm.querySelector('input[name="address_line2"]').value}`,
)
.then((coords) => {
editionForm.querySelector('input[name="lat"]').value = coords[1];
editionForm.querySelector('input[name="lng"]').value = coords[0];
editionForm.querySelector('input[type="submit"]').click();
});
return false;
};
/*
js intl, inspired by danabr/jsI18n
*/
class JsI18n {
constructor() {
this.locale = ""; //Current locale
this.locales = new Array(); //Available locales
this.overwrites = new Array();
this.defaultLocale = "fr";
}
/*
Method for automatically detecting the language, does not work in every browser.
*/
async detectLanguage() {
const customLangs = document.querySelectorAll("orbit-lang");
if (customLangs) {
for (const lang of customLangs) {
const name = lang.getAttribute("lang");
const file = lang.getAttribute("file");
const result = await fetch(file);
if (result.ok) {
const json = await result.json();
if (this.overwrites[name.toString()] !== undefined) {
this.mergeDeep(this.overwrites[name.toString()], json);
} else {
this.overwrites[name.toString()] = json;
}
}
}
}
this.resumeDetection();
}
resumeDetection() {
const langComponent = document.querySelector("orbit-fallback-lang");
if (langComponent) {
if (langComponent.hasAttribute("lang")) {
this.defaultLocale = langComponent.getAttribute("lang");
if (langComponent.hasAttribute("force")) {
localStorage.setItem("language", this.defaultLocale);
}
}
}
if (
localStorage.getItem("language") ||
(window.navigator.language !== null &&
window.navigator.language !== undefined)
) {
this.fetchLocale(this.defaultLocale);
this.setLocale(
localStorage.getItem("language") ||
window.navigator.language.slice(0, 2),
);
} else {
console.error("Language not found");
this.setLocale(this.defaultLocale);
}
}
isObject(item) {
return item && typeof item === "object" && !Array.isArray(item);
}
mergeDeep(target, ...sources) {
if (!sources.length) return target;
const source = sources.shift();
if (this.isObject(target) && this.isObject(source)) {
for (const key in source) {
if (this.isObject(source[key])) {
if (!target[key])
Object.assign(target, {
[key]: {},
});
this.mergeDeep(target[key], source[key]);
} else {
Object.assign(target, {
[key]: source[key],
});
}
}
}
return this.mergeDeep(target, ...sources);
}
/*
Translates tag contents and
attributes depending on the
value of key.
*/
translateTag(node, key) {
if (key.indexOf("=") === -1) {
//Simple key
this.translateNodeContent(node, key);
} else {
//Attribute/key pairs
const parts = key.split(";");
for (let i = 0; i < parts.length; i++) {
const pair = parts[i].split("=");
const attr = pair[0].toLowerCase().trim();
const k = pair[1].trim();
if (attr === "html") {
this.translateNodeContent(node, k);
} else {
// https://git.startinblox.com/framework/sib-core/issues/733
if (attr.startsWith("label-")) {
// biome-ignore lint/style/useConst: <explanation>
let label = node.querySelector(
`[name="${attr.replace("label-", "")}"] > label`,
);
if (label != null) {
this.translateNodeContent(label, k);
}
}
// https://git.startinblox.com/framework/sib-core/issues/755
if (attr.startsWith("placeholder-")) {
const placeholder = node.querySelector(
`[placeholder="${attr.replace("placeholder-", "")}"]`,
);
if (placeholder != null) {
this.translateNodeContent(
placeholder.attributes["placeholder"],
k,
);
const input = node.querySelector(
`[name="${attr.replace("placeholder-", "")}"] > input`,
);
if (input != null) {
this.translateNodeContent(input.attributes["placeholder"], k);
}
}
}
if (attr.startsWith("enum-")) {
const enumAttr = node.querySelector(
`[name="${attr.replace("enum-", "")}"]`,
);
if (enumAttr != null) {
this.translateNodeContent(enumAttr.attributes["enum"], k);
}
}
this.translateNodeContent(node.attributes[attr], k);
}
}
}
}
/**
Replace the content of the given node
if there is a translation for the given key.
**/
translateNodeContent(node, key) {
const translation = this.t(key);
if (node != null && translation !== undefined) {
if (node.nodeType === 1) {
//Element
try {
if (node.innerHTML !== translation) node.innerHTML = translation;
} catch (e) {
if (node.text !== translation) node.text = translation;
}
} else if (node.nodeType === 2) {
//Attribute
if (node.value !== translation) node.value = translation;
}
}
}
/*
Helper for translating a node
and all its child nodes.
*/
processNode(node) {
if (node !== undefined) {
if (node.nodeType === 1) {
//Element node
const key = node.attributes["data-trans"];
if (key != null) {
this.translateTag(node, key.nodeValue);
}
}
//Process child nodes
const children = node.childNodes;
for (let i = 0; i < children.length; i++) {
this.processNode(children[i]);
}
}
}
/*
Adds a locale to the list,
replacing the translations
if the locale is already defined.
*/
addLocale(locale, translations) {
if (this.overwrites[locale.toString()] !== undefined) {
this.mergeDeep(translations, this.overwrites[locale.toString()]);
}
this.locales[locale.toString()] = translations;
}
fetchLocale(locale) {
return fetch(`/locales/${locale}.json`).then((result) => {
if (result.ok) {
result.json().then((e) => {
this.addLocale(locale, e);
});
}
});
}
/*
Sets the locale to use when translating.
*/
setLocale(locale) {
try {
this.fetchLocale(locale).then(() => {
if (this.locale) {
localStorage.setItem("language", this.locale);
}
this.processPage();
this.locale = locale;
});
} catch {
if (locale !== this.defaultLocale) {
console.warn(
`Locale not found: ${locale}, fallback to ${this.defaultLocale}`,
);
this.setLocale(this.defaultLocale);
} else {
console.error("Language not found");
}
}
}
/*
Fetches the translation associated with the given key.
*/
t(key) {
let translations = this.locales[this.locale];
if (translations === undefined) {
if (this.locales.length > 1) {
translations = this.locales[this.defaultLocale];
}
}
if (translations !== undefined) {
let translation = key
.toString()
.split(".")
.reduce((o, i) => (o ? o[i] : undefined), translations);
if (typeof translation === "string") {
return translation;
}
try {
const keySplitted = key.toString().split(".");
const first = keySplitted.shift();
translation = translations[first][keySplitted.join(".")];
return translation;
} catch {
return translations[key.toString()];
}
}
return undefined;
}
/*
Alias for JsI18n.t
*/
translate(key) {
this.t(key);
}
/**
Replaces the contents of all tags
that have the data-trans attribute set.
**/
processPage() {
this.processNode(document.getElementsByTagName("html")[0]);
}
}
//Global
window.orbit.intl = new JsI18n();
document.addEventListener("DOMContentLoaded", () => {
// Detect the lang & initialize, based on the browser or "language" item from localstorage
window.orbit.intl.detectLanguage();
let timer;
let timer2;
new MutationObserver((mutations) => {
for (const mutation of mutations) {
if (mutation.target.attributes["data-trans"] != null) {
// Render the target of the mutation instantly
window.orbit.intl.processNode(mutation.target);
// Then wait one arbitrary second to re-render the whole document in case a widget re-rendered
clearTimeout(timer);
timer = setTimeout(
() => window.orbit.intl.processNode(document.querySelector("body")),
500,
);
}
// Hotfix for Secoia
if (mutation.target.nodeName === "SOLID-DIRECTORY") {
if (!timer2) {
setTimeout(() => mutation.target.render(), 1000);
timer2 = setTimeout(() => mutation.target.render(), 2000);
}
}
if (mutation.target.nodeName === "SOLID-COMMUNITIES") {
if (!timer2) {
setTimeout(() => mutation.target.render(), 1000);
timer2 = setTimeout(() => mutation.target.render(), 2000);
}
}
}
}).observe(document.body, {
subtree: true,
childList: true,
});
document.addEventListener("widgetRendered", (event) => {
window.orbit.intl.processNode(event.target);
// Then wait one arbitrary second to re-render the whole document in case a widget re-rendered
clearTimeout(timer);
timer = setTimeout(
() => window.orbit.intl.processNode(document.querySelector("body")),
500,
);
});
});
document.addEventListener("keydown", (e) => {
/*
CTRL + K : Focus on the user search
*/
if (e.ctrlKey && e.key === "k") {
document.querySelector('#general-search input[type="text"]').focus();
e.preventDefault();
}
});
window.requestLogin = false;
document.addEventListener("DOMContentLoaded", () => {
const sibAuth = document.querySelector("sib-auth");
const timeoutNoUser = setTimeout(() => {
if (sibAuth && !new URLSearchParams(window.location.search).get("code"))
sibAuth.login();
}, 15000);
if (sibAuth) {
sibAuth.getUser().then((user) => {
clearTimeout(timeoutNoUser);
if (user !== null) {
for (const el of document.querySelectorAll(".notLoggedIn")) {
el.style.visibility = "visible";
}
for (const el of document.querySelectorAll(".loggedIn")) {
el.style.display = "none";
}
for (const el of document.querySelectorAll(".loggedIn-loader")) {
el.style.display = "none";
}
} else if (sibAuth.hasAttribute("allow-anonymous")) {
for (const el of document.querySelectorAll(".notLoggedIn")) {
el.style.visibility = "visible";
}
for (const el of document.querySelectorAll(".loggedIn-loader")) {
el.style.display = "none";
}
} else {
window.requestLogin = true;
window.dispatchEvent(
new CustomEvent("requestNavigation", {
detail: {
route: "login",
wanted: true,
},
}),
);
for (const el of document.querySelectorAll(".loggedIn-loader")) {
el.style.display = "none";
}
}
});
}
});
window.addEventListener("navigate", (e) => {
if (
e.detail.route === "login" &&
!window.requestLogin &&
window.orbit.getRoute
) {
window.dispatchEvent(
new CustomEvent("requestNavigation", {
detail: {
route: window.orbit.getRoute(
window.orbit.defaultRoute || "dashboard",
true,
),
},
}),
);
}
});
const goToLoginHandler = () => {
const loggedInElements = document.querySelectorAll(".loggedIn");
for (const el of loggedInElements) {
el.style.display = "none";
}
const loggedInLoaders = document.querySelectorAll(".loggedIn-loader");
for (const el of loggedInLoaders) {
el.style.display = "flex";
}
setTimeout(() => {
document.querySelector("#something-goes-wrong").removeAttribute("hidden");
}, 5000);
if (!new URLSearchParams(window.location.search).get("code"))
document.querySelector("sib-auth").login();
};
const loginButton = document.querySelector("#loginButton");
if (loginButton) {
loginButton.addEventListener("click", goToLoginHandler);
}
const loginButtonHeader = document.querySelector("#loginButtonHeader");
if (loginButtonHeader) {
loginButtonHeader.addEventListener("click", goToLoginHandler);
}
document.addEventListener("DOMContentLoaded", () => {
const MenuTabs = Array.from(document.querySelectorAll(".jsMenuTab"));
if (MenuTabs) {
for (const menuTab of MenuTabs) {
const menuHeader = menuTab.querySelector(".jsMenuHeader");
const menuArrow = menuTab.querySelector(".jsMenuArrow");
const menuSub = menuTab.querySelector(".jsMenuSub");
const menuOption = menuTab.querySelector(".jsMenuOption");
const menuAdmin = menuTab.querySelector(".jsMenuAdmin");
const isParent = (refNode, otherNode) => {
let parent = otherNode.parentNode;
do {
if (refNode === parent) {
return true;
}
parent = parent.parentNode;
} while (parent);
return false;
};
if (menuAdmin) {
menuAdmin.addEventListener(
"mouseover",
function (ev) {
if (!isParent(this, ev.relatedTarget) && ev.target === this) {
menuAdmin.classList.toggle("hidden", false);
}
},
false,
);
menuAdmin.addEventListener(
"mouseout",
function (ev) {
if (!isParent(this, ev.relatedTarget) && ev.target === this) {
menuAdmin.classList.toggle("hidden", true);
}
},
false,
);
menuAdmin.querySelector("solid-link").addEventListener("click", (_) => {
menuAdmin.classList.toggle("hidden", true);
});
}
if (menuHeader) {
menuHeader.addEventListener("click", (_) => {
menuArrow.classList.toggle("transform-up");
menuSub.classList.toggle("hidden");
});
}
if (menuOption) {
menuOption.addEventListener("click", (e) => {
menuAdmin.classList.toggle("hidden");
e.stopPropagation();
});
}
}
}
const searchForm = document.querySelector(".menu-search");
if (searchForm) {
searchForm.addEventListener("formChange", () => {
if (document.querySelector(".menu-search input").value !== "") {
searchForm.style.backgroundColor = "#202B3C";
document
.querySelector("#main__menu")
.classList.toggle("searching", true);
} else {
searchForm.style.backgroundColor = "var(--color-heading)";
document
.querySelector("#main__menu")
.classList.toggle("searching", false);
}
});
}
});
// auxiliary function closes the user profile menu
function closeUserControls() {
const userControls = Array.from(document.querySelectorAll(".user-controls"));
for (const e of userControls) {
e.removeAttribute("open");
}
}
function closeLeftMenu() {
const leftMenu = document.querySelector("#main__menu");
if (leftMenu) leftMenu.removeAttribute("open");
}
function closeRightMenu() {
const rightMenu = document.querySelectorAll(".jsRightMenu");
if (
Array.from(rightMenu).filter((el) => el.hasAttribute("open")).length > 0
) {
for (const vC of document.querySelectorAll(".views-container")) {
vC.classList.toggle("sidebar-is-closed");
}
for (const el of document.querySelectorAll(".jsOffsiteToggle")) {
el.querySelector(".text-right").setAttribute("hidden", "");
el.querySelector(".text-left").removeAttribute("hidden");
}
for (const el of rightMenu) {
el.removeAttribute("open");
el.classList.add("sm-hidden");
for (const ac of el.parentElement.querySelectorAll(
".jsMobileRightMenuButton",
)) {
ac.classList.remove("icon-close");
ac.classList.add("icon-options-vertical");
}
}
}
}
function openRightMenu() {
const rightMenu = document.querySelectorAll(".jsRightMenu");
for (const el of rightMenu) {
el.setAttribute("open", "");
el.classList.remove("sm-hidden");
for (const ac of el.parentElement.querySelectorAll(
".jsMobileRightMenuButton",
)) {
ac.classList.remove("icon-options-vertical");
ac.classList.add("icon-close");
}
}
for (const el of document.querySelectorAll(".jsOffsiteToggle")) {
el.querySelector(".text-left").setAttribute("hidden", "");
el.querySelector(".text-right").removeAttribute("hidden");
}
for (const vC of document.querySelectorAll(".views-container")) {
vC.classList.toggle("sidebar-is-closed");
}
}
function closeRightMobileMenu() {
const rightMenu = document.querySelectorAll(".jsRightMenu");
if (
Array.from(rightMenu).filter((el) => el.hasAttribute("mobile-open"))
.length > 0
) {
for (const el of rightMenu) {
el.removeAttribute("mobile-open");
el.classList.add("sm-hidden");
for (const ac of el.parentElement.querySelectorAll(
".jsMobileRightMenuButton",
)) {
ac.classList.remove("icon-close");
ac.classList.add("icon-options-vertical");
}
}
}
}
function openRightMobileMenu() {
const rightMenu = document.querySelectorAll(".jsRightMenu");
for (const el of rightMenu) {
el.setAttribute("mobile-open", "");
el.classList.remove("sm-hidden");
for (const ac of el.parentElement.querySelectorAll(
".jsMobileRightMenuButton",
)) {
ac.classList.remove("icon-options-vertical");
ac.classList.add("icon-close");
}
}
}
document.addEventListener("DOMContentLoaded", () => {
// Workaround - No "navigate" event after the login on `/login`
if (window.location.pathname === "/login") {
const sibAuth = document.querySelector("sib-auth");
const timeoutNoUser = setTimeout(() => {
if (!new URLSearchParams(window.location.search).get("code"))
sibAuth.login();
}, 15000);
if (sibAuth) {
sibAuth.getUser().then((user) => {
clearTimeout(timeoutNoUser);
if (user !== null) {
window.dispatchEvent(
new CustomEvent("requestNavigation", {
detail: {
route: window.orbit.getRoute(
window.orbit.defaultRoute || "dashboard",
true,
),
},
}),
);
}
});
}
}
//- View change event
window.addEventListener("navigate", (e) => {
if (e.detail?.route) {
Array.from(
document.querySelectorAll(
"orbit-menu-fix-url-circle solid-link solid-display",
),
).map((e) => e.toggleAttribute("active", false));
const routes = e.detail.route.split("-");
if (
/\/circles\/[0-9]\/*/.test(sibRouter.currentResource) &&
((routes.length > 1 && routes[0] === "circles") ||
(routes.length > 2 &&
["events", "resources"].includes(routes[0]) &&
(routes[0] === routes[2] ||
routes[routes.length - 1] === "create")))
) {
const target = document.querySelector(
`orbit-menu-fix-url-circle solid-link[data-src='${sibRouter.currentResource}'] solid-display`,
);
if (target) {
setTimeout(() => target.toggleAttribute("active", true), 0);
}
}
}
if (orbit.componentSet.has("admin")) {
const onlyAdmin = document.querySelector(".only-on-admin");
if (onlyAdmin) {
if (e.detail.route.startsWith("admin-")) {
onlyAdmin.removeAttribute("hidden");
} else {
onlyAdmin.setAttribute("hidden", "");
}
}
for (const component of window.orbit.components) {
const adminTarget = document.querySelector(
`solid-route[name="admin-${component.route}"]`,
);
const adminTargetTwo = document.querySelector(
`.jsRightMenu solid-link[next="admin-${component.route}"]`,
);
if (e.detail.route.startsWith(`admin-${component.route}`)) {
if (adminTarget) adminTarget.setAttribute("active", "");
if (adminTargetTwo) adminTargetTwo.setAttribute("active", "");
} else {
if (adminTarget) adminTarget.removeAttribute("active");
if (adminTargetTwo) adminTargetTwo.removeAttribute("active");
}
}
}
closeLeftMenu();
closeUserControls();
if (e.detail.route.startsWith("login")) {
const sibAuth = document.querySelector("sib-auth");
const timeoutNoUser2 = setTimeout(() => {
if (new URLSearchParams(window.location.search).get("code"))
sibAuth.login();
}, 15000);
if (sibAuth) {
sibAuth.getUser().then((user) => {
clearTimeout(timeoutNoUser2);
if (user !== null) {
window.dispatchEvent(
new CustomEvent("requestNavigation", {
detail: {
route: window.orbit.getRoute(
window.orbit.defaultRoute || "dashboard",
true,
),
},
}),
);
}
});
}
}
});
// Document -> close menu
document.addEventListener("click", (event) => {
if (!event.target.closest(".user-controls")) {
closeUserControls();
}
if (
!event.target.closest("#main__menu") &&
event.target.id !== "toggleMainMenu"
) {
closeLeftMenu();
}
if (
!event.target.closest(".jsOffsiteToggle") &&
!event.target.classList.contains("jsMobileRightMenuButton")
) {
closeRightMenu();
closeRightMobileMenu();
}
});
// listen for keypress
document.onkeydown = (e) => {
if (e.key === "Escape" || e.key === "Esc") {
closeUserControls();
closeLeftMenu();
closeRightMenu();
closeRightMobileMenu();
}
};
const toggleMainMenu = document.querySelector("#toggleMainMenu");
if (toggleMainMenu) {
toggleMainMenu.addEventListener("click", () => {
const leftMenu = document.querySelector("#main__menu");
if (leftMenu.hasAttribute("open")) {
closeLeftMenu();
} else {
leftMenu.setAttribute("open", "");
}
});
}
const rightMenus = Array.from(document.querySelectorAll("nav.jsRightMenu"));
for (const rightMenu of rightMenus) {
const btnRightMenu = rightMenu.querySelector("li.jsOffsiteToggle");
btnRightMenu.addEventListener("click", () => {
if (rightMenu.hasAttribute("open")) {
closeRightMenu();
} else {
openRightMenu();
}
});
}
for (const el of document.querySelectorAll(".jsMobileRightMenuButton")) {
el.addEventListener("click", () => {
if (
el
.closest(".jsMobileContentSidebarControl")
.querySelector("nav.jsRightMenu")
.hasAttribute("mobile-open")
) {
closeRightMobileMenu();
} else {
openRightMobileMenu();
}
});
}
});
import { Swal } from "@helpers/utils";
document.addEventListener("DOMContentLoaded", () => {
const Toast = Swal.mixin({
toast: true,
position: "top",
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.addEventListener("mouseenter", Swal.stopTimer);
toast.addEventListener("mouseleave", Swal.resumeTimer);
},
});
document.addEventListener("save", () => {
Toast.fire({
icon: "success",
title: document.querySelector("#swal-content-text").innerHTML,
});
});
});
import { registerSW } from "virtual:pwa-register";
import { Swal } from "@helpers/utils";
const updateSW = registerSW({
onNeedRefresh() {
if (orbit.intl.t("serviceWorker.newUpdate") !== undefined) {
Swal.fire({
position: "bottom-end",
backdrop: false,
title: "",
text: `${orbit.intl.t("serviceWorker.newUpdate")}.`,
imageUrl:
orbit.client.logo ||
"https://cdn.startinblox.com/logos/webp/startinblox.webp",
imageAlt: orbit.client.name,
showCancelButton: true,
confirmButtonClass:
"button text-xsmall text-bold text-center reversed color-secondary bordered icon icon-check icon-margin-right-xsmall no-background-image",
cancelButtonClass:
"button text-xsmall text-bold text-center reversed color-primary bordered icon icon-exclamation icon-margin-right-xsmall no-background-image",
confirmButtonText: orbit.intl.t("serviceWorker.yes"),
cancelButtonText: orbit.intl.t("serviceWorker.no"),
}).then((result) => {
if (result.isConfirmed) {
updateSW();
}
});
}
},
});
setTimeout(() => {
const loggedinLoader = document.querySelector(".loggedIn-loader");
if (loggedinLoader) {
if (loggedinLoader.style.display !== "none") {
const somethingGoesWrong = document.querySelector(
"#something-goes-wrong",
);
if (somethingGoesWrong) {
somethingGoesWrong.removeAttribute("hidden");
}
}
}
}, 15000);
document.addEventListener("DOMContentLoaded", () => {
window.addEventListener("newMessage", (event) => {
const jid = event.detail.jid;
for (const el of document.querySelectorAll(`[data-jabberID="${jid}"]`)) {
el.parentElement.parentElement.parentElement.classList.add("unread");
}
});
window.addEventListener("read", (event) => {
if (event.detail?.resource?.["@id"]) {
const badge = document.querySelector(
`solid-badge[data-src="${event.detail.resource["@id"]}"]`,
);
if (badge) {
badge.parentElement.parentElement.parentElement.classList.remove(
"unread",
);
const project =
badge.parentElement.parentElement.parentElement.querySelector(
".unread",
);
if (project) project.classList.remove("unread");
}
}
});
});
document.addEventListener("DOMContentLoaded", () => {
const userCreationForm = document.querySelector("#user-creation-form");
if (userCreationForm) {
userCreationForm.addEventListener("save", (event) => {
if (event.originalTarget.id === "user-creation-form") {
if (!new URLSearchParams(window.location.search).get("code"))
document.querySelector("sib-auth").login();
}
});
}
});
#about {
>div>div>div {
min-height: 285px;
}
}
\ No newline at end of file
@font-face {
font-family: 'RefrigeratorDelxW01Bold';
src: url('../fonts/RefrigeratorDelxW01Bold.eot');
src: url('../fonts/RefrigeratorDelxW01Bold.eot') format('embedded-opentype'),
url('../fonts/RefrigeratorDelxW01Bold.woff') format('woff'),
url('../fonts/RefrigeratorDelxW01Bold.ttf') format('truetype'),
url('../fonts/RefrigeratorDelxW01Bold.svg#RefrigeratorDelxW01Bold') format('svg');
font-weight: bold;
}
@font-face {
font-family: 'Facit';
src: url('../fonts/FacitRegular.eot');
src: url('../fonts/FacitRegular.eot') format('embedded-opentype'),
url('../fonts/FacitRegular.woff2') format('woff2'),
url('../fonts/FacitRegular.woff') format('woff'),
url('../fonts/FacitRegular.ttf') format('truetype'),
url('../fonts/FacitRegular.svg#FacitRegular') format('svg');
font-weight: 400;
}
@font-face {
font-family: 'Facit';
src: url('../fonts/FacitBold.eot');
src: url('../fonts/FacitBold.eot') format('embedded-opentype'),
url('../fonts/FacitBold.woff2') format('woff2'),
url('../fonts/FacitBold.woff') format('woff'),
url('../fonts/FacitBold.ttf') format('truetype'),
url('../fonts/FacitBold.svg#FacitBold') format('svg');
font-weight: 700;
}
\ No newline at end of file
@mixin window-style-modal($background: $color-0-0-100, $shadow: hsla(212, 7%, 55%, 0.19)) {
box-shadow: 0 0 8px 0 $shadow;
background-color: $background;
}
@mixin breakpoint($min: 0, $max: 0) {
$type: type-of($min);
@if $type==string {
@if $min==xs {
@media (max-width: 768px) {
@content;
}
}
@else if $min==sm {
@media (max-width: 1024px) {
@content;
}
}
@else if $min==md {
@media (max-width: 1200px) {
@content;
}
}
@else if $min==lg {
@media (min-width: 1201px) {
@content;
}
}
@else {
@warn "Beware ! Breakpoints mixin supports xs, sm, md, lg";
}
}
@else if $type==number {
$query: "all" !default;
@if $min !=0 and $max !=0 {
$query: "(min-width: #{$min}) and (max-width: #{$max})";
}
@else if $min !=0 and $max==0 {
$query: "(min-width: #{$min})";
}
@else if $min==0 and $max !=0 {
$query: "(max-width: #{$max});"
}
@media #{$query} {
@content;
}
}
}
// Color Variables
$color-43-100-50: hsl(43, 100%, 50%);
$color-45-95-54: hsl(45, 95%, 54%);
$color-46-100-67: hsl(46, 100%, 67%);
$color-46-100-50: hsl(46, 100%, 50%);
$color-0-0-100: hsl(0, 0%, 100%);
$color-218-100-98: hsl(218, 100%, 98%);
$color-210-17-91: hsl(210, 17%, 91%);
$color-222-52-90: hsl(222, 52%, 90%);
$color-210-25-95: hsl(210, 25%, 95%);
$color-222-57-95: hsl(222, 57%, 95%);
$color-213-20-91: hsl(213, 20%, 91%);
$color-221-51-90: hsl(221, 51%, 90%);
$color-228-25-79: hsl(228, 25%, 79%);
$color-0-0-85: hsl(0, 0%, 85%);
$color-229-25-79: hsl(229, 25%, 79%);
$color-215-9-73: hsl(215, 9%, 73%);
$color-244-10-70: hsl(244, 10%, 70%);
$color-215-6-63: hsl(215, 6%, 63%);
$color-210-5-56: hsl(210, 5%, 56%);
$color-210-4-50: hsl(210, 4%, 50%);
$color-212-4-50: hsl(212.7,4.3%,50%);
$color-213-4-50: hsl(213, 4%, 50%);
$color-213-13-86: hsla(213, 13%, 86%, 0.2);
$color-0-0-29: hsl(0, 0%, 29%);
$color-0-0-22: hsl(0,0%,22.7%);
$color-203-87-19: hsl(203, 87.8%, 19.2%);
$color-233-18-29: hsl(233, 18%, 29%);
$color-233-20-17: hsl(233, 20%, 17%);
$color-216-4-22: hsl(216, 4%, 22%);
$color-244-73-62: hsl(244, 73%, 62%);
$color-357-67-45: hsl(357,67.5%,45.9%);
#admin-circles,
#admin-circles-leave,
.communities-directory {
.masonry > div:nth-child(1) {
/* change from directory (nth-child(2))*/
display: flex !important;
flex-wrap: wrap;
align-items: center;
.circle-subtitle-custom {
height: 32px;
}
}
.segment.hover:hover {
box-shadow: 0 0 16px 0 rgba(46, 63, 88, 0.34);
bottom: 2px;
cursor: pointer;
}
orbit-admin-circle-name:hover {
text-decoration: underline;
}
orbit-admin-community-logo {
height: 76px;
width: 100%;
display: block;
div {
display: block;
width: 100%;
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
}
.tab.active {
font-weight: bold;
border-bottom: 5px solid var(--color-third);
padding-bottom: 10px;
}
.communities-profile-picture {
> div:not(:empty) {
height: 200px;
div:first-child {
display: block;
width: 100%;
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
}
.picture-empty {
display: none;
}
}
@media (max-width: 768px) {
.tabs {
& > li {
color: #3c3f57;
font-size: 13px;
letter-spacing: 0.18px;
line-height: 17px;
& > .tab {
border-radius: 5px;
box-shadow: 0 0 6px 0 rgba(46, 63, 88, 0.17);
&.active {
color: var(--color-primary);
border: 1px solid var(--color-primary);
box-shadow: none;
}
}
}
}
orbit-communities-profile-logo {
height: 100px;
}
.communities-profile-picture {
> div:not(:empty) {
height: 180px;
}
}
}
}