Merge branch 'master' into feature/community-directory

This commit is contained in:
Jean-Baptiste Pasquier 2021-04-09 11:05:20 +02:00
commit 3811e74a88
23 changed files with 2139 additions and 1022 deletions

View File

@ -527,10 +527,11 @@ Module declaration, on `config.json`:
"endpoints": {
"get": "http://server.url/resources/",
"post": "http://server.url/resources/",
"types": "http://server.url/keywords/",
"keywords": "http://server.url/types/",
"postTypes": "http://server.url/keywords/",
"postKeywords": "http://server.url/types/"
"types": "http://server.url/types/",
"keywords": "http://server.url/keywords/",
"postTypes": "http://server.url/types/",
"postKeywords": "http://server.url/keywords/",
"uploads": "http://server.url/upload/"
}
}
```

2473
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,6 +15,9 @@
"cypress:info": "cypress info",
"test": "cypress run"
},
"browserslist": [
"last 2 Chrome versions"
],
"release": {
"branches": [
"master"
@ -44,12 +47,22 @@
"@semantic-release/gitlab"
]
},
"cache": {
"strategy": "inject",
"swSrc": "./src/service-worker.js",
"swDest": "service-worker.js",
"globPatterns": [
"**/*.{html,js,map,css,jpg,png,gif,webp,svg,eot,ttf,woff,woff2,json}"
],
"clearDist": false
},
"dependencies": {
"@startinblox/hubl-styling-framework": "^1.8.21",
"cross-env": "^7.0.3",
"fs-extra": "^9.0.1",
"normalize.css": "^8.0.1",
"parcel-bundler": "^1.12.4",
"parcel-bundler": "^1.12.5",
"parcel-plugin-sw-cache": "^0.3.1",
"pug": "^3.0.0",
"rimraf": "^2.7.1",
"sass": "^1.29.0"

View File

@ -1,34 +0,0 @@
import {
widgetFactory,
Helpers
} from 'https://cdn.skypack.dev/@startinblox/core@0.16';
import SlimSelect from 'https://cdn.skypack.dev/slim-select@1.23';
const HublStatus = widgetFactory(
'hubl-status',
`<label>\${label}</label>
<select
data-holder
name="\${name}">
<option
value="Public"
\${value=="Public" ? 'selected' : ''} data-trans="hublStatus.public">Public</option>
<option
value="Private"
\${value=="Private" ? 'selected' : ''} data-trans="hublStatus.private">Privé</option>
</select>`,
'',
formWidget => {
let select = formWidget.querySelector('select');
if (!select) return;
const slimSelect = new SlimSelect({
select: select
});
Helpers.importCSS('https://dev.jspm.io/slim-select/dist/slimselect.min.css');
select.addEventListener('change', () => slimSelect.render());
},
);
export {
HublStatus
}

View File

@ -0,0 +1,47 @@
import {
Workbox,
messageSW
} from 'https://storage.googleapis.com/workbox-cdn/releases/6.1.1/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
const wb = new Workbox('/service-worker.js');
let registration;
const showSkipWaitingPrompt = (event) => {
if(hubl.intl.t('serviceWorker.newUpdate') != undefined) {
Swal.fire({
position: 'bottom-end',
backdrop: false,
title: "",
text: hubl.intl.t('serviceWorker.newUpdate') + ". " + hubl.intl.t('serviceWorker.wantToUpdate'),
imageUrl: hubl.client.logo || 'https://cdn.startinblox.com/logos/webp/hubl.webp',
imageAlt: hubl.client.name,
showCancelButton: true,
confirmButtonClass: 'button text-xsmall text-bold text-center reversed color-secondary bordered icon icon-check no-background-image',
cancelButtonClass: 'button text-xsmall text-bold text-center reversed color-primary bordered icon icon-exclamation no-background-image',
confirmButtonText: hubl.intl.t('serviceWorker.yes'),
cancelButtonText: hubl.intl.t('serviceWorker.no')
}).then((result) => {
if (result.isConfirmed) {
wb.addEventListener('controlling', (event) => {
window.location.reload();
});
if (registration && registration.waiting) {
messageSW(registration.waiting, {
type: 'SKIP_WAITING'
});
}
}
});
}
};
wb.addEventListener('waiting', showSkipWaitingPrompt);
wb.addEventListener('externalwaiting', showSkipWaitingPrompt);
wb.register().then((r) => registration = r);
});
}

View File

@ -47,9 +47,8 @@ if componentSet.has("profileDirectory")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-directory@5.1" defer)
//- script(type="module" src="/lib/solid-directory/dist/index.js" defer)
//- Disabled - Not in core@0.16
//- if componentSet.has("resources")
script(type="module", src="https://cdn.skypack.dev/@startinblox/component-resource@2.0", defer)
if componentSet.has("resources")
script(type="module", src="https://cdn.skypack.dev/@startinblox/component-resource@3.1", defer)
//- script(type="module" src="/lib/solid-resource/solid-resource.js" defer)
if componentSet.has("themeChecker")

View File

@ -60,5 +60,5 @@ for component of components
defaultRoute = defaultComponent[0].uniq;
}
- const hublComponents = `window.hubl={};window.hubl.components = ${JSON.stringify(components)};window.hubl.defaultRoute = "${defaultRoute}";`;
- const hublComponents = `window.hubl={};window.hubl.components = ${JSON.stringify(components)};window.hubl.defaultRoute = "${defaultRoute}";window.hubl.client = ${JSON.stringify(client)}`;
script!=hublComponents

View File

@ -31,8 +31,8 @@ html(lang="en")
script(type="module" src="/components/sentry.js" defer)
script(type="module" src="/components/hubl-auto-login.js" defer)
script(type="module" src="/components/hubl-search-users.js" defer)
script(type="module" src="/components/hubl-status.js" defer)
script(type="module" src="/components/hubl-reactivity.js" defer)
script(type="module" src="/components/sw-toolbox.js" defer)
script(src="index.js" defer)
include dependencies.pug

View File

@ -33,13 +33,7 @@
"circlesBrowse": "Browse circles",
"circleCreate": "Create circle",
"messages": "Messages",
"search": "Search...",
"republiqueESS": {
"home": "Home",
"contribute": "Contribute",
"thematics": "Thematics",
"community": "Community"
}
"search": "Search"
},
"about": {
"title": "About",
@ -132,10 +126,7 @@
"subTitle": "Members :"
},
"extensions": {
"associated": "Associated circle",
"republiqueESS": {
"associatedThematic": "Associated thematic"
}
"associated": "Associated circle"
}
},
"communities": {
@ -281,10 +272,7 @@
"template-captain": {
"isLead": "Captain"
},
"hublStatus": {
"private": "Private",
"public": "Public"
},
"hublStatus": "Public = Public, Private = Private",
"success": "Success!",
"errors": {
"somethingGoesWrong": "Something goes wrong, try to",
@ -345,5 +333,11 @@
"edit": "Edit",
"back": "Back",
"goButton": "GO"
},
"serviceWorker": {
"newUpdate": "A new version is available",
"wantToUpdate": "Do you want to update?",
"yes": "Yes",
"no": "No"
}
}

View File

@ -33,13 +33,7 @@
"circlesBrowse": "Examinar los círculos",
"circleCreate": "Crea un círculo.",
"messages": "Mensajes",
"search": "Buscar...",
"republiqueESS": {
"home": "Hogar",
"contribute": "Contribuir",
"thematics": "Temáticas",
"community": "Comunidad"
}
"search": "Buscar"
},
"about": {
"title": "Acerca de",
@ -132,10 +126,7 @@
"subTitle": "Miembrxs: "
},
"extensions": {
"associated": "Círculo asociado",
"republiqueESS": {
"associatedThematic": "Temática asociada"
}
"associated": "Círculo asociado"
}
},
"communities": {
@ -281,10 +272,7 @@
"template-captain": {
"isLead": "Líder"
},
"hublStatus": {
"private": "Privado",
"public": "Público"
},
"hublStatus": "Público = Public, Privado = Private",
"success": "¡Éxito!",
"errors": {
"somethingGoesWrong": "Algo sale mal, intenta",
@ -345,5 +333,11 @@
"edit": "Modificar",
"back": "Atrás",
"goButton": "GO"
},
"serviceWorker": {
"newUpdate": "Una nueva version esta disponible",
"wantToUpdate": "¿Quieres actualizar?",
"yes": "Sí",
"no": "No"
}
}

View File

@ -9,9 +9,7 @@
},
"menuLeft": {
"emptyCircleProjectContact": {
"empty": "Il n'y a aucun résultat dans cette section.",
"project": "projet",
"circle": "cercle"
"empty": "Il n'y a aucun résultat dans cette section."
},
"contact": {
"create": "Retrouve tes contacts sur",
@ -33,13 +31,7 @@
"circlesBrowse": "Parcourir les cercles",
"circleCreate": "Créer un cercle",
"messages": "Messages",
"search": "Rechercher...",
"republiqueESS": {
"home": "Accueil",
"contribute": "Contribuer",
"thematics": "Thématiques",
"community": "Communauté"
}
"search": "Rechercher"
},
"about": {
"title": "A propos",
@ -132,10 +124,7 @@
"subTitle": "Membres :"
},
"extensions": {
"associated": "Cercle associé",
"republiqueESS": {
"associatedThematic": "Thématique associée"
}
"associated": "Cercle associé"
}
},
"communities": {
@ -281,10 +270,7 @@
"template-captain": {
"isLead": "Capitaine"
},
"hublStatus": {
"private": "Privé",
"public": "Public"
},
"hublStatus": "Public = Public, Privé = Private",
"success": "Succès!",
"errors": {
"somethingGoesWrong": "Quelque chose ne va pas, essayez de",
@ -345,5 +331,11 @@
"edit": "Editer",
"back": "Retour",
"goButton": "GO"
},
"serviceWorker": {
"newUpdate": "Une nouvelle version est disponible",
"wantToUpdate": "Voulez-vous mettre à jour ?",
"yes": "Oui",
"no": "Non"
}
}

View File

@ -6,27 +6,27 @@ 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.
*/
detectLanguage() {
async detectLanguage() {
const customLangs = document.querySelectorAll('hubl-lang');
if (customLangs) {
for (let lang of customLangs) {
let name = lang.getAttribute('lang'),
file = lang.getAttribute('file');
if(window.hubl.intl.locales[name.toString()] == undefined) {
return fetch(file).then((result) => {
let result = await fetch(file);
if (result.ok) {
result.json().then(e => {
window.hubl.intl.addLocale(name, e);
});
let json = await result.json();
if(this.overwrites[name.toString()] != undefined) {
this.mergeDeep(this.overwrites[name.toString()], json);
} else {
this.overwrites[name.toString()] = json;
}
window.hubl.intl.resumeDetection();
});
}
}
}
@ -52,6 +52,30 @@ class JsI18n {
}
};
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
@ -78,6 +102,17 @@ class JsI18n {
this.translateNodeContent(label, k);
}
}
// https://git.startinblox.com/framework/sib-core/issues/755
if (attr.startsWith('placeholder-')) {
let placeholder = node.querySelector('[placeholder="' + attr.replace("placeholder-", "") + '"]');
if (placeholder != null) {
this.translateNodeContent(placeholder.attributes['placeholder'], k);
let input = node.querySelector('[name="' + attr.replace("placeholder-", "") + '"] > input');
if (input != null) {
this.translateNodeContent(input.attributes['placeholder'], k);
}
}
}
this.translateNodeContent(node.attributes[attr], k);
}
}
@ -134,11 +169,13 @@ class JsI18n {
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) {
if(this.locales[locale.toString()] == undefined) {
return fetch(`/locales/${locale}.json`).then((result) => {
if (result.ok) {
result.json().then(e => {
@ -146,9 +183,6 @@ class JsI18n {
});
}
});
} else {
return (new Promise()).resolve();
}
}
/*

View File

@ -1,11 +0,0 @@
if ('serviceWorker' in navigator) {
var refreshing;
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (refreshing) {
return;
}
refreshing = true;
window.location.reload();
});
navigator.serviceWorker.register('/sw.js');
}

81
src/service-worker.js Normal file
View File

@ -0,0 +1,81 @@
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.1.1/workbox-sw.js');
workbox.precaching.precacheAndRoute([]);
addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') {
skipWaiting();
}
});
workbox.routing.registerRoute(
({url}) => url.origin === 'https://fonts.gstatic.com',
new workbox.strategies.CacheFirst({
cacheName: 'google-fonts-webfonts',
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [0, 200],
}),
new workbox.expiration.ExpirationPlugin({
maxAgeSeconds: 60 * 60 * 24 * 365,
maxEntries: 30,
}),
],
})
);
workbox.routing.registerRoute(
({url}) => [
'https://cdn.jsdelivr.net',
'https://unpkg.com',
'https://cdn.skypack.dev',
'https://jspm.dev',
'https://fonts.googleapis.com',
'https://cdn.startinblox.com'
].includes(url.origin),
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'cdn',
})
);
workbox.routing.registerRoute(
({ request }) => request.destination === 'image',
new workbox.strategies.CacheFirst({
cacheName: 'images',
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [200],
}),
new workbox.expiration.ExpirationPlugin({
maxEntries: 300,
maxAgeSeconds: 60 * 60 * 24 * 30,
}),
],
}),
);
workbox.routing.registerRoute(
({ request }) =>
request.destination === 'style' ||
request.destination === 'script',
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'assets',
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [200],
}),
],
}),
);
workbox.routing.registerRoute(
({ request }) => request.mode === 'navigate',
new workbox.strategies.NetworkFirst({
cacheName: 'pages',
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({
statuses: [200],
}),
],
}),
);

View File

@ -2,6 +2,10 @@ main {
height: 100vh;
}
.no-background-image {
background-image: none !important;
}
/* Styles of the right-hand menu + pages with that menu */
.with-sidebar {
flex-grow: 1;

View File

@ -131,10 +131,10 @@ nav#main__menu {
.menu-admin {
position: absolute;
z-index: 3016;
left: 78px;
left: 15%;
top: 36px;
text-align: end;
width: 64%;
width: 80%;
@media (max-width: 768px) {
width: 100%;
@ -242,6 +242,7 @@ nav#main__menu {
solid-set-default[name="message"] {
margin-right: 9px;
width: 74%;
}
hubl-menu-contact-removed {

115
src/sw.js
View File

@ -1,115 +0,0 @@
const CACHE_NAME = 'hubl-store-epm9475';
self.addEventListener('install', function (e) {
self.skipWaiting();
e.waitUntil(
caches.open(CACHE_NAME).then(function (cache) {
return cache.addAll([
'/locales/es.json',
'/locales/fr.json',
'/scripts/index.js',
'/syles/index.css',
'/index.html',
'/'
]);
})
);
});
self.addEventListener('activate', function (e) {
// invalidate older versions
e.waitUntil(
caches.keys()
.then(function (keyList) {
return Promise.all(keyList.map(function (key) {
if (key !== CACHE_NAME && key !== (CACHE_NAME + "-cdn") && key !== (CACHE_NAME + "-api")) {
return caches.delete(key);
}
}));
}));
self.clients.claim();
});
if(process.env.NODE_ENV === 'production'){
self.addEventListener('fetch', function (event) {
let requestURL = new URL(event.request.url);
if (requestURL.origin == location.origin) {
// Static asset, cache then network
event.respondWith(
caches.open(CACHE_NAME).then(function (cache) {
return cache.match(event.request).then(function (response) {
var fetchPromise = fetch(event.request).then(function (networkResponse) {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return response || fetchPromise;
});
}),
);
} else {
if (
event.request.method == 'POST' ||
event.request.method == 'PUT'
) {
// disabled: lead to cors errors
// // POST/PUT to api, rewrite the cache
// event.respondWith(
// caches.open(CACHE_NAME + '-api').then(function (cache) {
// return fetch(event.request).then(function (response) {
// cache.put(event.request, response.clone());
// return response;
// })
// }));
// api: no cache
event.respondWith(fetch(event.request));
} else if (
/matomo/.test(requestURL.origin) ||
/sentry/.test(requestURL.origin) ||
/jabber/.test(requestURL.origin) ||
/xmpp/.test(requestURL.origin)
) {
// analytics, always distant
event.respondWith(fetch(event.request));
} else {
if (
/unpkg/.test(requestURL.origin) ||
/skypack/.test(requestURL.origin) ||
/jspm/.test(requestURL.origin) ||
/jsdeliver/.test(requestURL.origin) ||
/cdn/.test(requestURL.origin) ||
/googleapis/.test(requestURL.origin)
) {
// cdn: cache then network
event.respondWith(
caches.open(CACHE_NAME + '-cdn').then(function (cache) {
return cache.match(event.request).then(function (response) {
var fetchPromise = fetch(event.request).then(function (networkResponse) {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
return response || fetchPromise;
});
}),
);
} else {
// disabled: lead to cors errors
// // api: distant then cache
// event.respondWith(
// fetch(event.request)
// .then((response) => {
// caches.open(CACHE_NAME + '-api').then(function (cache) {
// cache.put(event.request, response.clone());
// return response;
// });
// })
// .catch(() => {
// return caches.match(event.request);
// })
// );
// api: no cache
event.respondWith(fetch(event.request));
}
}
}
});
}

View File

@ -1,6 +1,7 @@
.with-sidebar.whitespace-normal.bg-color-white.only-on-admin(hidden)
.scrollbar-content.views-container.sidebar-is-closed
for component of components
if component.route
if component.type == "circles"
div(
id=`admin-${component.route}`
@ -65,6 +66,7 @@
span.icon.icon-arrow-right.icon-xsmall.margin-right-xxsmall
a(data-trans='admin.menuRight.fold')
for component of components
if component.route
if component.type == "circles"
solid-link.segment.full(next=`admin-${component.route}`)
li.segment.full.padding-medium

View File

@ -1,7 +1,10 @@
div.whitespace-normal
solid-resource(data-src=`${component.endpoints.resources}`
range-resource-type=`${component.endpoints.resourcestypes}`
range-resource-keyword=`${component.endpoints.resourceskeywords}`
solid-resource(data-src=`${component.endpoints.get}`
post-data-src=`${component.endpoints.post}`
range-resource-type=`${component.endpoints.types}`
post-data-type-src=`${component.endpoints.postTypes}`
range-resource-keyword=`${component.endpoints.keywords}`
post-data-keyword-src=`${component.endpoints.postKeywords}`
range-resource-circle=`${getComponent('circles').endpoints.get}/`
associated-circle-label=""
data-trans=`associated-circle-label=${component.parameters && component.parameters.associatedName ? component.parameters.associatedName : 'circle.extensions.associated'}`

View File

@ -38,7 +38,8 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
range-community='store://user.communities'
option-label-community="community.name"
widget-status='hubl-status'
widget-status='solid-form-dropdown-autocompletion-label'
enum-status=""
widget-community='solid-form-dropdown-autocompletion-label'
widget-linebreak='solid-form-hidden'
@ -50,5 +51,5 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
submit-button=''
submit-widget="button"
data-trans='label-status=circle.create.labelStatus;label-community=circle.create.labelCommunity;label-name=circle.create.labelName;label-description=circle.create.labelDescription;submit-button=circle.create.buttonSubmit;label-subtitle=circle.create.labelSubtitle;label-help=circle.create.descriptionHelp'
data-trans='enum-status=hublStatus;label-status=circle.create.labelStatus;label-community=circle.create.labelCommunity;label-name=circle.create.labelName;label-description=circle.create.labelDescription;submit-button=circle.create.buttonSubmit;label-subtitle=circle.create.labelSubtitle;label-help=circle.create.descriptionHelp'
)

View File

@ -49,7 +49,8 @@ div.segment.full.padding-large.whitespace-normal
class-owner='hidden'
class-help='segment full text-small margin-bottom-medium padding-left-small'
widget-status='hubl-status'
widget-status='solid-form-dropdown-autocompletion-label'
enum-status=""
widget-description='solid-form-richtext-label'
widget-help='solid-form-hidden-label'
widget-community='solid-form-dropdown-autocompletion-label'
@ -64,7 +65,7 @@ div.segment.full.padding-large.whitespace-normal
submit-widget="button"
next=`${component.route}-information`
data-trans='label-status=circle.edit.labelStatus;label-community=circle.edit.labelCommunity;label-name=circle.edit.labelName;label-owner=circle.edit.labelOwner;label-description=circle.edit.labelDescription;submit-button=circle.edit.buttonSubmit;label-subtitle=circle.edit.labelSubtitle;label-help=circle.edit.descriptionHelp'
data-trans='enum-status=hublStatus;label-status=circle.edit.labelStatus;label-community=circle.edit.labelCommunity;label-name=circle.edit.labelName;label-owner=circle.edit.labelOwner;label-description=circle.edit.labelDescription;submit-button=circle.edit.buttonSubmit;label-subtitle=circle.edit.labelSubtitle;label-help=circle.edit.descriptionHelp'
)
h3.segment.full.padding-bottom-small.border-bottom.border-color-grey.text-color-heading.text-bold.text-letter-spacing-large(data-trans='circle.edit.subTitle')

View File

@ -45,15 +45,15 @@ div
li.segment.padding-small.border-bottom.border-color-grey
div(data-trans='header.admin')
ul.text-normal
if componentSet.has("communities")
if componentSet.has("communities") && getComponent("chat").route
solid-link.text-hover(next=`admin-${getRoute("chat", true)}`)
li.segment.padding-top-small
a.icon.icon-people.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.community')
if componentSet.has("circles")
if componentSet.has("circles") && getComponent("circles").route
solid-link.text-hover(next=`admin-${getRoute("circles", true)}`)
li.segment.padding-top-small
a.icon.icon-globe.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.circles')
if componentSet.has("projects")
if componentSet.has("projects") && getComponent("projects").route
solid-link.text-hover(next=`admin-${getRoute("projects", true)}`)
li.segment.padding-top-small
a.icon.icon-folder-alt.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.projects')
@ -96,15 +96,15 @@ div
li.segment.padding-small.sm-padding-medium.sm-padding-left-xlarge.border-bottom.border-color-grey
div(data-trans='header.admin')
ul.text-normal
if componentSet.has("communities")
if componentSet.has("communities") && getComponent("chat").route
solid-link.text-hover(next=`admin-${getRoute("chat", true)}`)
li.segment.padding-top-small.sm-padding-top-medium
a.icon.icon-grid.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.community')
if componentSet.has("circles")
if componentSet.has("circles") && getComponent("circles").route
solid-link.text-hover(next=`admin-${getRoute("circles", true)}`)
li.segment.padding-top-small.sm-padding-top-medium
a.icon.icon-globe.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.circles')
if componentSet.has("projects")
if componentSet.has("projects") && getComponent("projects").route
solid-link.text-hover(next=`admin-${getRoute("projects", true)}`)
li.segment.padding-top-small.sm-padding-top-medium
a.icon.icon-folder-alt.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.projects')

View File

@ -2,10 +2,11 @@ solid-form-search.icon.children-icon-magnifier(
id='general-search'
class='segment block form menu-search'
fields='name'
search-name='circle.name, project.customer.name, project.name, contact.username'
search-name='circle.name, project.customer.name, project.name, contact.username, contact.name'
order-asc-names='name'
label-name='Rechercher'
placeholder-name=''
data-trans='placeholder-name=menuLeft.search'
widget-name="solid-form-placeholder-text"
submit-button=""