major: core 0.16

This commit is contained in:
Jean-Baptiste Pasquier 2021-03-16 15:27:30 +01:00
parent 668dfd04d7
commit 41a2910a4a
33 changed files with 418 additions and 115 deletions

View File

@ -118,6 +118,17 @@ On `config.json`:
"client": { "client": {
"favicon": "/images/favicon.webp", "favicon": "/images/favicon.webp",
"css": "/path/to/custom.css", "css": "/path/to/custom.css",
"i18n": {
"lang": "fr",
"force": "false",
"files": [
{
"name": "yourCustomLangName",
"file": "/path/to/file.json"
},
...
]
}
} }
} }
``` ```
@ -126,6 +137,10 @@ Where:
* `client.favicon` is an URL to a distant favicon * `client.favicon` is an URL to a distant favicon
* `client.css` is an URL to a distant CSS that'll be the last one loaded by the Hubl * `client.css` is an URL to a distant CSS that'll be the last one loaded by the Hubl
* `client.i18n.lang` is the fallback langage in case the visitor's browser one does not contain the string
* `client.i18n.force` allows to ignore the visitor's browser langage and force the `client.i18n.lang` one
* `client.i18n.files[].name` allows to use custom client lang file.
* `client.i18n.files[].file` is the path the the json lang file
### Allow to login to your application ### Allow to login to your application
@ -144,6 +159,56 @@ Where:
* `authority` is the OpenID Provider. Usually, if you use `djangoldp_account` it's the same as your djangoldp server. * `authority` is the OpenID Provider. Usually, if you use `djangoldp_account` it's the same as your djangoldp server.
### Custom lang files
Each client can overwrite langs files with their own or even create custom langs.
#### Overwrite langs
On `config.json`:
```json
{
"client": {
"i18n": {
"files": [
{
"name": "fr",
"file": "/path/to/custom-fr.json"
}
]
}
}
}
```
#### Custom langs
Needs `client.i18n.force` to `true` and `client.i18n.lang` to the custom lang name.
Your custom JSON file **must** contain every keys, from the template and from every bloxes, prefixed by the blox namespace. See example on `src/locales/fr.json`.
On `config.json`:
```json
{
"client": {
"i18n": {
"lang": "pirate",
"force": "true",
"files": [
{
"name": "pirate",
"file": "/path/to/yarr.json"
}
]
}
}
}
```
Setting custom langs will not allow user to choose their own lang.
## Optional modules ## Optional modules
### Adding modules ### Adding modules
@ -573,6 +638,14 @@ Components can get the route of a module with `window.hubl.getRoute('componentNa
Did you properly created subscriptions on your DjangoLDP's server? You can quickly create them with `./manage.py create_subscriptions` Did you properly created subscriptions on your DjangoLDP's server? You can quickly create them with `./manage.py create_subscriptions`
### I see some technical strings instead of my fallback language strings
By default, the template fallback to `fr` lang, which is the most complete. If you're using your own fallback lang within your configuration, please ensure that this lang is completly translated.
### I see some technical strings instead of my custom language
Using a custom language file does not allow to use the default fallback language.
## Built With ## Built With
* [Sib-Core](https://git.startinblox.com/framework/sib-core/) - A SOLID-Compliant framework * [Sib-Core](https://git.startinblox.com/framework/sib-core/) - A SOLID-Compliant framework

6
package-lock.json generated
View File

@ -1159,9 +1159,9 @@
} }
}, },
"@startinblox/hubl-styling-framework": { "@startinblox/hubl-styling-framework": {
"version": "1.8.8", "version": "1.8.10",
"resolved": "https://registry.npmjs.org/@startinblox/hubl-styling-framework/-/hubl-styling-framework-1.8.8.tgz", "resolved": "https://registry.npmjs.org/@startinblox/hubl-styling-framework/-/hubl-styling-framework-1.8.10.tgz",
"integrity": "sha512-SKVRUV95f45qIGSgpIMvgbQaZ6mPNNCXQY+6LlU18lGMvq0vwQ3AmOuTkp4VbfUWvSLYXTUE1N61YmIFikMIfw==" "integrity": "sha512-3mT3H9Wgrgvja0JVu9TLEuvz1OtTeiN0UHuZx5IPLFDk5njGoDldElFEr3nw+BOMY1nJzSb8kHqW5cyIsP80cQ=="
}, },
"@types/q": { "@types/q": {
"version": "1.5.4", "version": "1.5.4",

View File

@ -45,7 +45,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@startinblox/hubl-styling-framework": "^1.8.8", "@startinblox/hubl-styling-framework": "^1.8.10",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",

View File

@ -1,5 +1,5 @@
window.hubl.getRoute = (type, returnFirst = false) => { window.hubl.getRoute = (type, returnFirst = false) => {
let availables = window.hubl.components.filter(c => c.type == type); let availables = window.hubl.components.filter(c => c.type == type || c.uniq == type);
if (availables.length > 1) { if (availables.length > 1) {
if (returnFirst) { if (returnFirst) {
return availables[0].route; return availables[0].route;

View File

@ -1,6 +1,6 @@
import { import {
Sib Sib
} from 'https://cdn.skypack.dev/@startinblox/core@0.15'; } from 'https://cdn.skypack.dev/@startinblox/core@0.16';
export const HublAutoLogin = { export const HublAutoLogin = {
name: 'hubl-auto-login', name: 'hubl-auto-login',

View File

@ -2,7 +2,7 @@ import {
store, store,
Sib, Sib,
StoreMixin StoreMixin
} from 'https://cdn.skypack.dev/@startinblox/core@0.15'; } from 'https://cdn.skypack.dev/@startinblox/core@0.16';
export const HublReactivity = { export const HublReactivity = {
name: 'hubl-reactivity', name: 'hubl-reactivity',

View File

@ -1,6 +1,6 @@
import { import {
widgetFactory widgetFactory
} from 'https://cdn.skypack.dev/@startinblox/core@0.15'; } from 'https://cdn.skypack.dev/@startinblox/core@0.16';
const HublSearchUsers = widgetFactory( const HublSearchUsers = widgetFactory(
'hubl-search-users', 'hubl-search-users',

View File

@ -1,7 +1,7 @@
import { import {
widgetFactory, widgetFactory,
Helpers Helpers
} from 'https://cdn.skypack.dev/@startinblox/core@0.15'; } from 'https://cdn.skypack.dev/@startinblox/core@0.16';
import SlimSelect from 'https://cdn.skypack.dev/slim-select@1.23'; import SlimSelect from 'https://cdn.skypack.dev/slim-select@1.23';
const HublStatus = widgetFactory( const HublStatus = widgetFactory(

View File

@ -1,4 +1,4 @@
script(type="module" src="https://cdn.skypack.dev/@startinblox/core@0.15" defer) script(type="module" src="https://cdn.skypack.dev/@startinblox/core@0.16" defer)
//- script(type="module" src="/lib/sib-core/dist/index.js" defer) //- script(type="module" src="/lib/sib-core/dist/index.js" defer)
script(type="module" src="https://cdn.skypack.dev/@startinblox/router@0.11" defer) script(type="module" src="https://cdn.skypack.dev/@startinblox/router@0.11" defer)
@ -7,45 +7,48 @@ script(type="module" src="https://cdn.skypack.dev/@startinblox/router@0.11" defe
- const componentSet = new Set(components.map(c=>c.type)); - const componentSet = new Set(components.map(c=>c.type));
if componentSet.has("autoLogin") || componentSet.has("registering") if componentSet.has("autoLogin") || componentSet.has("registering")
script(type="module" src="https://cdn.skypack.dev/@startinblox/oidc@0.13" defer) script(type="module" src="https://cdn.skypack.dev/@startinblox/oidc@0.14" defer)
//- script(type="module" src="/lib/sib-auth/index.js" defer) //- script(type="module" src="/lib/sib-auth/index.js" defer)
if componentSet.has("chat") || componentSet.has("circles") || componentSet.has("projects") if componentSet.has("chat") || componentSet.has("circles") || componentSet.has("projects")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-chat@4.2" defer) script(type="module" src="https://cdn.skypack.dev/@startinblox/component-chat@5.0" defer)
//- script(type="module" src="/lib/solid-xmpp-chat/dist/index.js" defer) //- script(type="module" src="/lib/solid-xmpp-chat/dist/index.js" defer)
if componentSet.has("dashboard") if componentSet.has("dashboard")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-dashboard@3.1" defer) 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) //- script(type="module" src="/lib/solid-dashboard/dist/index.js" defer)
if componentSet.has("events") //- Disabled - Not in core@0.16
//- if componentSet.has("events")
script(type="module", src="https://cdn.skypack.dev/@startinblox/component-event@2.1", defer) script(type="module", src="https://cdn.skypack.dev/@startinblox/component-event@2.1", defer)
//- script(type="module", src="/lib/solid-event/solid-event.js", defer) //- script(type="module", src="/lib/solid-event/solid-event.js", defer)
if componentSet.has("events") || componentSet.has("polls") || componentSet.has("resources") //- 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) script(type="module" src="https://cdn.skypack.dev/@startinblox/component-conversation@0.9" defer)
if componentSet.has("jobBoard") if componentSet.has("jobBoard")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-job-board@4.1" defer) script(type="module" src="https://cdn.skypack.dev/@startinblox/component-job-board@5.0" defer)
//- script(type="module" src="/lib/solid-job-board/dist/index.js" defer) //- script(type="module" src="/lib/solid-job-board/dist/index.js" defer)
if componentSet.has("notification") if componentSet.has("notification")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-notifications@0.11" defer) script(type="module" src="https://cdn.skypack.dev/@startinblox/component-notifications@0.12" defer)
//- script(type="module" src="/lib/sib-notifications/index.js" defer) //- script(type="module" src="/lib/sib-notifications/index.js" defer)
//- Disabled - Not in core@0.15 //- Disabled - Not in core@0.16
//- if componentSet.has("polls") //- if componentSet.has("polls")
//- script(type="module" src="https://cdn.skypack.dev/@startinblox/component-poll@1.2" defer) //- 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) //- //- script(type="module" src="/lib/sib-polls-component/index.js" defer)
if componentSet.has("resources") if componentSet.has("profileDirectory")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-directory@5.0" defer)
//- script(type="module" src="/lib/solid-directory/dist/index.js" defer)
//- Disabled - Not in core@0.16
//- if componentSet.has("resources")
script(type="module", src="https://cdn.skypack.dev/@startinblox/component-resource@2.0", defer) script(type="module", src="https://cdn.skypack.dev/@startinblox/component-resource@2.0", defer)
//- script(type="module" src="/lib/solid-resource/solid-resource.js" defer) //- script(type="module" src="/lib/solid-resource/solid-resource.js" defer)
if componentSet.has("themeChecker") if componentSet.has("themeChecker")
script(src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js" defer) script(src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js" defer)
link(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css') link(rel='stylesheet', href='https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css')
if componentSet.has("profileDirectory")
script(type="module" src="https://cdn.skypack.dev/@startinblox/component-directory@4.1" defer)
//- script(type="module" src="/lib/solid-directory/dist/index.js" defer)

View File

@ -5,12 +5,13 @@
Eg. Eg.
``` ```
window.hubl.getRoute('chat', true) window.hubl.getRoute('chat', true)
window.hubl.getRoute('uxnzsa') // Where uxnzsa is the uniq of the component
``` ```
will return the route of the first chat component, if exists, or triggers an error. will return the route of the first chat component, if exists, or triggers an error.
- -
let routes = new Set(); let routes = new Set();
const getRoute = (type, returnFirst = false) => { const getRoute = (type, returnFirst = false) => {
let availables = components.filter(c=>c.type==type); let availables = components.filter(c=>c.type==type||c.uniq==type);
if(availables.length > 1) { if(availables.length > 1) {
if(returnFirst) { if(returnFirst) {
return availables[0].route; return availables[0].route;
@ -52,5 +53,12 @@ for component of components
routes.add(route); routes.add(route);
component.route = route; component.route = route;
} }
- const hublComponents = `window.hubl={};window.hubl.components = ${JSON.stringify(components)};`; -
const defaultComponent = components.filter(e=>e.defaultRoute != undefined);
let defaultRoute = "dashboard";
if(defaultComponent.length == 1) {
defaultRoute = defaultComponent[0].uniq;
}
- const hublComponents = `window.hubl={};window.hubl.components = ${JSON.stringify(components)};window.hubl.defaultRoute = "${defaultRoute}";`;
script!=hublComponents script!=hublComponents

View File

@ -33,6 +33,7 @@ html(lang="en")
script(type="module" src="/components/hubl-search-users.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-status.js" defer)
script(type="module" src="/components/hubl-reactivity.js" defer) script(type="module" src="/components/hubl-reactivity.js" defer)
script(src="index.js" defer)
include dependencies.pug include dependencies.pug
include context.pug include context.pug
@ -40,7 +41,6 @@ html(lang="en")
//- swal2 does not work with skypack //- swal2 does not work with skypack
script(src="https://cdn.jsdelivr.net/npm/sweetalert2@10" defer) script(src="https://cdn.jsdelivr.net/npm/sweetalert2@10" defer)
script(src="index.js" defer)
body.bg-color-grey body.bg-color-grey
@ -197,6 +197,19 @@ html(lang="en")
span   span  
a(data-trans='errors.reload' href='/') a(data-trans='errors.reload' href='/')
if client.i18n
hubl-fallback-lang(
hidden
lang=client.i18n.lang?client.i18n.lang:"fr"
)&attributes({"force": client.i18n.force})
if client.i18n.files
for clientI18n in client.i18n.files
hubl-lang(
hidden
lang=clientI18n.name
file=clientI18n.file
)
div( div(
id="swal-content-text" id="swal-content-text"
hidden hidden

View File

@ -242,5 +242,59 @@
"errors": { "errors": {
"somethingGoesWrong": "Something goes wrong, try to", "somethingGoesWrong": "Something goes wrong, try to",
"reload": "reload" "reload": "reload"
},
"goButton": "GO",
"directory": {
"back": "Back",
"members": "members",
"module.name": "Members directory",
"picture.delete": "Remove the picture",
"picture.upload": "Upload the picture",
"profile.city": "City",
"profile.edit": "Edit my profile",
"profile.email": "E-mail",
"profile.firstName": "Firstname",
"profile.job": "Job",
"profile.name": "Name",
"profile.phone": "Phone",
"profile.smile": "Show us your best smile",
"profile.smileParagraph": "Pictures help us to know ourselves but also to recognize us, so don't be afraid to show",
"profile.smileParagraph2": "your pretty face and avoid weird avatars.",
"profile.website": "Website",
"save": "Save",
"search.by.city": "Search by city",
"search.by.job": "Search by job",
"search.by.name": "Search by name and/or firstname",
"search.by.skill": "Add a skill filter",
"sendMessage": "Send a message",
"settings.receiveMail": "I would like to receive notifications by email",
"skills.main": "Main skills:",
"skills": "Skills",
"profileHidden.lineOne": "Your profile is not visible on this directory",
"profileHidden.lineTwoOne": "To activate it, ",
"profileHidden.lineTwoTwo": "go to your profile",
"profileHidden.lineTwoThree": ". You need to add a photo.",
"myProfileHidden.lineOne": "Your profile is not visible to other members",
"myProfileHidden.lineTwo": "To activate it, you need to add a photo.",
"activeProfiles": "Show only active profiles",
"goButton": "GO"
},
"jobboard": {
"joboffers": "Job offers",
"joboffer.description": "Here you will find job offers",
"joboffer.edit": "Modify the job offer",
"joboffer.shownUntil": "THE OFFER WILL BE VISIBLE UNTIL",
"joboffer.title": "Title",
"joboffer.save": "SAVE MY OFFER",
"joboffer.requiredSkills": "REQUIRED SKILLS",
"joboffer.desc": "DESCRIPTION",
"joboffer.create": "POST A NEW JOB OFFER",
"joboffer.post": "Post a job offer",
"search.by.skills": "Search by skills",
"search.noResult": "There are no results for your search",
"search.tryAnother": "Try another skill ",
"edit": "Edit",
"back": "Back",
"goButton": "GO"
} }
} }

View File

@ -242,5 +242,59 @@
"errors": { "errors": {
"somethingGoesWrong": "Algo sale mal, intenta", "somethingGoesWrong": "Algo sale mal, intenta",
"reload": "recargar" "reload": "recargar"
},
"goButton": "GO",
"directory": {
"back": "Atrás",
"members": "Miembrxs",
"module.name": "Directorio de miembrxs",
"picture.delete": "Eliminar una foto",
"picture.upload": "Subir una foto",
"profile.city": "Ciudad",
"profile.edit": "Modificar mi perfil",
"profile.email": "E-mail",
"profile.firstName": "Nombre",
"profile.job": "Trabajo",
"profile.name": "Apellido",
"profile.phone": "Teléfono",
"profile.smile": "Muéstranos tu mejor sonrisa",
"profile.smileParagraph": "Las fotos nos ayudan a reconocernos entre nosotrxs y humanizar el listado ¡No tengas miedo de mostrarte!",
"profile.smileParagraph2": "Te invitamos a evitar avatares y usar fotos personales",
"profile.website": "Sitio web",
"save": "Guardar",
"search.by.city": "Buscar por ciudad",
"search.by.job": "Buscar por trabajo",
"search.by.name": "Buscar por nombre y/o apellido",
"search.by.skill": "Agregar un filtro de aptitudes",
"sendMessage": "Envía un mensaje",
"settings.receiveMail": "Me gustaría recibir notificaciones por correo electrónico",
"skills.main": "Aptitudes principales :",
"skills": "Aptitudes",
"profileHidden.lineOne": "Su perfil no es visible en este directorio",
"profileHidden.lineTwoOne": "Para activarlo, ",
"profileHidden.lineTwoTwo": "Ve a tu perfil",
"profileHidden.lineTwoThree": ". Debes añadir una foto.",
"myProfileHidden.lineOne": "Su perfil no es visible para otros miembros",
"myProfileHidden.lineTwo": "Para activarlo, debes añadir una foto",
"activeProfiles": "Mostrar solo perfiles activos",
"goButton": "GO"
},
"jobboard": {
"joboffers": "Oportunidades de trabajo",
"joboffer.description": "Aquí encontrarás oportunidades de trabajo",
"joboffer.edit": "Modificar la oportunidad de trabajo",
"joboffer.shownUntil": "LA OPORTUNIDAD SERÁ VISIBLE HASTA",
"joboffer.title": "Título",
"joboffer.save": "GUARDAR LA OPORTUNIDAD",
"joboffer.requiredSkills": "APTITUDES REQUERIDAS",
"joboffer.desc": "DESCRIPCIÓN",
"joboffer.create": "PUBLICAR UNA NUEVA OPORTUNIDAD DE TRABAJO",
"joboffer.post": "Publicar una oportunidad",
"search.by.skills": "Buscar por oportunidad",
"search.noResult": "No hay resultados para su búsqueda",
"search.tryAnother": "Prueba otra habilidad ",
"edit": "Modificar",
"back": "Atrás",
"goButton": "GO"
} }
} }

View File

@ -244,5 +244,59 @@
"errors": { "errors": {
"somethingGoesWrong": "Quelque chose ne va pas, essayez de", "somethingGoesWrong": "Quelque chose ne va pas, essayez de",
"reload": "recharger" "reload": "recharger"
},
"goButton": "GO",
"directory": {
"back": "Retour",
"members": "membres",
"module.name": "Annuaire des membres",
"picture.delete": "Supprimer une photo",
"picture.upload": "Télécharger une photo",
"profile.city": "Ville",
"profile.edit": "Modifier mon profil",
"profile.email": "E-mail",
"profile.firstName": "Prénom",
"profile.job": "Métier",
"profile.name": "Nom",
"profile.phone": "Téléphone",
"profile.smile": "Montre-nous ton plus beau sourire",
"profile.smileParagraph": "Les photos nous aident à nous connaître mais aussi à nous reconnaître, alors n'aie pas peur de montrer",
"profile.smileParagraph2": "ton joli minois et évite les avatars bizarres.",
"profile.website": "Site",
"save": "Enregistrer",
"search.by.city": "Rechercher par ville",
"search.by.job": "Rechercher par métier",
"search.by.name": "Rechercher par nom et/ou prénom",
"search.by.skill": "Ajouter un filtre compétence",
"sendMessage": "Envoyer un message",
"settings.receiveMail": "Je souhaite recevoir les notifications par mail",
"skills.main": "Compétences principales :",
"skills": "Compétences",
"profileHidden.lineOne": "Votre profil n'est pas visible sur cet annuaire.",
"profileHidden.lineTwoOne": "Pour l'activer, ",
"profileHidden.lineTwoTwo": "rendez-vous sur votre profil",
"profileHidden.lineTwoThree": ". Vous devez ajouter une photo.",
"myProfileHidden.lineOne": "Votre profil n'est pas visible des autres membres.",
"myProfileHidden.lineTwo": "Pour l'activer, vous devez ajouter une photo.",
"activeProfiles": "Afficher uniquement les profils actifs",
"goButton": "GO"
},
"jobboard": {
"joboffers": "Offres de missions",
"joboffer.description": "Tu trouveras ici des offres de missions",
"joboffer.edit": "Modifier l'offre de mission",
"joboffer.shownUntil": "L'OFFRE SERA VISIBLE JUSQU'AU",
"joboffer.title": "Titre",
"joboffer.save": "ENREGISTRER MON OFFRE",
"joboffer.requiredSkills": "COMPÉTENCES REQUISES",
"joboffer.desc": "DESCRIPTIF",
"joboffer.create": "POSTER UNE NOUVELLE OFFRE DE MISSION",
"joboffer.post": "Poster une offre",
"search.by.skills": "Rechercher par compétence",
"search.noResult": "Il n'y a aucun résultat pour ta recherche",
"search.tryAnother": "Essaye une autre compétence",
"edit": "Editer",
"back": "Retour",
"goButton": "GO"
} }
} }

View File

@ -6,17 +6,49 @@ class JsI18n {
constructor() { constructor() {
this.locale = ""; //Current locale this.locale = ""; //Current locale
this.locales = new Array(); //Available locales this.locales = new Array(); //Available locales
this.defaultLocale = "fr";
} }
/* /*
Method for automatically detecting the language, does not work in every browser. Method for automatically detecting the language, does not work in every browser.
*/ */
detectLanguage() { 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();
});
}
}
}
this.resumeDetection();
}
resumeDetection() {
const langComponent = document.querySelector('hubl-fallback-lang');
if(langComponent) {
if(langComponent.hasAttribute('lang')) {
this.defaultLocale = langComponent.getAttribute('lang');
if(langComponent.hasAttribute('force')) {
localStorage.setItem('language', this.defaultLocale);
}
}
}
if (localStorage.getItem('language') || (window.navigator.language !== null && window.navigator.language !== undefined)) { if (localStorage.getItem('language') || (window.navigator.language !== null && window.navigator.language !== undefined)) {
this.fetchLocale(this.defaultLocale);
this.setLocale(localStorage.getItem('language') || window.navigator.language.slice(0, 2)); this.setLocale(localStorage.getItem('language') || window.navigator.language.slice(0, 2));
} else { } else {
console.error('Language not found'); console.error('Language not found');
this.setLocale('fr'); this.setLocale(this.defaultLocale);
} }
}; };
@ -105,38 +137,36 @@ class JsI18n {
this.locales[locale.toString()] = translations; 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();
}
}
/* /*
Sets the locale to use when translating. Sets the locale to use when translating.
*/ */
setLocale(locale) { setLocale(locale) {
try { try {
fetch(`/locales/${locale}.json`).then((result) => { this.fetchLocale(locale).then(() => {
if (result.ok) { if(this.locale) {
result.json().then(e => { localStorage.setItem('language', this.locale);
this.addLocale(locale, e);
this.processPage();
}).catch(() => {
if (locale != "fr") {
console.warn(`Locale not found: ${locale}, fallback to french`);
this.setLocale("fr");
} else {
console.error("Language not found");
}
});
} else {
if (locale != "fr") {
console.warn(`Locale not found: ${locale}, fallback to french`);
this.setLocale("fr");
} else {
console.error("Language not found");
}
} }
this.processPage();
this.locale = locale;
}); });
this.locale = locale;
} catch { } catch {
if (locale != "fr") { if (locale != this.defaultLocale) {
console.warn(`Locale not found: ${locale}, fallback to french`); console.warn(`Locale not found: ${locale}, fallback to ${this.defaultLocale}`);
this.setLocale("fr"); this.setLocale(this.defaultLocale);
} else { } else {
console.error("Language not found"); console.error("Language not found");
} }
@ -148,12 +178,22 @@ class JsI18n {
*/ */
t(key) { t(key) {
var translations = this.locales[this.locale]; var translations = this.locales[this.locale];
if (translations != undefined) { if (translations == undefined) {
translations = this.locales[this.defaultLocale];
}
if(translations != undefined) {
let translation = key.toString().split('.').reduce((o, i) => (o ? o[i] : undefined), translations); let translation = key.toString().split('.').reduce((o, i) => (o ? o[i] : undefined), translations);
if (typeof translation == "string") { if (typeof translation == "string") {
return translation; return translation;
} else { } else {
return translations[key.toString()]; try {
let keySplitted = key.toString().split('.');
let first = keySplitted.shift();
translation = translations[first][keySplitted.join('.')];
return translation;
} catch {
return translations[key.toString()];
}
} }
} }
return undefined; return undefined;
@ -176,21 +216,20 @@ class JsI18n {
} }
//Global //Global
jsI18n = new JsI18n; window.hubl.intl = new JsI18n;
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
// Detect the lang & initialize, based on the browser or "language" item from localstorage // Detect the lang & initialize, based on the browser or "language" item from localstorage
jsI18n.detectLanguage(); window.hubl.intl.detectLanguage();
let timer; let timer;
(new MutationObserver((mutations) => { (new MutationObserver((mutations) => {
mutations.forEach(mutation => { mutations.forEach(mutation => {
if (mutation.target.attributes["data-trans"] != null) { if (mutation.target.attributes["data-trans"] != null) {
// Render the target of the mutation instantly // Render the target of the mutation instantly
jsI18n.processNode(mutation.target); window.hubl.intl.processNode(mutation.target);
// Then wait one arbitrary second to re-render the whole document in case a widget re-rendered // Then wait one arbitrary second to re-render the whole document in case a widget re-rendered
clearTimeout(timer); clearTimeout(timer);
timer = setTimeout(() => jsI18n.processNode(document.querySelector('body')), 500); timer = setTimeout(() => window.hubl.intl.processNode(document.querySelector('body')), 500);
} }
}); });
}).observe(document.body, { }).observe(document.body, {
@ -198,9 +237,9 @@ document.addEventListener("DOMContentLoaded", () => {
childList: true childList: true
})); }));
document.addEventListener('widgetRendered', event => { document.addEventListener('widgetRendered', event => {
jsI18n.processNode(event.target); window.hubl.intl.processNode(event.target);
// Then wait one arbitrary second to re-render the whole document in case a widget re-rendered // Then wait one arbitrary second to re-render the whole document in case a widget re-rendered
clearTimeout(timer); clearTimeout(timer);
timer = setTimeout(() => jsI18n.processNode(document.querySelector('body')), 500); timer = setTimeout(() => window.hubl.intl.processNode(document.querySelector('body')), 500);
}); });
}); });

View File

@ -36,7 +36,7 @@ window.addEventListener("navigate", e => {
window.dispatchEvent( window.dispatchEvent(
new CustomEvent('requestNavigation', { new CustomEvent('requestNavigation', {
detail: { detail: {
route: window.hubl.getRoute("dashboard", true) route: window.hubl.getRoute((window.hubl.defaultRoute || "dashboard"), true)
} }
}), }),
); );

View File

@ -67,7 +67,7 @@
} }
solid-form-text-label, solid-form-text-label,
hubl-input-type-password, solid-form-password,
hubl-input-type-email { hubl-input-type-email {
color: #5D7393; color: #5D7393;
} }
@ -76,7 +76,7 @@
text-align: left; text-align: left;
} }
input[type="submit"] { [type="submit"] {
float: initial !important; float: initial !important;
} }
} }

View File

@ -1,5 +1,5 @@
.search-form { .search-form {
input[type="submit"] { [type="submit"] {
margin-bottom: 20px; margin-bottom: 20px;
@media (min-width: 768.01px) { @media (min-width: 768.01px) {
margin-bottom: 0; margin-bottom: 0;

View File

@ -106,8 +106,10 @@ hubl-create-contact {
/* Fix on Join button in admin (circles + projects) */ /* 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. */ /* 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. */ /* 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 { .join-button {
input { input,
button {
padding: 9px 20px; padding: 9px 20px;
border-radius: 16.5px; border-radius: 16.5px;
height: 33px; height: 33px;

View File

@ -26,7 +26,6 @@ div.segment.full.padding-top-small.padding-right-large.padding-bottom-small.padd
data-authentication='login' data-authentication='login'
data-auto-login='true' data-auto-login='true'
data-websocket-url=component.endpoints.xmpp data-websocket-url=component.endpoints.xmpp
data-i18n='en'
bind-resources bind-resources
uniq=component.uniq uniq=component.uniq
) )

View File

@ -58,15 +58,6 @@
class-logo='community-logo' class-logo='community-logo'
default-logo=`${client.logo || '/images/logo.webp'}` default-logo=`${client.logo || '/images/logo.webp'}`
) )
solid-widget(name='hubl-input-type-password')
template
label ${label}
input(
type="password"
name="user.password"
required
data-holder
)
solid-widget(name='hubl-input-type-email') solid-widget(name='hubl-input-type-email')
template template
label ${label} label ${label}
@ -88,7 +79,7 @@
widget-user.first_name='solid-form-text-label' widget-user.first_name='solid-form-text-label'
widget-user.last_name='solid-form-text-label' widget-user.last_name='solid-form-text-label'
widget-user.email='hubl-input-type-email' widget-user.email='hubl-input-type-email'
widget-user.password='hubl-input-type-password' widget-user.password='solid-form-password'
widget-user.username='solid-form-hidden' widget-user.username='solid-form-hidden'
class-user.first_name='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left' class-user.first_name='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left'
class-user.last_name='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left' class-user.last_name='segment margin-bottom-medium full padding-left-small sm-padding-none text-large text-left'
@ -98,10 +89,11 @@
required-user.last_name required-user.last_name
required-user.email required-user.email
required-user.password required-user.password
pattern-user.first_name='.+' minlength-user.first_name='1'
pattern-user.last_name='.+' minlength-user.last_name='1'
value-user.username='generate-an-username' value-user.username='generate-an-username'
submit-button='' submit-button=''
submit-widget="button"
id='user-creation-form' id='user-creation-form'
next=getRoute('dashboard', true) next=getRoute('dashboard', true)
) )

View File

@ -56,5 +56,6 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
next=`admin-${getRoute('chat', true)}` next=`admin-${getRoute('chat', true)}`
submit-button='' submit-button=''
submit-widget="button"
data-trans='label-user.first_name=user.create.labelFirstname;label-user.last_name=user.create.labelLastname;label-user.username=user.create.labelUsername;label-user.email=user.create.labelEmail;submit-button=user.create.buttonSubmit' data-trans='label-user.first_name=user.create.labelFirstname;label-user.last_name=user.create.labelLastname;label-user.username=user.create.labelUsername;label-user.email=user.create.labelEmail;submit-button=user.create.buttonSubmit'
) )

View File

@ -10,10 +10,11 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
id="admin-community-filter" id="admin-community-filter"
fields='cell1' fields='cell1'
label-cell1='' label-cell1=''
data-trans='label-cell1=communities.searchBy'
widget-cell1='solid-form-label-text' widget-cell1='solid-form-label-text'
class-cell1="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading" class-cell1="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
submit-button="GO" submit-button=""
submit-widget="button"
data-trans='label-cell1=communities.searchBy;submit-button=goButton'
) )
.segment.table-wrapper .segment.table-wrapper

View File

@ -43,6 +43,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
next=getRoute('circles', true) next=getRoute('circles', true)
submit-button='' submit-button=''
submit-widget="button"
data-trans='label-status=circle.create.labelStatus;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='label-status=circle.create.labelStatus;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

@ -24,10 +24,11 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
id="admin-circle-filter" id="admin-circle-filter"
fields='name' fields='name'
label-name='' label-name=''
data-trans='label-name=circle.list.searchBy'
widget-name='solid-form-label-text' widget-name='solid-form-label-text'
class-name="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading" class-name="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
submit-button="GO" submit-button=""
submit-widget="button"
data-trans='label-name=circle.list.searchBy;submit-button=goButton'
) )
.segment.table-wrapper .segment.table-wrapper
@ -38,7 +39,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
div.segment.table-cell.third(data-trans='circle.list.tableHeader2') div.segment.table-cell.third(data-trans='circle.list.tableHeader2')
div.segment.table-cell.third(data-trans='circle.list.tableHeader3') div.segment.table-cell.third(data-trans='circle.list.tableHeader3')
solid-widget(name=`leave-circle-reactivity-${component.uniq}`) solid-widget(name=`leave-circle-reactivity`)
template template
hubl-reactivity(data-src=`${getComponent('circles').endpoints.get}` target-src='${value}') hubl-reactivity(data-src=`${getComponent('circles').endpoints.get}` target-src='${value}')
hubl-reactivity(data-src=`${getComponent('circles').endpoints.get}joinable/` target-src='${value}') hubl-reactivity(data-src=`${getComponent('circles').endpoints.get}joinable/` target-src='${value}')
@ -46,7 +47,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
hubl-reactivity(data-src=`${getComponent('circles').endpoints.post}joinable/` target-src='${value}') hubl-reactivity(data-src=`${getComponent('circles').endpoints.post}joinable/` target-src='${value}')
hubl-reactivity(bind-user nested-field="circles" target-src='${value}') hubl-reactivity(bind-user nested-field="circles" target-src='${value}')
solid-widget(name=`hubl-admin-circle-leave-button-${component.uniq}`) solid-widget(name=`hubl-admin-circle-leave-button`)
template template
solid-delete( solid-delete(
class='segment text-xsmall children-link-button children-link-text-bold children-link-text-uppercase children-link-color-secondary bordered' class='segment text-xsmall children-link-button children-link-text-bold children-link-text-uppercase children-link-color-secondary bordered'
@ -62,7 +63,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
solid-display( solid-display(
data-src="${src}" data-src="${src}"
fields="circle" fields="circle"
widget-circle=`leave-circle-reactivity-${component.uniq}` widget-circle=`leave-circle-reactivity`
hidden hidden
) )
@ -83,7 +84,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
class-circle.subtitle='segment full text-ellipsis' class-circle.subtitle='segment full text-ellipsis'
action-leaveButton="joinButton" action-leaveButton="joinButton"
widget-leaveButton=`hubl-admin-circle-leave-button-${component.uniq}` widget-leaveButton=`hubl-admin-circle-leave-button`
widget-circle.owner='hubl-circle-owner' widget-circle.owner='hubl-circle-owner'
action-counter="counter" action-counter="counter"
widget-counter="hubl-admin-circle-counter-alternate" widget-counter="hubl-admin-circle-counter-alternate"
@ -91,7 +92,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
order-by="circle.name" order-by="circle.name"
) )
solid-widget(name=`hubl-admin-circle-join-button-${component.uniq}`) solid-widget(name=`hubl-admin-circle-join-button`)
template template
solid-form( solid-form(
class='join-button text-xsmall' class='join-button text-xsmall'
@ -102,6 +103,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
widget-user.username='solid-form-hidden' widget-user.username='solid-form-hidden'
submit-button='' submit-button=''
submit-widget="button"
data-trans='submit-button=circle.list.buttonJoin' data-trans='submit-button=circle.list.buttonJoin'
) )
hubl-reactivity(data-src=`${getComponent('circles').endpoints.get}` target-src='${value}') hubl-reactivity(data-src=`${getComponent('circles').endpoints.get}` target-src='${value}')
@ -128,7 +130,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
class-subtitle='segment full text-ellipsis' class-subtitle='segment full text-ellipsis'
widget-owner='hubl-circle-owner' widget-owner='hubl-circle-owner'
widget-members=`hubl-admin-circle-join-button-${component.uniq}` widget-members=`hubl-admin-circle-join-button`
action-counter="counter" action-counter="counter"
widget-counter="hubl-admin-circle-counter" widget-counter="hubl-admin-circle-counter"

View File

@ -45,6 +45,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
widget-linebreak='solid-form-hidden' widget-linebreak='solid-form-hidden'
submit-button='' submit-button=''
submit-widget="button"
next=getRoute('projects', true) next=getRoute('projects', true)
data-trans='label-status=project.create.labelStatus;label-customer.name=project.create.labelCustomer;label-name=project.create.labelName;label-description=project.create.labelDescription;label-captain=project.create.labelCaptain;label-help=project.create.descriptionHelp;submit-button=project.create.buttonSubmit' data-trans='label-status=project.create.labelStatus;label-customer.name=project.create.labelCustomer;label-name=project.create.labelName;label-description=project.create.labelDescription;label-captain=project.create.labelCaptain;label-help=project.create.descriptionHelp;submit-button=project.create.buttonSubmit'

View File

@ -18,10 +18,11 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
id="admin-project-filter" id="admin-project-filter"
fields='cell1' fields='cell1'
label-cell1='' label-cell1=''
data-trans='label-cell1=project.list.searchBy'
widget-cell1='solid-form-label-text' widget-cell1='solid-form-label-text'
class-cell1="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading" class-cell1="segment margin-bottom-medium third sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading"
submit-button="GO" submit-button=""
submit-widget="button"
data-trans='label-cell1=project.list.searchBy;submit-button=goButton'
) )
.segment.table-wrapper .segment.table-wrapper
@ -33,7 +34,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
div.segment.table-cell.quarter(data-trans='project.list.tableHeader3') div.segment.table-cell.quarter(data-trans='project.list.tableHeader3')
div.segment.table-cell.quarter(data-trans='project.list.tableHeader4') div.segment.table-cell.quarter(data-trans='project.list.tableHeader4')
solid-widget(name=`leave-project-reactivity-${component.uniq}`) solid-widget(name=`leave-project-reactivity`)
template template
hubl-reactivity(data-src=`${getComponent('projects').endpoints.get}` target-src='${value}') hubl-reactivity(data-src=`${getComponent('projects').endpoints.get}` target-src='${value}')
hubl-reactivity(data-src=`${getComponent('projects').endpoints.get}joinable/` target-src='${value}') hubl-reactivity(data-src=`${getComponent('projects').endpoints.get}joinable/` target-src='${value}')
@ -41,7 +42,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
hubl-reactivity(data-src=`${getComponent('projects').endpoints.post}joinable/` target-src='${value}') hubl-reactivity(data-src=`${getComponent('projects').endpoints.post}joinable/` target-src='${value}')
hubl-reactivity(bind-user nested-field="projects" target-src='${value}') hubl-reactivity(bind-user nested-field="projects" target-src='${value}')
solid-widget(name=`hubl-admin-project-leave-button-${component.uniq}`) solid-widget(name=`hubl-admin-project-leave-button`)
template template
solid-delete( solid-delete(
class='segment text-xsmall children-link-button children-link-text-bold children-link-text-uppercase children-link-color-secondary bordered' class='segment text-xsmall children-link-button children-link-text-bold children-link-text-uppercase children-link-color-secondary bordered'
@ -57,7 +58,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
solid-display( solid-display(
data-src="${src}" data-src="${src}"
fields="project" fields="project"
widget-project=`leave-project-reactivity-${component.uniq}` widget-project=`leave-project-reactivity`
hidden hidden
) )
@ -88,7 +89,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
class-project.name='segment full' class-project.name='segment full'
action-leaveButton="joinButton" action-leaveButton="joinButton"
widget-leaveButton=`hubl-admin-project-leave-button-${component.uniq}` widget-leaveButton=`hubl-admin-project-leave-button`
widget-project.captain='hubl-project-captain' widget-project.captain='hubl-project-captain'
widget-project.members='hubl-project-admins' widget-project.members='hubl-project-admins'
@ -98,7 +99,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
order-by="project.name" order-by="project.name"
) )
solid-widget(name=`hubl-admin-project-join-button-${component.uniq}`) solid-widget(name=`hubl-admin-project-join-button`)
template template
solid-form( solid-form(
class='button text-xsmall text-bold text-uppercase reversed color-secondary bordered icon icon-arrow-right-circle' class='button text-xsmall text-bold text-uppercase reversed color-secondary bordered icon icon-arrow-right-circle'
@ -110,6 +111,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
widget-user.username='solid-form-hidden' widget-user.username='solid-form-hidden'
submit-button='' submit-button=''
submit-widget="button"
data-trans='submit-button=project.list.buttonJoin' data-trans='submit-button=project.list.buttonJoin'
) )
hubl-reactivity(data-src=`${getComponent('projects').endpoints.get}` target-src='${value}') hubl-reactivity(data-src=`${getComponent('projects').endpoints.get}` target-src='${value}')
@ -136,7 +138,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
class-name='segment full' class-name='segment full'
action-joinButton="joinButton" action-joinButton="joinButton"
widget-joinButton=`hubl-admin-project-join-button-${component.uniq}` widget-joinButton=`hubl-admin-project-join-button`
widget-captain='hubl-project-captain' widget-captain='hubl-project-captain'
widget-members='hubl-project-admins' widget-members='hubl-project-admins'

View File

@ -14,7 +14,6 @@ div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-p
data-authentication='login' data-authentication='login'
data-auto-login='true' data-auto-login='true'
data-websocket-url=component.endpoints.xmpp data-websocket-url=component.endpoints.xmpp
data-i18n='en'
bind-resources bind-resources
uniq=component.uniq uniq=component.uniq
) )

View File

@ -53,7 +53,8 @@ div.segment.full.padding-large.whitespace-normal
partial='' partial=''
submit-button='Enregistrer' submit-button=''
submit-widget="button"
next=`${component.route}-information` next=`${component.route}-information`
data-trans='label-status=circle.edit.labelStatus;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='label-status=circle.edit.labelStatus;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'
@ -72,6 +73,7 @@ div.segment.full.padding-large.whitespace-normal
widget-user='solid-form-dropdown-autocompletion' widget-user='solid-form-dropdown-autocompletion'
submit-button='' submit-button=''
submit-widget="button"
data-trans='submit-button=circle.edit.buttonAddMember' data-trans='submit-button=circle.edit.buttonAddMember'
) )

View File

@ -45,16 +45,17 @@ div(
solid-ac-checker(no-permission='acl:Delete', bind-resources) solid-ac-checker(no-permission='acl:Delete', bind-resources)
solid-link(class='segment sm-full button text-xsmall text-bold text-uppercase text-center reversed color-secondary bordered icon icon-pencil' next=`${component.route}-edit` bind-resources data-trans='circle.profile.buttonAdd') solid-link(class='segment sm-full button text-xsmall text-bold text-uppercase text-center reversed color-secondary bordered icon icon-pencil' next=`${component.route}-edit` bind-resources data-trans='circle.profile.buttonAdd')
solid-widget(name=`hubl-circle-leave-button-${uniq}`) solid-widget(name=`hubl-circle-leave-button-${component.uniq}`)
template template
solid-ac-checker(no-permission='acl:Delete', data-src="${src}", nested-field="circle") solid-ac-checker(permission='acl:Delete', data-src="${src}")
solid-delete( solid-ac-checker(no-permission='acl:Delete', data-src="${src}", nested-field='circle')
class='button text-xsmall text-bold text-uppercase color-secondary bordered' solid-delete(
data-src="${src}" class='button text-xsmall text-bold text-uppercase color-secondary bordered'
data-label='' data-src="${src}"
data-trans='data-label=circle.profile.buttonQuit' data-label=''
next=`${component.route}-left` data-trans='data-label=circle.profile.buttonQuit'
) next=`${component.route}-left`
)
.segment.full.text-right.margin-bottom-large.sm-margin-bottom-medium .segment.full.text-right.margin-bottom-large.sm-margin-bottom-medium
solid-display.segment( solid-display.segment(
@ -62,10 +63,10 @@ div(
nested-field='members' nested-field='members'
fields='relation' fields='relation'
action-relation='relation' action-relation='relation'
widget-relation=`hubl-circle-leave-button-${uniq}` widget-relation=`hubl-circle-leave-button-${component.uniq}`
search-fields='user' search-fields='user'
search-widget-user='solid-form-hidden' search-widget-user='solid-form-hidden'
search-value-user="store://user.@id" search-value-user='store://user.@id'
empty-widget='hubl-circle-join-button' empty-widget='hubl-circle-join-button'
) )
solid-ac-checker.segment.margin-left-small(permission='acl:Delete', bind-resources) solid-ac-checker.segment.margin-left-small(permission='acl:Delete', bind-resources)
@ -112,7 +113,7 @@ div(
class-is_admin='segment tag color-primary' class-is_admin='segment tag color-primary'
multiple-user.communities multiple-user.communities
multiple-user.communities-fields="community.name" multiple-user.communities-fields='community.name'
widget-user='hubl-circle-team-contact' widget-user='hubl-circle-team-contact'
widget-user.account.picture='hubl-user-avatar' widget-user.account.picture='hubl-user-avatar'

View File

@ -18,7 +18,6 @@ div.segment.full.padding-large.sm-padding-top-small.sm-padding-right-xsmall.sm-p
data-authentication='login' data-authentication='login'
data-auto-login='true' data-auto-login='true'
data-websocket-url=component.endpoints.xmpp data-websocket-url=component.endpoints.xmpp
data-i18n='en'
bind-resources bind-resources
uniq=component.uniq uniq=component.uniq
) )

View File

@ -56,7 +56,8 @@ div.segment.full.padding-large.whitespace-normal
partial="" partial=""
submit-button='Enregistrer' submit-button=''
submit-widget="button"
next=`${component.route}-information` next=`${component.route}-information`
data-trans='label-name=project.edit.labelName;label-captain=project.edit.labelCaptain;label-customer.name=project.edit.labelCustomer;label-description=project.edit.labelDescription;label-help=project.edit.descriptionHelp;submit-button=project.edit.buttonSubmit' data-trans='label-name=project.edit.labelName;label-captain=project.edit.labelCaptain;label-customer.name=project.edit.labelCustomer;label-description=project.edit.labelDescription;label-help=project.edit.descriptionHelp;submit-button=project.edit.buttonSubmit'
@ -76,6 +77,7 @@ div.segment.full.padding-large.whitespace-normal
widget-user='solid-form-dropdown-autocompletion' widget-user='solid-form-dropdown-autocompletion'
submit-button='' submit-button=''
submit-widget="button"
data-trans='submit-button=project.edit.buttonAddMember' data-trans='submit-button=project.edit.buttonAddMember'
) )

View File

@ -11,5 +11,6 @@ if componentSet.has('circles')
widget-user.username='solid-form-hidden' widget-user.username='solid-form-hidden'
submit-button='' submit-button=''
submit-widget="button"
data-trans='submit-button=circle.profile.buttonJoin' data-trans='submit-button=circle.profile.buttonJoin'
) )