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": {
"favicon": "/images/favicon.webp",
"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.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
@ -144,6 +159,56 @@ Where:
* `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
### 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`
### 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
* [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": {
"version": "1.8.8",
"resolved": "https://registry.npmjs.org/@startinblox/hubl-styling-framework/-/hubl-styling-framework-1.8.8.tgz",
"integrity": "sha512-SKVRUV95f45qIGSgpIMvgbQaZ6mPNNCXQY+6LlU18lGMvq0vwQ3AmOuTkp4VbfUWvSLYXTUE1N61YmIFikMIfw=="
"version": "1.8.10",
"resolved": "https://registry.npmjs.org/@startinblox/hubl-styling-framework/-/hubl-styling-framework-1.8.10.tgz",
"integrity": "sha512-3mT3H9Wgrgvja0JVu9TLEuvz1OtTeiN0UHuZx5IPLFDk5njGoDldElFEr3nw+BOMY1nJzSb8kHqW5cyIsP80cQ=="
},
"@types/q": {
"version": "1.5.4",

View File

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

View File

@ -1,5 +1,5 @@
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 (returnFirst) {
return availables[0].route;

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import {
widgetFactory,
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';
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="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));
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)
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)
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)
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="/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)
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)
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)
//- Disabled - Not in core@0.15
//- 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("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="/lib/solid-resource/solid-resource.js" defer)
if componentSet.has("themeChecker")
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')
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.
```
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.
-
let routes = new Set();
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(returnFirst) {
return availables[0].route;
@ -52,5 +53,12 @@ for component of components
routes.add(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

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-status.js" defer)
script(type="module" src="/components/hubl-reactivity.js" defer)
script(src="index.js" defer)
include dependencies.pug
include context.pug
@ -40,7 +41,6 @@ html(lang="en")
//- swal2 does not work with skypack
script(src="https://cdn.jsdelivr.net/npm/sweetalert2@10" defer)
script(src="index.js" defer)
body.bg-color-grey
@ -196,6 +196,19 @@ html(lang="en")
span(data-trans="errors.somethingGoesWrong")
span  
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(
id="swal-content-text"

View File

@ -242,5 +242,59 @@
"errors": {
"somethingGoesWrong": "Something goes wrong, try to",
"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": {
"somethingGoesWrong": "Algo sale mal, intenta",
"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": {
"somethingGoesWrong": "Quelque chose ne va pas, essayez de",
"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() {
this.locale = ""; //Current locale
this.locales = new Array(); //Available locales
this.defaultLocale = "fr";
}
/*
Method for automatically detecting the language, does not work in every browser.
*/
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)) {
this.fetchLocale(this.defaultLocale);
this.setLocale(localStorage.getItem('language') || window.navigator.language.slice(0, 2));
} else {
console.error('Language not found');
this.setLocale('fr');
this.setLocale(this.defaultLocale);
}
};
@ -105,38 +137,36 @@ class JsI18n {
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.
*/
setLocale(locale) {
try {
fetch(`/locales/${locale}.json`).then((result) => {
if (result.ok) {
result.json().then(e => {
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.fetchLocale(locale).then(() => {
if(this.locale) {
localStorage.setItem('language', this.locale);
}
this.processPage();
this.locale = locale;
});
this.locale = locale;
} catch {
if (locale != "fr") {
console.warn(`Locale not found: ${locale}, fallback to french`);
this.setLocale("fr");
if (locale != this.defaultLocale) {
console.warn(`Locale not found: ${locale}, fallback to ${this.defaultLocale}`);
this.setLocale(this.defaultLocale);
} else {
console.error("Language not found");
}
@ -148,12 +178,22 @@ class JsI18n {
*/
t(key) {
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);
if (typeof translation == "string") {
return translation;
} 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;
@ -176,21 +216,20 @@ class JsI18n {
}
//Global
jsI18n = new JsI18n;
window.hubl.intl = new JsI18n;
document.addEventListener("DOMContentLoaded", () => {
// Detect the lang & initialize, based on the browser or "language" item from localstorage
jsI18n.detectLanguage();
window.hubl.intl.detectLanguage();
let timer;
(new MutationObserver((mutations) => {
mutations.forEach(mutation => {
if (mutation.target.attributes["data-trans"] != null) {
// 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
clearTimeout(timer);
timer = setTimeout(() => jsI18n.processNode(document.querySelector('body')), 500);
timer = setTimeout(() => window.hubl.intl.processNode(document.querySelector('body')), 500);
}
});
}).observe(document.body, {
@ -198,9 +237,9 @@ document.addEventListener("DOMContentLoaded", () => {
childList: true
}));
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
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(
new CustomEvent('requestNavigation', {
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,
hubl-input-type-password,
solid-form-password,
hubl-input-type-email {
color: #5D7393;
}
@ -76,7 +76,7 @@
text-align: left;
}
input[type="submit"] {
[type="submit"] {
float: initial !important;
}
}

View File

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

View File

@ -106,8 +106,10 @@ hubl-create-contact {
/* 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 {
input,
button {
padding: 9px 20px;
border-radius: 16.5px;
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-auto-login='true'
data-websocket-url=component.endpoints.xmpp
data-i18n='en'
bind-resources
uniq=component.uniq
)

View File

@ -58,15 +58,6 @@
class-logo='community-logo'
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')
template
label ${label}
@ -88,7 +79,7 @@
widget-user.first_name='solid-form-text-label'
widget-user.last_name='solid-form-text-label'
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'
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'
@ -98,10 +89,11 @@
required-user.last_name
required-user.email
required-user.password
pattern-user.first_name='.+'
pattern-user.last_name='.+'
minlength-user.first_name='1'
minlength-user.last_name='1'
value-user.username='generate-an-username'
submit-button=''
submit-widget="button"
id='user-creation-form'
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)}`
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'
)

View File

@ -10,10 +10,11 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
id="admin-community-filter"
fields='cell1'
label-cell1=''
data-trans='label-cell1=communities.searchBy'
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"
submit-button="GO"
submit-button=""
submit-widget="button"
data-trans='label-cell1=communities.searchBy;submit-button=goButton'
)
.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)
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'
)

View File

@ -24,10 +24,11 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac
id="admin-circle-filter"
fields='name'
label-name=''
data-trans='label-name=circle.list.searchBy'
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"
submit-button="GO"
submit-button=""
submit-widget="button"
data-trans='label-name=circle.list.searchBy;submit-button=goButton'
)
.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.tableHeader3')
solid-widget(name=`leave-circle-reactivity-${component.uniq}`)
solid-widget(name=`leave-circle-reactivity`)
template
hubl-reactivity(data-src=`${getComponent('circles').endpoints.get}` 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(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
solid-delete(
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(
data-src="${src}"
fields="circle"
widget-circle=`leave-circle-reactivity-${component.uniq}`
widget-circle=`leave-circle-reactivity`
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'
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'
action-counter="counter"
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"
)
solid-widget(name=`hubl-admin-circle-join-button-${component.uniq}`)
solid-widget(name=`hubl-admin-circle-join-button`)
template
solid-form(
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'
submit-button=''
submit-widget="button"
data-trans='submit-button=circle.list.buttonJoin'
)
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'
widget-owner='hubl-circle-owner'
widget-members=`hubl-admin-circle-join-button-${component.uniq}`
widget-members=`hubl-admin-circle-join-button`
action-counter="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'
submit-button=''
submit-widget="button"
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'

View File

@ -18,10 +18,11 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
id="admin-project-filter"
fields='cell1'
label-cell1=''
data-trans='label-cell1=project.list.searchBy'
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"
submit-button="GO"
submit-button=""
submit-widget="button"
data-trans='label-cell1=project.list.searchBy;submit-button=goButton'
)
.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.tableHeader4')
solid-widget(name=`leave-project-reactivity-${component.uniq}`)
solid-widget(name=`leave-project-reactivity`)
template
hubl-reactivity(data-src=`${getComponent('projects').endpoints.get}` 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(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
solid-delete(
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(
data-src="${src}"
fields="project"
widget-project=`leave-project-reactivity-${component.uniq}`
widget-project=`leave-project-reactivity`
hidden
)
@ -88,7 +89,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac
class-project.name='segment full'
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.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"
)
solid-widget(name=`hubl-admin-project-join-button-${component.uniq}`)
solid-widget(name=`hubl-admin-project-join-button`)
template
solid-form(
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'
submit-button=''
submit-widget="button"
data-trans='submit-button=project.list.buttonJoin'
)
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'
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-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-auto-login='true'
data-websocket-url=component.endpoints.xmpp
data-i18n='en'
bind-resources
uniq=component.uniq
)

View File

@ -53,7 +53,8 @@ div.segment.full.padding-large.whitespace-normal
partial=''
submit-button='Enregistrer'
submit-button=''
submit-widget="button"
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'
@ -72,6 +73,7 @@ div.segment.full.padding-large.whitespace-normal
widget-user='solid-form-dropdown-autocompletion'
submit-button=''
submit-widget="button"
data-trans='submit-button=circle.edit.buttonAddMember'
)

View File

@ -18,7 +18,7 @@ div(
class-name='text-color-heading text-bold'
class-dash='text-color-heading text-bold'
)
div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-xlarge
div.loader(id=`loader-${component.route}-profile-1`)
div
@ -45,16 +45,17 @@ div(
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-widget(name=`hubl-circle-leave-button-${uniq}`)
solid-widget(name=`hubl-circle-leave-button-${component.uniq}`)
template
solid-ac-checker(no-permission='acl:Delete', data-src="${src}", nested-field="circle")
solid-delete(
class='button text-xsmall text-bold text-uppercase color-secondary bordered'
data-src="${src}"
data-label=''
data-trans='data-label=circle.profile.buttonQuit'
next=`${component.route}-left`
)
solid-ac-checker(permission='acl:Delete', data-src="${src}")
solid-ac-checker(no-permission='acl:Delete', data-src="${src}", nested-field='circle')
solid-delete(
class='button text-xsmall text-bold text-uppercase color-secondary bordered'
data-src="${src}"
data-label=''
data-trans='data-label=circle.profile.buttonQuit'
next=`${component.route}-left`
)
.segment.full.text-right.margin-bottom-large.sm-margin-bottom-medium
solid-display.segment(
@ -62,10 +63,10 @@ div(
nested-field='members'
fields='relation'
action-relation='relation'
widget-relation=`hubl-circle-leave-button-${uniq}`
widget-relation=`hubl-circle-leave-button-${component.uniq}`
search-fields='user'
search-widget-user='solid-form-hidden'
search-value-user="store://user.@id"
search-value-user='store://user.@id'
empty-widget='hubl-circle-join-button'
)
solid-ac-checker.segment.margin-left-small(permission='acl:Delete', bind-resources)
@ -76,9 +77,9 @@ div(
data-trans='data-label=circle.profile.buttonDelete'
next=`admin-${component.route}`
)
h3.text-color-heading.text-bold.text-letter-spacing-large(data-trans='circle.profile.description')
solid-display.segment.block.sm-hidden.whitespace-normal(
bind-resources
fields='description'
@ -112,7 +113,7 @@ div(
class-is_admin='segment tag color-primary'
multiple-user.communities
multiple-user.communities-fields="community.name"
multiple-user.communities-fields='community.name'
widget-user='hubl-circle-team-contact'
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-auto-login='true'
data-websocket-url=component.endpoints.xmpp
data-i18n='en'
bind-resources
uniq=component.uniq
)

View File

@ -56,7 +56,8 @@ div.segment.full.padding-large.whitespace-normal
partial=""
submit-button='Enregistrer'
submit-button=''
submit-widget="button"
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'
@ -76,6 +77,7 @@ div.segment.full.padding-large.whitespace-normal
widget-user='solid-form-dropdown-autocompletion'
submit-button=''
submit-widget="button"
data-trans='submit-button=project.edit.buttonAddMember'
)

View File

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