Merge branch 'master' into solid-resource

This commit is contained in:
antoine37120 2021-04-19 14:47:47 +02:00
commit 3c32e3880a
69 changed files with 3353 additions and 1161 deletions

View File

@ -5,7 +5,7 @@ stages:
- integration
- acceptance
- release
- deployment
- deploy
# default image for jobs
default:
@ -33,6 +33,7 @@ build:
- dist/
except:
- tags
- feature/ansible
tags:
- test
@ -53,6 +54,7 @@ test:e2e:
- cypress run -e CYPRESS_baseUrl=http://localhost:3000
except:
- tags
- feature/ansible
tags:
- test
@ -67,8 +69,10 @@ test1:
extends: .ansible
stage: integration
environment:
name: test1
name: dev/test1
url: https://test1.startinblox.com
variables:
ANSIBLE_INVENTORY: inventory/dev/
only:
- /^feature\/.*/
when: manual
@ -77,8 +81,10 @@ test2:
extends: .ansible
stage: integration
environment:
name: test2
name: dev/test2
url: https://test2.startinblox.com
variables:
ANSIBLE_INVENTORY: inventory/dev
only:
- /^feature\/.*/
when: manual
@ -87,8 +93,10 @@ test3:
extends: .ansible
stage: integration
environment:
name: test3
name: dev/test3
url: https://test3.startinblox.com
variables:
ANSIBLE_INVENTORY: inventory/dev
only:
- /^feature\/.*/
when: manual
@ -97,8 +105,10 @@ stg1:
extends: .ansible
stage: acceptance
environment:
name: stg1
name: review/stg1
url: https://stg1.startinblox.com
variables:
ANSIBLE_INVENTORY: inventory/stg
only:
- /^release\/.*/
when: manual
@ -107,8 +117,10 @@ stg2:
extends: .ansible
stage: acceptance
environment:
name: stg2
name: review/stg2
url: https://stg2.startinblox.com
variables:
ANSIBLE_INVENTORY: inventory/stg
only:
- /^release\/.*/
when: manual
@ -129,6 +141,16 @@ publish:
hublworld:
extends: .ansible
variables:
ANSIBLE_INVENTORY: inventory/prd
only:
- master
when: manual
hublunderworld:
extends: .ansible
variables:
ANSIBLE_INVENTORY: inventory/prd
only:
- master
when: manual

View File

@ -267,7 +267,8 @@ Eg.:
"get": "http://server.url/events/",
"post": "http://server.url/events/",
"typeevents": "http://server.url/typeevents/",
"postTypeevents": "http://server.url/typeevents/"
"postTypeevents": "http://server.url/typeevents/",
"uploads": "http://server.url/upload/"
}
}
]
@ -295,6 +296,24 @@ To activate community on Hubl, add this module declaration your `config.json`:
}
```
#### Activate the community directory
When you work with a federated application, you may want a directory for communities.
You can activate it by changing the route to anything else than false. Some endpoints will also get needed:
```json
{
"type": "communities",
"endpoints": {
"get": "http://server/communities/",
"addresses": "http://server/community-addresses/",
"uploads": "http://server/upload/"
},
"route": "communities"
}
```
### Dashboard
Dashboard includes card generation from HTML. To activate them, you need:
@ -335,7 +354,8 @@ Module declaration, on `config.json`:
"get": "http://server.url/events/",
"post": "http://server.url/events/",
"typeevents": "http://server.url/typeevents/",
"postTypeevents": "http://server.url/typeevents/"
"postTypeevents": "http://server.url/typeevents/",
"uploads": "http://server.url/upload/"
}
}
```
@ -404,6 +424,36 @@ Where:
Setting custom langs will not allow user to choose their own lang.
### Invoices
Invoices allow your Projects to manage invoices
Project is mandatory.
You'll need:
On Server: `djangoldp_invoice` packages
Module declaration, on `config.json`:
```json
{
"type": "projects",
"extensions": [
{
"type": "invoices",
"endpoints": {
"uploads": "http://server.url/upload/"
}
}
]
}
```
Where:
* `xmpp` is your [Prosody](https://prosody.im/) with [appropriate modules](https://git.startinblox.com/infra/prosody-modules/) configured on.
### Job Offers
Job Offers includes a job board with conversation. To activate them
@ -478,7 +528,10 @@ On `config.json`:
"type": "polls",
"endpoints": {
"get": "http://server.url/polls/",
"post": "http://server.url/polls/"
"post": "http://server.url/polls/",
"pollRangeTags": "http://server.url/tags/",
"pollRangeCircles": "http://server.url/circles/",
"uploads": "http://server.url/upload/"
}
}
```
@ -632,6 +685,29 @@ Some module don't need any route to be active, set `route` to `false` so.
Components can get the route of a module with `window.hubl.getRoute('componentName')`.
#### Change the default route
By default, Hubl will take a Dashboard as a default route.
You can enforce a component to be the default one by adding `defaultRoute` to its parameters.
Eg.:
```json
{
"type": "profileDirectory",
"endpoints": {
"get": "http://server.url/users/",
"skills": "http://server.url/skills/",
"uploads": "http://server.url/upload/"
},
"route": "directory",
"defaultRoute": true
}
```
If there is more than one component with this parameter, it'll be ignored.
## Troubleshooting
### Circles or Projects are missing the @user list

2489
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.15",
"@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

@ -4,7 +4,13 @@ script(type="module" src="https://cdn.skypack.dev/@startinblox/core@0.16" defer)
script(type="module" src="https://cdn.skypack.dev/@startinblox/router@0.11" defer)
//- script(type="module" src="/lib/sib-router/src/index.js" defer)
- const componentSet = new Set(components.map(c=>c.type));
-
const componentSet = new Set(components.map(c=>c.type));
components.map(c => {
if(c.extensions) {
c.extensions.forEach(e => componentSet.add(e.type));
}
});
if componentSet.has("autoLogin") || componentSet.has("registering")
script(type="module" src="https://cdn.skypack.dev/@startinblox/oidc@0.14" defer)
@ -14,6 +20,10 @@ if componentSet.has("chat") || componentSet.has("circles") || componentSet.has("
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-chat@5.2" defer)
//- script(type="module" src="/lib/solid-xmpp-chat/dist/index.js" defer)
if componentSet.has("communities")
script(type="module" src="https://cdn.skypack.dev/@startinblox/core@0.16/dist/components/solid-map.js" defer)
//- script(type="module" src="/lib/sib-core/dist/components/solid-map.js" defer)
if componentSet.has("dashboard")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-dashboard@4.0" defer)
//- script(type="module" src="/lib/solid-dashboard/dist/index.js" defer)
@ -23,8 +33,8 @@ if componentSet.has("events")
//- script(type="module", src="/lib/solid-event/solid-event.js", defer)
//- Disabled - Not in core@0.16
//- if componentSet.has("events") || componentSet.has("polls") || componentSet.has("resources")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-conversation@0.9" defer)
if componentSet.has("events") || componentSet.has("polls") || componentSet.has("resources")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-conversation@0.10" defer)
if componentSet.has("jobBoard")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-job-board@5.0" defer)
@ -34,10 +44,9 @@ if componentSet.has("notification")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-notifications@0.12" defer)
//- script(type="module" src="/lib/sib-notifications/index.js" defer)
//- Disabled - Not in core@0.16
//- if componentSet.has("polls")
//- script(type="module" src="https://cdn.skypack.dev/@startinblox/component-poll@1.2" defer)
//- //- script(type="module" src="/lib/sib-polls-component/index.js" defer)
if componentSet.has("polls")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-poll@2.1" defer)
//script(type="module" src="/lib/solid-poll/index.js" defer)
if componentSet.has("profileDirectory")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-directory@5.1" defer)

View File

@ -53,6 +53,22 @@ for component of components
routes.add(route);
component.route = route;
}
if(component.extensions)
for extension of component.extensions
-
if(typeof extension.route === 'undefined') {
extension.route = extension.type;
}
if(extension.route) {
extension.uniq = Math.random().toString(16).slice(2);
let route = extension.route;
if (routes.has(extension.route)) {
route += "-" + extension.uniq;
}
routes.add(route);
extension.route = route;
}
-
const defaultComponent = components.filter(e=>e.defaultRoute != undefined);
let defaultRoute = "dashboard";
@ -60,5 +76,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
@ -99,7 +99,7 @@ html(lang="en")
include views/page-messages.pug
if component.type == "circles"
.with-sidebar.whitespace-normal
.with-sidebar.whitespace-normal.jsMobileContentSidebarControl
hubl-reactivity(bind-user nested-field='inbox' target-src="store://user.circles")
hubl-reactivity(bind-user nested-field="circles" target-src="store://user")
hubl-reactivity(data-src=`${component.endpoints.get}joinable/` target-src=`${component.endpoints.get}`)
@ -111,6 +111,10 @@ html(lang="en")
hubl-reactivity(bind-user nested-field="circles" target-src=`${component.endpoints.get}joinable/`)
include views/page-circle.pug
if component.type == "communities"
.scrollbar-content.whitespace-normal
include views/page-communities.pug
if component.type == "dashboard"
.scrollbar-content
include views/page-dashboard.pug
@ -133,11 +137,11 @@ html(lang="en")
include views/page-job-board.pug
if component.type == "polls"
.with-sidebar
.scrollbar-content
include views/page-polls.pug
if component.type == "projects"
.with-sidebar.whitespace-normal
.with-sidebar.whitespace-normal.jsMobileContentSidebarControl
hubl-reactivity(bind-user nested-field='inbox' target-src="store://user.projects")
hubl-reactivity(bind-user nested-field="projects" target-src="store://user")
hubl-reactivity(data-src=`${component.endpoints.post}joinable/` target-src=`${component.endpoints.get}`)
@ -178,7 +182,7 @@ html(lang="en")
if component.type == "lang"
hubl-lang(
hidden
hidden
lang=component.parameters.name
file=component.parameters.file
)
@ -217,12 +221,12 @@ html(lang="en")
div
div
div
div#something-goes-wrong(hidden)
div#something-goes-wrong(hidden)
br
span(data-trans="errors.somethingGoesWrong")
span &nbsp;
a(data-trans='errors.reload' href='/')
if client.i18n
hubl-fallback-lang(
hidden

View File

@ -24,6 +24,7 @@
"resources": "Resources",
"jobBoard": "Job offers",
"profileDirectory": "Profiles directory",
"communities": "Communities",
"projects": "Projects",
"closeMenu": "Close menu",
"projectsBrowse": "Browse projects",
@ -32,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",
@ -131,13 +126,11 @@
"subTitle": "Members :"
},
"extensions": {
"associated": "Associated circle",
"republiqueESS": {
"associatedThematic": "Associated thematic"
}
"associated": "Associated circle"
}
},
"communities": {
"back": "Back",
"title": "Administration",
"menuMobile": "MENU",
"linkInvite": "Invite a new user",
@ -156,6 +149,42 @@
"email": "Email*",
"password": "Password*",
"formCreateAccount": "Create an account"
},
"list": {
"title": "Communities",
"searchBy": "Find by name",
"searchButton": "Search",
"members": "members"
},
"profile": {
"back": "Back",
"members": "members",
"edit": "Edit the page"
},
"edit": {
"labelShortDescription": "Community headline",
"labelDescription": "community description",
"labelPhone": "Phone",
"labelEmail": "Email",
"labelWebsite": "Website",
"labelTwitter": "Twitter",
"labelFacebook": "Facebook",
"labelLinkedin": "Linkedin",
"labelInstagram": "Instagram",
"labelPicture1": "Picture 1",
"labelPicture2": "Picture 2",
"labelPicture3": "Picture 3",
"labelAddressLine1": "New address line 1",
"labelAddressLine2": "New address line 2",
"labelLogo": "Community Logo",
"subTitle": "Pictures",
"subTitle1": "Address",
"buttonSubmit": "Save",
"noPermission": "You don't have access to this page",
"tableHeader1": "Address line 1",
"tableHeader2": "Address line 2",
"buttonDelete": "Delete",
"buttonAdd": "Add"
}
},
"project": {
@ -248,10 +277,7 @@
"template-captain": {
"isLead": "Captain"
},
"hublStatus": {
"private": "Private",
"public": "Public"
},
"hublStatus": "Public = Public, Private = Private",
"success": "Success!",
"errors": {
"somethingGoesWrong": "Something goes wrong, try to",
@ -312,5 +338,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

@ -24,6 +24,7 @@
"resources": "Recursos",
"jobBoard": "Ofertas de trabajo",
"profileDirectory": "Directorio de miembrxs",
"communities": "Las comunidades",
"projects": "Proyectos",
"closeMenu": "Cerrar menú",
"projectsBrowse": "Examinar los proyectos",
@ -32,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",
@ -131,13 +126,11 @@
"subTitle": "Miembrxs: "
},
"extensions": {
"associated": "Círculo asociado",
"republiqueESS": {
"associatedThematic": "Temática asociada"
}
"associated": "Círculo asociado"
}
},
"communities": {
"back": "Volver",
"title": "Administración",
"menuMobile": "MENÚ",
"linkInvite": "Invita a un/a nuevx usuarix",
@ -156,6 +149,42 @@
"email": "Correo electrónico*",
"password": "Contraseña*",
"formCreateAccount": "Crear una cuenta"
},
"list": {
"title": "Comunidades",
"searchBy": "Buscar por nombre",
"searchButton": "Buscar",
"members": "miembros"
},
"profile": {
"back": "Volver",
"members": "miembros",
"edit": "Editar la página"
},
"edit": {
"labelShortDescription": "Subtítulo del comunidad",
"labelDescription": "Descripción de la comunidad",
"labelPhone": "Teléfono",
"labelEmail": "Email",
"labelWebsite": "Página web",
"labelTwitter": "Twitter",
"labelFacebook": "Facebook",
"labelLinkedin": "Linkedin",
"labelInstagram": "Instagram",
"labelPicture1": "Foto 1",
"labelPicture2": "Foto 2",
"labelPicture3": "Foto 3",
"labelAddressLine1": "Nueva línea de dirección 1",
"labelAddressLine2": "Nueva línea de dirección 2",
"labelLogo": "Logotipo comunitario",
"subTitle": "Foto",
"subTitle1": "Dirección",
"buttonSubmit": "Guardar",
"noPermission": "No tiene permiso",
"tableHeader1": "Dirección línea 1",
"tableHeader2": "Dirección línea 2",
"buttonDelete": "Eliminar",
"buttonAdd": "Añadir"
}
},
"project": {
@ -248,10 +277,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",
@ -312,5 +338,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",
@ -24,6 +22,7 @@
"resources": "Ressources",
"jobBoard": "Offres de mission",
"profileDirectory": "Annuaire des membres",
"communities": "Les communautés",
"projects": "Projets",
"closeMenu": "Fermer le menu",
"projectsBrowse": "Parcourir les projets",
@ -32,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",
@ -131,13 +124,11 @@
"subTitle": "Membres :"
},
"extensions": {
"associated": "Cercle associé",
"republiqueESS": {
"associatedThematic": "Thématique associée"
}
"associated": "Cercle associé"
}
},
"communities": {
"back": "Retour",
"title": "Administration",
"menuMobile": "MENU",
"linkInvite": "Inviter un nouvel utilisateur",
@ -156,6 +147,42 @@
"email": "E-mail*",
"password": "Mot de passe*",
"formCreateAccount": "Créer un compte"
},
"list": {
"title": "Les communautés",
"searchBy": "Trouver par nom",
"searchButton": "Rechercher",
"members": "membres"
},
"profile": {
"back": "Retour",
"members": "membres",
"edit": "Editer la page"
},
"edit": {
"labelShortDescription": "Sous-titre de la communauté",
"labelDescription": "Description de la communauté",
"labelPhone": "Téléphone",
"labelEmail": "Email",
"labelWebsite": "Site web",
"labelTwitter": "Twitter",
"labelFacebook": "Facebook",
"labelLinkedin": "Linkedin",
"labelInstagram": "Instagram",
"labelPicture1": "Photo 1",
"labelPicture2": "Photo 2",
"labelPicture3": "Photo 3",
"labelAddressLine1": "Nouvelle adresse ligne 1",
"labelAddressLine2": "Nouvelle adresse ligne 2",
"labelLogo": "Logo de la communauté",
"subTitle": "Photos",
"subTitle1": "Adresse",
"buttonSubmit": "Enregistrer",
"noPermission": "Vous n'avez pas la permission",
"tableHeader1": "Adresse ligne 1",
"tableHeader2": "Adresse ligne 2",
"buttonDelete": "Effacer",
"buttonAdd": "Ajouter"
}
},
"project": {
@ -248,10 +275,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",
@ -312,5 +336,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

@ -0,0 +1,33 @@
/*
Geocoord helper using Nominatim
Usage:
const madrid = await hubl.geocoord('Madrid');
madrid == ["-3.7035825", "40.4167047"]
*/
window.hubl.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.hubl.geocalc = (element) => {
const editionForm = element.parentElement.parentElement.parentElement.parentElement;
window.hubl.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;
}

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) => {
if (result.ok) {
result.json().then(e => {
window.hubl.intl.addLocale(name, e);
});
}
window.hubl.intl.resumeDetection();
});
if (customLangs) {
for (let lang of customLangs) {
let name = lang.getAttribute('lang'),
file = lang.getAttribute('file');
let result = await fetch(file);
if (result.ok) {
let json = await result.json();
if(this.overwrites[name.toString()] != undefined) {
this.mergeDeep(this.overwrites[name.toString()], json);
} else {
this.overwrites[name.toString()] = json;
}
}
}
}
@ -35,10 +35,10 @@ class JsI18n {
resumeDetection() {
const langComponent = document.querySelector('hubl-fallback-lang');
if(langComponent) {
if(langComponent.hasAttribute('lang')) {
if (langComponent) {
if (langComponent.hasAttribute('lang')) {
this.defaultLocale = langComponent.getAttribute('lang');
if(langComponent.hasAttribute('force')) {
if (langComponent.hasAttribute('force')) {
localStorage.setItem('language', this.defaultLocale);
}
}
@ -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,21 +169,20 @@ 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 => {
this.addLocale(locale, e);
});
}
});
} else {
return (new Promise()).resolve();
}
return fetch(`/locales/${locale}.json`).then((result) => {
if (result.ok) {
result.json().then(e => {
this.addLocale(locale, e);
});
}
});
}
/*
@ -157,7 +191,7 @@ class JsI18n {
setLocale(locale) {
try {
this.fetchLocale(locale).then(() => {
if(this.locale) {
if (this.locale) {
localStorage.setItem('language', this.locale);
}
this.processPage();
@ -179,11 +213,11 @@ class JsI18n {
t(key) {
var translations = this.locales[this.locale];
if (translations == undefined) {
if(this.locales.length > 1) {
if (this.locales.length > 1) {
translations = this.locales[this.defaultLocale];
}
}
if(translations != undefined) {
if (translations != undefined) {
let translation = key.toString().split('.').reduce((o, i) => (o ? o[i] : undefined), translations);
if (typeof translation == "string") {
return translation;

View File

@ -0,0 +1,9 @@
document.addEventListener("keydown", function (e) {
/*
CTRL + K : Focus on the user search
*/
if(e.ctrlKey && e.key == "k") {
document.querySelector('#general-search input[type="text"]').focus();
e.preventDefault();
}
});

View File

@ -19,13 +19,27 @@ function closeRightMenu() {
el.querySelector('.text-right').setAttribute('hidden', '');
el.querySelector('.text-left').removeAttribute('hidden');
});
Array.from(rightMenu).forEach(el => el.removeAttribute("open"));
Array.from(rightMenu).forEach(el => {
el.removeAttribute("open");
el.classList.add('sm-hidden');
Array.from(el.parentElement.querySelectorAll('.jsMobileRightMenuButton')).forEach(ac => {
ac.classList.remove('icon-close');
ac.classList.add('icon-options-vertical');
});
});
}
}
function openRightMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
Array.from(rightMenu).forEach(el => el.setAttribute("open", ""));
Array.from(rightMenu).forEach(el => {
el.setAttribute("open", "");
el.classList.remove('sm-hidden');
Array.from(el.parentElement.querySelectorAll('.jsMobileRightMenuButton')).forEach(ac => {
ac.classList.remove('icon-options-vertical');
ac.classList.add('icon-close');
});
});
Array.from(document.querySelectorAll(".jsOffsiteToggle")).forEach(el => {
el.querySelector('.text-left').setAttribute('hidden', '');
el.querySelector('.text-right').removeAttribute('hidden');
@ -35,6 +49,32 @@ function openRightMenu() {
);
}
function closeRightMobileMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
if (Array.from(rightMenu).filter(el => el.hasAttribute("mobile-open")).length > 0) {
Array.from(rightMenu).forEach(el => {
el.removeAttribute("mobile-open");
el.classList.add('sm-hidden');
Array.from(el.parentElement.querySelectorAll('.jsMobileRightMenuButton')).forEach(ac => {
ac.classList.remove('icon-close');
ac.classList.add('icon-options-vertical');
});
});
}
}
function openRightMobileMenu() {
let rightMenu = document.querySelectorAll(".jsRightMenu");
Array.from(rightMenu).forEach(el => {
el.setAttribute("mobile-open", "");
el.classList.remove('sm-hidden');
Array.from(el.parentElement.querySelectorAll('.jsMobileRightMenuButton')).forEach(ac => {
ac.classList.remove('icon-options-vertical');
ac.classList.add('icon-close');
});
});
}
document.addEventListener("DOMContentLoaded", function () {
const componentSet = new Set(window.hubl.components.map(c => c.type));
@ -112,9 +152,11 @@ document.addEventListener("DOMContentLoaded", function () {
closeLeftMenu();
}
if (
!event.target.closest(".jsOffsiteToggle")
!event.target.closest(".jsOffsiteToggle") &&
!event.target.classList.contains('jsMobileRightMenuButton')
) {
closeRightMenu();
closeRightMobileMenu();
}
});
@ -125,6 +167,7 @@ document.addEventListener("DOMContentLoaded", function () {
closeUserControls();
closeLeftMenu();
closeRightMenu();
closeRightMobileMenu();
}
};
@ -152,10 +195,15 @@ document.addEventListener("DOMContentLoaded", function () {
});
});
Array.from(document.querySelectorAll(".jsMobileSidebarOpenButton")).forEach(
Array.from(document.querySelectorAll(".jsMobileRightMenuButton")).forEach(
el => {
el.addEventListener("click", () => {
openRightMenu();
if (el.closest('.jsMobileContentSidebarControl').querySelector('nav.jsRightMenu').hasAttribute("mobile-open")) {
closeRightMobileMenu();
} else {
openRightMobileMenu();
}
});
}
);

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

@ -1,12 +1,13 @@
#admin-circles,
#admin-circles-leave {
#admin-circles-leave,
.communities-directory {
/* Fix on Join button in admin (circles + projects) */
/* Styles on buttons and .children-link don't work because this input is inside too many elements. */
/* And no I can't add that stupid icon because it'a an input. */
/* But now, with 0.16, it's a button and you can :D */
.join-button {
input,
button {
padding: 9px 20px;
@ -18,7 +19,7 @@
background-color: var(--color-secondary);
color: white;
border: 1px solid var(--color-secondary);
&:before {
font-size: 15px;
margin-right: 6px;
@ -37,17 +38,17 @@
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
&:hover {
background: white;
color: var(--color-secondary);
}
}
@media (max-width: 768px) {
&.sm-full {
input,
button {
width: 100%;
@ -57,10 +58,15 @@
}
.form.search-button :not(.add-member)+button[type=submit] {
background-color: #E9F2FF;
border: none;
background-color: transparent;
border: 1px solid var(--color-secondary);
color: var(--color-secondary);
&:hover {
background-color: var(--color-secondary);
color: #fff;
}
&:before {
font-size: 15px;
margin-right: 6px;
@ -75,11 +81,11 @@
text-align: center;
font-variant: normal;
text-transform: none;
line-height: 1em;
line-height: 13px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
}
}
.masonry>div:nth-child(1) {
/* change from directory (nth-child(2))*/
@ -95,6 +101,7 @@
.segment.hover:hover {
box-shadow: 0 0 16px 0 rgba(46, 63, 88, 0.34);
bottom: 2px;
cursor: pointer;
}
hubl-admin-circle-name:hover {
@ -105,6 +112,40 @@
height: 76px;
width: 100%;
display: block;
div {
display: block;
width: 100%;
height: 100%;
background-position: center;
background-repeat: no-repeat;
background-size: contain;
}
}
.community-profile solid-multiple {
[name="address_line1"]::before {
font-family: 'material-design-icons';
content: "\F34E";
position: relative;
top: 2px;
color: var(--color-third);
font-size: 20px;
margin-right: 10px;
}
[name="address_line2"] {
display: block;
margin-left: 30px;
}
}
hubl-communities-profile-logo {
height: 155px;
width: 100%;
display: block;
div {
display: block;
width: 100%;
@ -121,6 +162,107 @@
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: contain;
}
}
}
.communities-map {
.leaflet-popup-content-wrapper {
border-radius: 5px;
.leaflet-popup-content {
width: 340px !important;
margin: 0;
.description {
height: 32px;
}
.title:hover {
cursor: pointer;
text-decoration: underline;
}
}
}
.leaflet-popup-close-button {
display: none;
}
}
.edit-img {
input[type="file"] {
display: block;
margin-top: 10px;
}
img {
display: block;
margin-top: 15px;
}
&.edit-logo {
img{
width: 280px;
}
}
&.edit-picture {
&>div {
position: relative;
button {
margin-top: 10px;
color: #636363;
font-weight: bold;
line-height: 19px;
font-size: 22px;
}
}
img {
width: 100%;
}
}
}
.edit-address {
form {
display: table-row;
}
.segment.table-cell {
display: table-cell;
border-bottom: 1px solid #C9C8C8;
border-right: 1px solid #C9C8C8;
height: 60px;
padding: 10px;
vertical-align: middle;
width: 250px;
}
input[type='submit'] {
display: none;
}
}
@media (max-width: 768px) {
.tabs {
@ -143,5 +285,66 @@
}
}
}
.community-profile-logo {
border-bottom: 1px solid #D6CECE;
}
hubl-communities-profile-logo {
height: 100px;
}
.communities-profile-picture {
>div:not(:empty) {
height: 180px;
}
}
.mobile-map-search-field {
position: fixed;
top: 70px;
z-index: 1000;
width: 97%;
button[type='submit'] {
background: var(--color-secondary) !important;
color: white !important;
&:hover {
background: white !important;
color: var(--color-secondary) !important;
}
}
}
.communities-map {
height: calc(100vh - 50px) !important;
.leaflet-top.leaflet-left {
display: none;
}
.leaflet-popup-close-button {
display: block;
font-size: 20px;
margin-top: 5px;
margin-right: 5px;
}
}
.edit-img {
&.edit-logo {
img {
width: 100%;
}
}
}
}
.flex {
display: flex;
}
}

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;
@ -65,11 +69,28 @@ main {
/* Styles use with JS to open/close the sidebar */
&.jsRightMenu {
display: block;
@media (min-width: 768,01px) {
display: block;
}
@media (max-width: 768px) {
position: fixed;
top: 99px;
right: 0;
height: auto;
z-index: 2999;
box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.14);
}
solid-link[active] {
color: white;
background: var(--color-heading);
>li {
border-bottom: 1px solid var(--color-heading);
}
}
solid-link:not([active]):hover {
background: #e4e4e4;
}
@ -79,30 +100,18 @@ main {
@media (min-width: 768.01px) {
transform: translate(152px);
}
/* Quick fix. When you got time, use animation on the span instead */
@media (max-width: 768px) {
ul>li:first-child>span,
ul>li:first-child>a {
visibility: hidden;
}
}
}
&.jsRightMenu[open] {
display: block;
bottom: 0;
right: 0;
@media(max-width: 768px) {
box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.12);
min-width: 60%;
position: fixed;
top: 50px;
z-index: 3000;
}
}
}
.jsMobileRightMenuButton {
float: right;
}
}
/* Add scrollbar to the left menu and to the content */
@ -118,7 +127,7 @@ main {
height: 100vh;
}
/* Custom scrollbar of the left-menu*/
/* Custom scrollbar of the right-menu */
/* Works on Firefox*/
.scrollbar-nav {
scrollbar-width: thin;
@ -142,9 +151,6 @@ main {
}
}
/* Custom scrollbar of the content */
/* Works on Firefox */
.scrollbar-content {
@ -168,6 +174,7 @@ main {
border: 3px solid white; /* creates padding around scroll thumb */
}
}
/* End scrollbar*/
solid-display-value-markdown {

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,4 +1,4 @@
.with-sidebar.whitespace-normal.bg-color-white.only-on-admin(hidden)
.with-sidebar.jsMobileContentSidebarControl.whitespace-normal.bg-color-white.only-on-admin(hidden)
.scrollbar-content.views-container.sidebar-is-closed
for component of components
if component.route
@ -57,10 +57,10 @@
)
include partials/admin/page-admin-chat-create.pug
nav.jsRightMenu.text-disable-selection.sidebar.whitespace-normal(role='navigation')
nav.jsRightMenu.segment.sm-hidden.text-disable-selection.sidebar.whitespace-normal(role='navigation')
.segment.whitespace-normal.text-color-heading.text-bold
ul
li.segment.full.padding-small.text-normal.jsOffsiteToggle
li.segment.full.sm-hidden.padding-small.text-normal.jsOffsiteToggle
span.icon.icon-arrow-left.icon-xsmall.margin-left-xxsmall.text-left
span.segment.full.text-right(hidden)
span.icon.icon-arrow-right.icon-xsmall.margin-right-xxsmall

View File

@ -14,55 +14,37 @@
no-render
)
include partials/circle/page-circle-profile.pug
//- Note:
Instead of using flat events/resources or polls components, you
may you to expend the way circle work to handle events & cie.
Like:
{
"type": "circles",
...
"extensions": [
{
"type": "events",
"endpoints": {...},
...
}
]
}
-
let extensions = new Set();
if(component.extensions) {
extensions = new Set(component.extensions.map(c=>c.type));
}
if extensions.has('events')
div(
id=`${component.route}-events`
hidden
data-view=`${component.route}-events`
no-render
)
include partials/circle/page-circle-events.pug
if extensions.has('resources')
div(
id=`${component.route}-resources`
hidden
data-view=`${component.route}-resources`
no-render
)
include partials/circle/page-circle-resources.pug
if extensions.has('polls')
div(
id=`${component.route}-polls`
hidden
data-view=`${component.route}-polls`
no-render
)
include partials/circle/page-circle-polls.pug
if component.extensions
for extension of component.extensions
if extension.type == 'events'
div(
id=`${extension.route}-events`
hidden
data-view=`${extension.route}-events`
no-render
)
include partials/circle/page-circle-events.pug
if extension.type == 'resources'
div(
id=`${extension.route}-resources`
hidden
data-view=`${extension.route}-resources`
no-render
)
include partials/circle/page-circle-resources.pug
if extension.type == 'polls'
div(
id=`${extension.route}-polls`
hidden
data-view=`${extension.route}-polls`
no-render
)
include partials/circle/page-circle-polls.pug
nav.jsRightMenu.text-disable-selection.sidebar.whitespace-normal(role='navigation')
nav.jsRightMenu.segment.sm-hidden.text-disable-selection.sidebar.whitespace-normal(role='navigation')
solid-router.segment.whitespace-normal.text-color-heading.text-bold(default-route=`${component.route}-chat`)
ul
li.segment.full.padding-small.text-normal.jsOffsiteToggle
li.segment.full.sm-hidden.padding-small.text-normal.jsOffsiteToggle
span.icon.icon-arrow-left.icon-xsmall.margin-left-xxsmall.text-left
span.segment.full.text-right(hidden)
span.icon.icon-arrow-right.icon-xsmall.margin-right-xxsmall
@ -75,18 +57,20 @@ nav.jsRightMenu.text-disable-selection.sidebar.whitespace-normal(role='navigatio
li.segment.full.padding-medium
span.icon.ci-information.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.information')
if extensions.has('resources')
solid-route.segment.full(name=`${component.route}-resources` use-id)
li.segment.full.padding-medium
span.icon.ci-networking.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.resources')
if extensions.has('events')
solid-route.segment.full(name=`${component.route}-events` use-id)
li.segment.full.padding-medium
span.icon.ci-networking.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.events')
if extensions.has('polls')
solid-route.segment.full(name=`${component.route}-polls` use-id)
li.segment.full.padding-medium
span.icon.ci-networking.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.polls')
if component.extensions
for extension of component.extensions
if extension.type == 'resources'
solid-route.segment.full(name=`${extension.route}-resources` use-id)
li.segment.full.padding-medium
span.icon.ci-file.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.resources')
if extension.type == 'events'
solid-route.segment.full(name=`${extension.route}-events` use-id)
li.segment.full.padding-medium
span.icon.ci-appointment.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.events')
if extension.type == 'polls'
solid-route.segment.full(name=`${extension.route}-polls` use-id)
li.segment.full.padding-medium
span.icon.ci-list.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.polls')

View File

@ -0,0 +1,34 @@
div.communities-directory
solid-router(default-route=`${component.route}-directory` hidden)
solid-route(name=`${component.route}-directory`)
solid-route(name=`${component.route}-map`)
solid-route(name=`${component.route}-profile` use-id)
solid-route(name=`${component.route}-edit` use-id)
div(
id=`${component.route}-directory`
hidden
data-view=`${component.route}-directory`
no-render
)
include partials/communities/page-community-directory.pug
div(
id=`${component.route}-map`
hidden
data-view=`${component.route}-map`
no-render
)
include partials/communities/page-community-map.pug
div(
id=`${component.route}-profile`
hidden
data-view=`${component.route}-profile`
no-render
)
include partials/communities/page-community-profile.pug
div(
id=`${component.route}-edit`
hidden
data-view=`${component.route}-edit`
no-render
)
include partials/communities/page-community-edit.pug

View File

@ -1,8 +1,8 @@
.views-container
solid-poll(
data-src=`${component.endpoints.get}`
range-base-polls=`${component.endpoints.pollRangeBase}`
upload-dir=`${component.endpoints.uploads}`
id-prefix='default'
uniq=component.uniq
)
solid-poll(
data-src=component.endpoints.get
data-dest=component.endpoints.post
range-tags=component.endpoints.pollRangeTags
range-circles=component.endpoints.pollRangeCircles
upload-dir=component.endpoints.uploads
uniq=component.uniq
)

View File

@ -21,11 +21,21 @@
no-render
)
include partials/project/page-project-picture.pug
if component.extensions
for extension of component.extensions
if extension.type == 'invoices'
div(
id=`${extension.route}-invoices`
hidden
data-view=`${extension.route}-invoices`
no-render
)
include partials/project/page-project-invoices.pug
nav.jsRightMenu.text-disable-selection.sidebar.whitespace-normal(role='navigation')
nav.jsRightMenu.segment.sm-hidden.text-disable-selection.sidebar.whitespace-normal(role='navigation')
solid-router.segment.whitespace-normal.text-color-heading.text-bold(default-route=`${component.route}-chat`)
ul
li.segment.full.padding-small.text-normal.jsOffsiteToggle
li.segment.full.sm-hidden.padding-small.text-normal.jsOffsiteToggle
span.icon.icon-arrow-left.icon-xsmall.margin-left-xxsmall.text-left
span.segment.full.text-right(hidden)
span.icon.icon-arrow-right.icon-xsmall.margin-right-xxsmall
@ -39,3 +49,10 @@ nav.jsRightMenu.text-disable-selection.sidebar.whitespace-normal(role='navigatio
span.icon.ci-information.icon-xlarge.margin-right-medium
a(data-trans='project.menuRight.information')
solid-route(name=`${component.route}-picture` use-id)
if component.extensions
for extension of component.extensions
if extension.type == 'invoices'
solid-route.segment.full(name=`${extension.route}-invoices` use-id)
li.segment.full.padding-medium
span.icon.ci-list.icon-xlarge.margin-right-medium
a(data-trans='circle.menuRight.invoices')

View File

@ -1,8 +1,10 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.padding-large.border-bottom.border-color-grey
div.segment.half.sm-full
div.segment.full.sm-three-quarter
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='communities.title')
div.segment.half.sm-hidden.text-right
solid-link(class="backlink", next=`admin-${getRoute('chat', true)}` data-trans='circle.create.backlink')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespace-normal
div#loader-users-title.loader.loader
@ -11,12 +13,6 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
div
div
div#loader-users-create.loader.loader-top
div
div
div
div
div.segment.margin-bottom-medium
div.segment
solid-display.text-color-heading.text-semibold.text-xlarge.text-letter-spacing-large(
@ -27,6 +23,12 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
loader-id='loader-users-title'
)
div#loader-users-create.loader.loader-top
div
div
div
div
solid-form.form#selected-community(
bind-resources
nested-field='members'

View File

@ -1,5 +1,8 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='communities.title')
div.segment.full.sm-three-quarter
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='communities.title')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespace-normal

View File

@ -1,8 +1,10 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey
div.segment.half.sm-full
div.segment.full.sm-three-quarter
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='circle.create.title')
div.segment.half.sm-hidden.text-right
solid-link(class="backlink", next=`admin-${getRoute('circles', true)}` data-trans='circle.create.backlink')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespace-normal
div.loader.loader-top(id=`loader-admin-${getComponent('circles').uniq}`)
@ -14,32 +16,34 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
solid-form.form(
data-src=`${getComponent('circles').endpoints.post}`
fields='status, community, name, subtitle, description, help'
fields='status, community.community, name, subtitle, description, help'
required-status
required-community
required-community.community
required-name
required-subtitle
loader-id=`loader-admin-${getComponent('circles').uniq}`
class-status='segment margin-bottom-medium half sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading whitespace-normal'
class-community='segment margin-bottom-medium half sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading whitespace-normal'
class-community.community='segment margin-bottom-medium half sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading whitespace-normal'
class-name='segment margin-bottom-medium half sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading'
class-subtitle='segment margin-bottom-medium half sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading'
class-description='segment margin-bottom-xxsmall full text-small text-semibold text-uppercase text-color-heading'
class-help='segment full text-small margin-bottom-medium padding-left-small'
label-status=''
label-community=''
label-community.community=''
label-name=''
label-subtitle=''
label-description=''
label-help=''
range-community='store://user.communities'
option-label-community="community.name"
range-community.community='store://user.communities'
option-label-community.community="community.name"
option-value-community.community="community"
widget-status='hubl-status'
widget-community='solid-form-dropdown-autocompletion-label'
widget-status='solid-form-dropdown-autocompletion-label'
enum-status=""
widget-community.community='solid-form-dropdown-autocompletion-label'
widget-linebreak='solid-form-hidden'
widget-description='solid-form-richtext-label'
@ -50,5 +54,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.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

@ -1,5 +1,8 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='circle.list.title')
div.segment.full.sm-three-quarter
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='circle.list.title')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.padding-top-medium.padding-bottom-xsmall.sm-padding-xsmall.sm-padding-top-xxsmall.whitespace-normal

View File

@ -1,8 +1,10 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey
div.segment.half.sm-full
div.segment.full.sm-three-quarter
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='project.create.title')
div.segment.half.sm-hidden.text-right
solid-link(class="backlink", next=`admin-${getRoute('projects', true)}` data-trans='project.create.backlink')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespace-normal
div.loader.loader-top(id=`loader-admin-${getComponent('projects').uniq}`)

View File

@ -1,5 +1,8 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='project.list.title')
div.segment.full.sm-three-quarter
h2.margin-none.text-color-heading.text-uppercase.text-xlarge.text-letter-spacing-large(data-trans='project.list.title')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespace-normal

View File

@ -1,13 +1,16 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
solid-display.text-xxlarge.text-letter-spacing-large(
bind-resources
fields='name, dash, subtitle'
div.segment.full.sm-three-quarter.whitespace-normal
solid-display.text-xlarge.text-letter-spacing-large(
bind-resources
fields='name, dash, subtitle'
value-dash=' - '
value-dash=' - '
class-name='text-color-heading text-bold'
class-dash='text-color-heading text-bold'
)
class-name='text-color-heading text-bold'
class-dash='text-color-heading text-bold'
)
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
.chat-view.segment.full.whitespace-normal
solid-xmpp-chat(

View File

@ -1,7 +1,7 @@
solid-ac-checker(permission='acl:Read', bind-resources)
div.segment.full.padding-large.border-bottom.border-color-grey
div.segment.half.sm-full
solid-display.text-xxlarge.text-letter-spacing-large(
div.segment.half.sm-three-quarter.whitespace-normal
solid-display.text-xlarge.text-letter-spacing-large(
bind-resources
fields='name, dash, subtitle'
@ -12,6 +12,8 @@ solid-ac-checker(permission='acl:Read', bind-resources)
)
div.segment.half.sm-hidden.text-right
solid-link(class="backlink", bind-resources, next=`${component.route}-profile` data-trans='circle.edit.backlink')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.whitespace-normal
@ -25,12 +27,12 @@ div.segment.full.padding-large.whitespace-normal
solid-form.form(
bind-resources
fields='name, subtitle, description, status, community, owner'
fields='name, subtitle, description, status, community.community, owner'
required-status
required-name
required-owner
required-subtitle
required-community
required-community.community
range-owner=`${component.endpoints.owners}`
label-name=''
@ -38,25 +40,27 @@ div.segment.full.padding-large.whitespace-normal
label-description=''
label-subtitle=''
label-status=''
label-community=''
label-community.community=''
label-help=''
class-name='segment margin-bottom-medium half sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading'
class-subtitle='segment margin-bottom-medium half sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading'
class-description='segment margin-bottom-medium full text-small text-semibold text-uppercase text-color-heading'
class-status='segment margin-bottom-medium half sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading whitespace-normal'
class-community='segment margin-bottom-medium half sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading whitespace-normal'
class-community.community='segment margin-bottom-medium half sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading 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'
widget-community.community='solid-form-dropdown-autocompletion-label'
widget-owner='solid-form-dropdown-autocompletion-label'
range-community='store://user.communities'
option-label-community="community.name"
range-community.community='store://user.communities'
option-label-community.community="community.name"
option-value-community.community="community"
partial=''
@ -64,7 +68,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.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

@ -1,10 +1,9 @@
solid-event(
class='w700'
bind-resources
nested-field="events"
range-event-type=`${component.extensions.find(c => c.type=='events').endpoints.typeevents}`
range-event-circle=`${component.endpoints.get}/`
upload-dir=`${component.extensions.find(c => c.type=='events').endpoints.uploads}`
id-prefix=`${component.route}`
uniq=component.uniq
range-event-type=`${extension.endpoints.typeevents}`
range-event-circle=`${getComponent('circles').endpoints.get}/`
upload-dir=`${extension.endpoints.uploads}`
id-prefix='default'
uniq=extension.uniq
)

View File

@ -1,9 +1,9 @@
solid-poll(
class='w700'
id-prefix='circles'
bind-resources
nested-field="polls"
range-base-polls=`${component.get('polls').endpoints.pollRangeBase}`
upload-dir=`${component.get('polls').endpoints.uploads}`
uniq=component.uniq
)
data-dest=extension.endpoints.post
range-tags=extension.endpoints.pollRangeTags
range-circles=extension.endpoints.pollRangeCircles
upload-dir=extension.endpoints.uploads
uniq=extension.uniq
)

View File

@ -9,15 +9,18 @@ div(
)
solid-ac-checker.segment.block(permission='acl:Read', bind-resources)
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
solid-display.text-xxlarge.text-letter-spacing-large(
bind-resources
fields='name, dash, subtitle'
div.segment.full.sm-three-quarter.whitespace-normal
solid-display.text-xlarge.text-letter-spacing-large(
bind-resources
fields='name, dash, subtitle'
value-dash=' - '
value-dash=' - '
class-name='text-color-heading text-bold'
class-dash='text-color-heading text-bold'
)
class-name='text-color-heading text-bold'
class-dash='text-color-heading text-bold'
)
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-xlarge
div.loader(id=`loader-${component.route}-profile-1`)

View File

@ -1,10 +1,15 @@
solid-resource(
class='w700'
bind-resources
nested-field="resources"
range-resource-type=`${component.extensions.find(c => c.type=='resources').endpoints.resourcestypes}`
range-resource-keyword=`${component.extensions.find(c => c.type=='resources').endpoints.resourceskeywords}`
range-resource-circle=`${component.endpoints.get}/`
upload-dir=`${component.extensions.find(c => c.type=='resources').endpoints.uploads}`
id-prefix='circles'
post-data-src=`${extension.endpoints.post}`
range-resource-type=`${extension.endpoints.types}`
post-data-type-src=`${extension.endpoints.postTypes}`
range-resource-keyword=`${extension.endpoints.keywords}`
post-data-keyword-src=`${extension.endpoints.postKeywords}`
range-resource-circle=`${getComponent('circles').endpoints.get}/`
associated-circle-label=""
data-trans=`associated-circle-label=${extension.parameters && extension.parameters.associatedName ? extension.parameters.associatedName : 'circle.extensions.associated'}`
upload-dir=`${extension.endpoints.uploads}`
id-prefix='default'
uniq=extension.uniq
)

View File

@ -0,0 +1,46 @@
.padding-small.sm-padding-none.sm-padding-top-medium.sm-padding-bottom-medium
h2.margin-top-xxsmall.margin-left-xsmall.margin-bottom-medium.sm-margin-none.sm-margin-right-xsmall.sm-margin-bottom-small.sm-margin-left-xsmall.text-xlarge.text-bold.text-color-heading.text-uppercase(data-trans='communities.list.title')
div.padding-top-xxsmall.margin-left-xsmall.margin-right-xsmall.sm-padding-none.sm-margin-none.sm-margin-right-xsmall.sm-margin-left-xsmall
div.segment.quarter.sm-full
solid-form-search.form.search-form.search-button(
id=`communities-filter`
fields='name'
placeholder-name=''
widget-name='solid-form-placeholder-text'
class-name="segment margin-bottom-medium sm-margin-bottom-none three-quarter sm-full padding-right-small sm-padding-none text-small input-bg-white children-shadow"
submit-button=""
submit-widget="button"
data-trans='placeholder-name=communities.list.searchBy;submit-button=communities.list.searchButton'
)
div.segment.three-quarter.sm-full.text-right
solid-link.segment.children-link-rounded.children-icon-map.children-link-reversed.color-secondary.bordered(next=`${component.route}-map`)
span
div.segment.full.padding-top-xsmall.sm-padding-xsmall.whitespace-normal
div.loader(id=`loader-${component.route}-directory`)
div
div
div
div
solid-display(
class='segment full children children-quarter sm-children-full children-margin-bottom-medium sm-children-margin-bottom-xsmall children-padding-right-xsmall children-padding-left-xsmall sm-children-padding-none sm-whitespace-normal masonry pagination text-disable-selection'
data-src=`${component.endpoints.get}`
loader-id=`loader-${component.route}-directory`
fields='segment1(segment2(logo), segment3(name, profile.shortDescription, counter))'
filtered-by=`communities-filter`
order-by='name'
paginate-by='20'
class-segment1='segment hover bg-color-white shadow border-rounded-xxsmall full text-top whitespace-normal'
class-segment2='segment block padding-xlarge text-center'
class-segment3='segment full padding-xlarge sm-padding-medium border-top border-color-grey text-center whitespace-normal'
class-name='segment block one-line-ellipsis text-xlarge text-bold text-color-heading margin-bottom-xsmall'
class-profile.shortDescription='segment two-lines-ellipsis margin-bottom-xlarge sm-margin-bottom-medium whitespace-normal circle-subtitle-custom'
class-counter='segment block whitespace-normal'
widget-logo='hubl-admin-community-logo'
action-counter="counter"
widget-counter='hubl-communities-counter-alternate'
next=`${component.route}-profile`
)

View File

@ -0,0 +1,162 @@
div.bg-color-white
solid-ac-checker(permission="acl:Read", bind-resources)
div.segment.full.padding-large.border-bottom.border-color-grey
div.segment.half.sm-full
solid-display.text-color-heading.text-bold.text-xxlarge.text-letter-spacing-large(
bind-resources
fields="name"
)
div.segment.half.sm-hidden.text-right
solid-link(class="backlink", bind-resources, next=`${component.route}-profile` data-trans="communities.back")
div.segment.full.padding-large.whitespace-normal
solid-ac-checker(permission="acl:Write", bind-resources)
div.loader.loader-top(id=`loader-${component.route}-edit`)
div
div
div
div
solid-form.form(
bind-resources
loader-id=`loader-${component.route}-edit`
fields="profile.shortDescription, profile.description, segment(logo), profile.website, profile.email, profile.phone, profile.tweeter, profile.facebook, profile.linkedin, segment1(profile.instagram)"
label-profile.shortDescription=""
label-profile.description=""
label-logo=""
label-profile.website=""
label-profile.email=""
label-profile.phone=""
label-profile.tweeter=""
label-profile.facebook=""
label-profile.linkedin=""
label-profile.instagram=""
class-profile.shortDescription="segment margin-bottom-medium full text-small text-semibold text-uppercase text-color-heading"
class-profile.description="segment margin-bottom-medium full text-small text-semibold text-uppercase text-color-heading"
class-segment="segment full"
class-logo="edit-img edit-logo segment margin-bottom-medium full sm-padding-none text-small text-semibold text-uppercase text-color-heading"
class-profile.website="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none"
class-profile.email="segment margin-bottom-medium third sm-full padding-right-small padding-left-small sm-padding-none"
class-profile.phone="segment margin-bottom-medium third sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
class-profile.tweeter="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
class-profile.facebook="segment margin-bottom-medium third sm-full padding-right-small padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
class-profile.linkedin="segment margin-bottom-medium third sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
class-segment1="segment full"
class-profile.instagram="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
widget-profile.description="solid-form-richtext-label"
widget-profile.email="hubl-communities-edit-email"
widget-profile.website="hubl-communities-edit-website"
upload-url-logo=component.endpoints.uploads
widget-logo="solid-form-image-label"
submit-button=""
submit-widget="button"
data-trans="label-logo=communities.edit.labelLogo;label-profile.shortDescription=communities.edit.labelShortDescription;label-profile.description=communities.edit.labelDescription;label-profile.phone=communities.edit.labelPhone;label-profile.tweeter=communities.edit.labelTwitter;label-profile.facebook=communities.edit.labelFacebook;label-profile.linkedin=communities.edit.labelLinkedin;label-profile.instagram=communities.edit.labelInstagram;submit-button=communities.edit.buttonSubmit"
)
h3.segment.full.padding-bottom-small.border-bottom.border-color-grey.text-color-heading.text-bold.text-letter-spacing-large(data-trans="communities.edit.subTitle")
solid-form.form(
bind-resources
fields="profile.picture1, profile.picture2, profile.picture3"
upload-url-profile.picture1=component.endpoints.uploads
upload-url-profile.picture2=component.endpoints.uploads
upload-url-profile.picture3=component.endpoints.uploads
widget-profile.picture1="solid-form-image-label"
widget-profile.picture2="solid-form-image-label"
widget-profile.picture3="solid-form-image-label"
label-profile.picture1=""
label-profile.picture2=""
label-profile.picture3=""
class-profile.picture1="edit-img edit-picture segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading text-top"
class-profile.picture2="edit-img edit-picture segment margin-bottom-medium third sm-full padding-right-small padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading text-top"
class-profile.picture3="edit-img edit-picture segment margin-bottom-medium third sm-full padding-left-small sm-padding-none text-small text-semibold text-uppercase text-color-heading text-top"
submit-button=""
submit-widget="button"
data-trans="label-profile.picture1=communities.edit.labelPicture1;label-profile.picture2=communities.edit.labelPicture2;label-profile.picture3=communities.edit.labelPicture3;submit-button=communities.edit.buttonSubmit"
)
h3.segment.full.padding-bottom-small.border-bottom.border-color-grey.text-color-heading.text-bold.text-letter-spacing-large(data-trans="communities.edit.subTitle1")
solid-widget(name=`hubl-communities-edit-delete-button`)
template
solid-delete(
class='segment text-xsmall children-link-button children-link-text-bold children-link-text-uppercase children-link-color-secondary bordered'
data-src="${src}"
data-label=''
data-trans=''
)
.segment.table-wrapper.margin-top-medium
.table
div.table-header.bg-color-third.text-color-heading
div.segment.table-cell.third(data-trans='communities.edit.tableHeader1')
div.segment.table-cell.third(data-trans='communities.edit.tableHeader2')
div.segment.table-cell.third
solid-display(
class='table-body'
bind-resources
nested-field='addresses'
fields='segment1(address_line1), segment2(address_line2), remove'
loader-id=`loader-${component.route}-edit`
class-segment1='segment table-cell third'
class-segment2='segment table-cell third'
class-remove='segment table-cell third text-center'
class-address_line1='text-small text-semibold'
class-address_line2='text-small text-semibold'
multiple-addresses
multiple-addresses-fields="address_line1, address_line2"
action-remove='remove'
widget-remove='hubl-circle-edit-members-delete'
)
solid-form.form.table-body.edit-address(
bind-resources
nested-field="addresses"
fields="segment1(address_line1), segment2(address_line2), lat, lng, segment3(addButton)"
placeholder-address_line1=""
placeholder-address_line2=""
class-segment1='segment table-cell third'
class-segment2='segment table-cell third'
class-segment3='segment table-cell third text-center'
class-address_line1="segment full text-small"
class-address_line2="segment full text-small"
class-lat="hidden"
class-lng="hidden"
widget-community="solid-form-hidden"
widget-address_line1="solid-form-placeholder-text"
widget-address_line2="solid-form-placeholder-text"
widget-lat="solid-form-hidden"
widget-lng="solid-form-hidden"
widget-addButton=`hubl-communities-edit-add-button`
data-trans="placeholder-address_line1=communities.edit.labelAddressLine1;placeholder-address_line2=communities.edit.labelAddressLine2"
)
solid-ac-checker(no-permission="acl:Write", bind-resources)
span(data-trans="communities.edit.noPermission")

View File

@ -0,0 +1,40 @@
.padding-small.sm-padding-none
h2.segment.sm-hidden.margin-top-xxsmall.margin-left-xsmall.margin-bottom-medium.sm-margin-none.sm-margin-right-xsmall.sm-margin-bottom-large.sm-margin-left-xsmall.text-xlarge.text-bold.text-color-heading.text-uppercase(data-trans='communities.list.title')
div.mobile-map-search-field.padding-top-xxsmall.margin-left-xsmall.margin-right-xsmall.sm-padding-none.sm-margin-none.sm-margin-right-xsmall.sm-margin-left-xsmall
div.segment.quarter.sm-full
solid-form-search.form.search-form.search-button(
id=`communities-filter-map`
fields='filter'
search-filter='community.name, address_line1, address_line2'
placeholder-filter=''
widget-filter='solid-form-placeholder-text'
class-filter="segment margin-bottom-medium sm-margin-bottom-none three-quarter sm-full padding-right-small sm-padding-none text-small input-bg-white children-shadow"
submit-button=""
submit-widget="button"
data-trans='placeholder-filter=communities.list.searchBy;submit-button=communities.list.searchButton'
)
div.segment.three-quarter.sm-full.text-right
solid-link.segment.children-link-rounded.children-icon-grid.children-link-reversed.color-secondary.bordered(next=`${component.route}-directory`)
span
solid-map.communities-map.margin-right-xsmall.margin-left-xsmall.sm-margin-none.shadow(
data-src=`${component.endpoints.addresses}`
loader-id=`loader-${component.route}-map`
fields="position(segment1(community.logo), segment2(community.name, community.profile.shortDescription, community.members))"
class-segment1="segment block margin-medium"
class-segment2="segment full padding-top-xlarge padding-right-large padding-bottom-xlarge padding-left-large sm-padding-medium border-top border-color-grey text-center whitespace-normal"
class-community.name="title segment block margin-bottom-xsmall text-color-heading text-xlarge text-bold"
class-community.profile.shortDescription="segment block description text-medium margin-bottom-xsmall whitespace-normal two-lines-ellipsis"
action-community.name=`${component.route}-profile`
widget-community.name='hubl-communities-map-fix-url-name'
widget-community.logo='hubl-admin-community-logo'
widget-community.members="hubl-communities-profile-members-counter"
clustering=""
filtered-by=`communities-filter-map`
style="display:block;height:698px;"
)

View File

@ -0,0 +1,80 @@
div.community-profile.padding-medium.sm-padding-none
div.segment.full.sm-hidden.text-right
solid-link.backlink.text-xlarge.line-xlarge.margin-right-xxsmall(next=`${component.route}-directory` data-trans="communities.back")
div.segment.block.shadow.bg-color-white.margin-right-xxsmall.margin-top-large.margin-left-xxsmall.sm-margin-none
div.loader(id=`loader-${component.route}-profile`)
div
div
div
div
solid-display.segment.block.whitespace-normal(
fields="segment0(segment1(community-picture(logo)), segment2(segment3(segment4(name),segment5(profile.tweeter, profile.facebook, profile.linkedin, profile.instagram)), segment6(profile.shortDescription), segment7(profile.tweeter, profile.facebook, profile.linkedin, profile.instagram), segment8(addresses, members, profile.website, profile.email, profile.phone), segment9(profile.description), segment10(edit))), segment11(profile.picture1, profile.picture2, profile.picture3)"
loader-id=`loader-${component.route}-profile`
class-segment0="segment full padding-xlarge sm-padding-none whitespace-normal"
class-segment1="community-profile-logo segment quarter sm-full margin-top-medium padding-top-medium padding-right-medium sm-margin-top-xsmall sm-padding-medium text-center"
class-segment2="segment three-quarter sm-full sm-padding-top-medium sm-padding-right-xsmall sm-padding-bottom-medium sm-padding-left-xsmall text-top sm-text-center whitespace-normal"
class-segment3="segment full sm-two-third"
class-segment4="segment half sm-two-third padding-top-xsmall"
class-name="segment block text-color-heading text-xxlarge text-bold sm-text-center margin-bottom-xxsmall whitespace-normal"
class-segment5="segment half text-right sm-hidden"
class-segment6="segment two-third sm-full padding-top-xsmall sm-text-center"
class-profile.shortDescription="segment block sm-text-center margin-bottom-large whitespace-normal"
class-segment7="segment lg-hidden sm-full"
class-segment8="segment two-third sm-full padding-bottom-large padding-bottom-xxsmall sm-text-left"
class-addresses="segment block margin-bottom-xsmall"
class-members="segment block margin-bottom-xsmall"
class-profile.website="segment block"
class-profile.email="segment block"
class-profile.phone="segment block"
class-segment9="segment full"
class-profile.description="segment full whitespace-normal"
class-segment10="segment full text-right"
class-segment11="segment full whitespace-normal flex"
class-profile.picture1="communities-profile-picture segment third sm-full"
class-profile.picture2="communities-profile-picture segment third sm-full"
class-profile.picture3="communities-profile-picture segment third sm-full"
widget-logo="hubl-communities-profile-logo"
widget-profile.description="solid-display-value-markdown"
widget-profile.tweeter="hubl-communities-profile-twitter"
widget-profile.facebook="hubl-communities-profile-facebook"
widget-profile.linkedin="hubl-communities-profile-linkedin"
widget-profile.instagram="hubl-communities-profile-instagram"
widget-addresses="hubl-communities-profile-address"
widget-members="hubl-communities-profile-members-counter"
widget-profile.website="hubl-communities-profile-website"
widget-profile.email="hubl-communities-profile-email"
widget-profile.phone="hubl-communities-profile-phone"
widget-profile.picture1="hubl-communities-profile-picture"
widget-profile.picture2="hubl-communities-profile-picture"
widget-profile.picture3="hubl-communities-profile-picture"
action-edit="edit"
widget-edit="hubl-communities-edit-button"
multiple-addresses
multiple-addresses-fields="address_line1, address_line2"
bind-resources
)
solid-map.communities-profile-map(
bind-resources
nested-field="addresses"
fields="position(community.name, address_line1, address_line2)"
class-community.name="segment block margin-bottom-xsmall text-color-heading text-xlarge text-bold text-center"
class-address_line1="segment block"
class-address_line2="segment block"
clustering=""
style="display:block;height:450px;"
)

View File

@ -99,7 +99,7 @@ div
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-people.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.community')
a.icon.icon-grid.icon-third.icon-small.icon-margin-right-xsmall(data-trans='admin.menuRight.community')
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

View File

@ -5,14 +5,15 @@ solid-form-search.icon.children-icon-magnifier(
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=""
submit-widget="button"
)
div.divider
solid-router#navbar-router(default-route='dashboard')
solid-router#navbar-router(default-route=defaultRoute)
for component of components
if component.route
if component.type == "about"
@ -23,6 +24,14 @@ solid-router#navbar-router(default-route='dashboard')
div.icon.icon-small.icon-home
div.segment.text-uppercase.text-letter-spacing-large(data-trans=`${component.name?component.name:"menuLeft.dashboard"}`)
div.divider
if component.type == "communities"
solid-route.menu.segment.full.padding-xsmall.text-semibold.text-color-white.heading-active.bg-color-heading.hover.active(name=component.route)
div.segment.margin-right-xxsmall
div.segment.icon.icon-small.icon-grid
div.segment.text-uppercase.text-letter-spacing-large(data-trans="menuLeft.communities")
solid-route(name=`${component.route}-profile`)
div.divider
if component.type == "circles"
div.jsMenuTab
div.menu-header.segment.full.padding-xsmall.text-semibold.text-color-white.bg-color-heading.transparent-background.hover.cursor-pointer.jsMenuHeader

View File

@ -1,17 +1,20 @@
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
solid-display.text-xxlarge.text-letter-spacing-large(
bind-resources
fields='const-title1, number, customer.name, dash, name'
div.segment.full.sm-three-quarter.whitespace-normal
solid-display.text-xlarge.text-letter-spacing-large(
bind-resources
fields='const-title1, number, customer.name, dash, name'
class-const-title1='text-color-heading text-bold text-uppercase'
class-number='text-color-heading text-bold text-uppercase word-spacing-right'
class-customer.name='text-color-heading text-bold text-uppercase'
class-dash='text-color-heading text-bold text-xlarge'
class-name=''
class-const-title1='text-color-heading text-bold text-uppercase'
class-number='text-color-heading text-bold text-uppercase word-spacing-right'
class-customer.name='text-color-heading text-bold text-uppercase'
class-dash='text-color-heading text-bold text-xlarge'
class-name=''
value-const-title1='N°'
value-dash=' - '
)
value-const-title1='N°'
value-dash=' - '
)
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
.chat-view.segment.full.whitespace-normal
solid-xmpp-chat(

View File

@ -1,7 +1,7 @@
solid-ac-checker(permission='acl:Read', bind-resources)
div.segment.full.padding-large.border-bottom.border-color-grey
div.segment.half.sm-full
solid-display.text-xxlarge.text-letter-spacing-large(
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
div.segment.half.sm-three-quarter.whitespace-normal
solid-display.text-xlarge.text-letter-spacing-large(
bind-resources
fields='const-title1, number, customer.name, dash, name'
@ -16,6 +16,8 @@ solid-ac-checker(permission='acl:Read', bind-resources)
)
div.segment.half.sm-hidden.text-right
solid-link(class='backlink', bind-resources, next=`${component.route}-profile` data-trans='project.edit.backlink')
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.whitespace-normal

View File

@ -0,0 +1,5 @@
solid-invoicing(
bind-resources
upload-dir=`${extension.endpoints.uploads}`
uniq=extension.uniq
)

View File

@ -9,19 +9,22 @@ div(
)
solid-ac-checker.segment.block(permission='acl:Read', bind-resources)
div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-padding-bottom-small.sm-padding-left-xsmall.border-bottom.border-color-grey.whitespace-normal
solid-display.text-xxlarge.text-letter-spacing-large(
bind-resources
fields='const-title1, number, customer.name, dash, name'
div.segment.full.sm-three-quarter.whitespace-normal
solid-display.text-xlarge.text-letter-spacing-large(
bind-resources
fields='const-title1, number, customer.name, dash, name'
class-const-title1='text-color-heading text-bold text-uppercase'
class-number='text-color-heading text-bold text-uppercase word-spacing-right'
class-customer.name='text-color-heading text-bold text-uppercase'
class-dash='text-color-heading text-bold text-xlarge'
class-name=''
class-const-title1='text-color-heading text-bold text-uppercase'
class-number='text-color-heading text-bold text-uppercase word-spacing-right'
class-customer.name='text-color-heading text-bold text-uppercase'
class-dash='text-color-heading text-bold text-xlarge'
class-name=''
value-const-title1='N°'
value-dash=' - '
)
value-const-title1='N°'
value-dash=' - '
)
div.segment.lg-hidden.sm-quarter.text-right
div.jsMobileRightMenuButton.icon.icon-options-vertical.icon-heading
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-xlarge
div.loader(id=`loader-${component.route}-profile`)

View File

@ -20,6 +20,23 @@ include widgets/hubl-circle-join-button.pug
include widgets/hubl-circle-owner.pug
include widgets/hubl-circle-team-contact.pug
include widgets/hubl-circle-user-admin.pug
include widgets/hubl-communities-counter-alternate.pug
include widgets/hubl-communities-edit-button.pug
include widgets/hubl-communities-edit-add-button.pug
include widgets/hubl-communities-edit-email.pug
include widgets/hubl-communities-edit-website.pug
include widgets/hubl-communities-logo.pug
include widgets/hubl-communities-map-fix-url-name.pug
include widgets/hubl-communities-profile-email.pug
include widgets/hubl-communities-profile-facebook.pug
include widgets/hubl-communities-profile-instagram.pug
include widgets/hubl-communities-profile-linkedin.pug
include widgets/hubl-communities-profile-logo.pug
include widgets/hubl-communities-profile-members-counter.pug
include widgets/hubl-communities-profile-phone.pug
include widgets/hubl-communities-profile-picture.pug
include widgets/hubl-communities-profile-twitter.pug
include widgets/hubl-communities-profile-website.pug
include widgets/hubl-counter.pug
include widgets/hubl-email-field.pug
include widgets/hubl-menu-empty.pug

View File

@ -1,3 +1,3 @@
if componentSet.has('admin') && componentSet.has('circles')
if (componentSet.has('admin') && componentSet.has('circles')) || componentSet.has('communities')
solid-widget(name='hubl-admin-community-logo')
template ${value != "" ? `<div \style="background-image:url(${value});" />` : `<div></div>`}

View File

@ -0,0 +1,12 @@
if componentSet.has('communities')
solid-widget(name='hubl-communities-counter-alternate')
template
div
span.icon.icon-people.icon-third.icon-large.margin-right-xsmall
solid-display(
fields=''
data-src="${src || value}"
nested-field="members"
counter-template="\\\${counter}"
)
span(data-trans="communities.list.members")

View File

@ -0,0 +1,11 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-edit-add-button')
template
div(
class="segment text-xsmall children-link-button children-link-text-bold children-link-text-uppercase children-link-color-secondary bordered"
)
button.form-sub(
data-trans="communities.edit.buttonAdd"
type="button"
onclick="window.hubl.geocalc(this);"
)

View File

@ -0,0 +1,10 @@
if componentSet.has('communities')
solid-widget(name="hubl-communities-edit-address-delete")
template
solid-ac-checker(permission="acl:Delete", data-src="${src}")
solid-delete(
class='segment text-xsmall children-link-button children-link-text-bold children-link-text-uppercase children-link-color-secondary bordered'
data-src="${src}"
data-label=''
data-trans='data-label=communities.edit.buttonDelete'
)

View File

@ -0,0 +1,14 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-edit-button')
template
solid-ac-checker(
permission='acl:Write'
data-src="${src}"
nested-field="profile"
)
solid-link(
class="segment margin-top-xxlarge sm-full button text-xsmall text-bold text-uppercase text-center reversed color-secondary bordered icon icon-pencil"
data-trans="communities.profile.edit"
data-src="${src}"
next=`${getRoute('communities', true)}-edit`
)

View File

@ -0,0 +1,5 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-edit-email')
template
label(class="text-small text-semibold text-uppercase text-color-heading" data-trans="communities.edit.labelEmail")
input(type="email" label="communities.edit.labelEmail" name="profile.email" value="\${value}" data-holder)

View File

@ -0,0 +1,5 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-edit-website')
template
label(class="text-small text-semibold text-uppercase text-color-heading" data-trans='communities.edit.labelWebsite')
input(type="url" label="communities.edit.labelWebsite" name="profile.website" value="\${value}" data-holder)

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-logo')
template ${value != "" ? `<div \style="background-image:url(${value});" />` : `<div></div>`}

View File

@ -0,0 +1,15 @@
if componentSet.has('communities')
solid-widget(name='hubl-communities-name')
template
solid-link(
data-src="${value}"
next=`${getRoute(`communities`, true)}-profile`
) ${await value.name}
solid-widget(name='hubl-communities-map-fix-url-name')
template
solid-display(
data-src="${src}"
fields="community"
widget-community='hubl-communities-name'
)

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-email')
template ${value != "" ? `<a class="link margin-bottom-xsmall icon mdi-email-outline icon-third icon-large icon-margin-right-xsmall" style="text-decoration:none;" href="mailto:\${value}">${value}</a>` : ""}

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-facebook')
template ${value != "" ? `<a class="segment children-link-rounded children-icon-social-facebook children-link-reversed color-secondary bordered margin-right-medium" href="${value}" target="_blank"><span></span></a>` : ""}

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-instagram')
template ${value != "" ? `<a class="segment children-link-rounded children-icon-social-instagram children-link-reversed color-secondary bordered" href="${value}" target="_blank"><span></span></a>` : ""}

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-linkedin')
template ${value != "" ? `<a class="segment children-link-rounded children-icon-social-linkedin children-link-reversed color-secondary bordered margin-right-medium" href="${value}" target="_blank"><span></span></a>` : ""}

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-logo')
template ${value != "" ? `<div \style="background-image:url(${value});" />` : ""}

View File

@ -0,0 +1,11 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-members-counter')
template
span
span.icon.icon-people.icon-third.icon-large.margin-right-xsmall
solid-display.text-medium(
data-src="${src || value}"
fields=''
counter-template="\\\${counter}"
)
span.text-medium(data-trans="communities.profile.members")

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-phone')
template ${value != "" ? `<a class="link margin-bottom-xsmall icon mdi-cellphone-iphone icon-third icon-large icon-margin-right-xsmall" style="text-decoration:none;" href="tel:\${value}">${value}</a>` : ""}

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-picture')
template ${value != "" ? `<div><div \style="background-image:url(${value});"></div></div>` : `<div class="picture-empty"></div>`}

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-twitter')
template ${value != "" ? `<a class="segment children-link-rounded children-icon-social-twitter children-link-reversed color-secondary bordered margin-right-medium" href="${value}" target="_blank"><span></span></a>` : ""}

View File

@ -0,0 +1,3 @@
if componentSet.has('communities') && getRoute('communities')
solid-widget(name='hubl-communities-profile-website')
template ${value != "" ? `<a class="link margin-bottom-xsmall icon mdi-link-variant icon-third icon-large icon-margin-right-xsmall" style="text-decoration:none;" href="tel:\${value}" target="_blank">${value}</a>` : ""}