diff --git a/src/locales/en.json b/src/locales/en.json index 2a8252b..a97448f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -68,7 +68,7 @@ "create": { "backlink": "Back", "title": " Create a circle", - "labelStatus": "Statut du circle", + "labelStatus": "Circle status", "labelName": "Circle name *", "labelSubtitle": "Circle headline *", "labelDescription": "Circle description", @@ -100,7 +100,8 @@ "tableHeader2": "Admins", "tableHeader3": "Join", "buttonQuit": "Leave", - "buttonJoin": "Join" + "buttonJoin": "Join", + "searchBy": "Find a circle by name" }, "left": { "paragraphQuit": "You left this circle.", @@ -126,7 +127,8 @@ "noPermission": "Member, no permission", "subTitle": "Communities", "tableHeader1": "Name", - "tableHeader2": "Action" + "tableHeader2": "Action", + "searchBy": "Find a community by name" }, "project": { "menuRight": { @@ -142,7 +144,6 @@ "labelDescription": "Poject description", "descriptionHelp": "You can use markdown", "labelCustomer": "Customer name*", - "labelDescription": "Description", "labelCaptain": "Project captain*", "buttonSubmit": "Save" }, @@ -175,7 +176,8 @@ "tableHeader3": "Captains", "tableHeader4": "Join", "buttonQuit": "Leave", - "buttonJoin":"Join" + "buttonJoin":"Join", + "searchBy": "Find a project by name" }, "left": { "paragraphQuit": "You left this project.", diff --git a/src/locales/es.json b/src/locales/es.json index 86f3959..678913d 100644 --- a/src/locales/es.json +++ b/src/locales/es.json @@ -100,7 +100,8 @@ "tableHeader2": "Administradorxs", "tableHeader3": "Unirse", "buttonQuit": "Salir", - "buttonJoin": "Unirse" + "buttonJoin": "Unirse", + "searchBy": "Busca un círculo por nombre " }, "left": { "paragraphQuit": "Dejaste este círculo.", @@ -126,7 +127,8 @@ "noPermission": "Miembrx sin permiso", "subTitle": "Comunidades", "tableHeader1": "Nombre", - "tableHeader2": "Acción" + "tableHeader2": "Acción", + "searchBy": "Encuentra una comunidad por nombre " }, "project": { "menuRight": { @@ -142,7 +144,6 @@ "labelDescription": "Descripción del proyecto", "descriptionHelp": "Puedes usar markdown", "labelCustomer": "Nombre del/la clientx *", - "labelDescription": "Description", "labelCaptain": "Líder del proyecto *", "buttonSubmit": "Guardar" }, @@ -175,7 +176,8 @@ "tableHeader3": "Líderes", "tableHeader4": "Unirse", "buttonQuit": "Salir", - "buttonJoin": "Unirse" + "buttonJoin": "Unirse", + "searchBy": "Buscar un proyecto por nombre " }, "left": { "paragraphQuit": "Dejaste este proyecto.", diff --git a/src/locales/fr.json b/src/locales/fr.json index b7bbdee..f24ed52 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -101,7 +101,8 @@ "tableHeader2": "Administrateurs", "tableHeader3": "Rejoindre", "buttonQuit": "Quitter", - "buttonJoin": "Rejoindre" + "buttonJoin": "Rejoindre", + "searchBy": "Rechercher un cercle par nom" }, "left": { "paragraphQuit": "Tu as quitté ce cercle.", @@ -127,7 +128,8 @@ "noPermission": "Membre, aucune permission", "subTitle": "Communautés", "tableHeader1": "Nom", - "tableHeader2": "Action" + "tableHeader2": "Action", + "searchBy": "Rechercher une communauté par nom" }, "project": { "menuRight": { @@ -143,7 +145,6 @@ "labelDescription": "Description du projet", "descriptionHelp": "Vous pouvez utiliser Markdown", "labelCustomer": "Nom du client*", - "labelDescription": "Description", "labelCaptain": "Capitaine du projet*", "buttonSubmit": "Enregistrer" }, @@ -176,7 +177,8 @@ "tableHeader3": "Capitaines", "tableHeader4": "Rejoindre", "buttonQuit": "Quitter", - "buttonJoin":"Rejoindre" + "buttonJoin":"Rejoindre", + "searchBy": "Rechercher un projet par nom" }, "left": { "paragraphQuit": "Tu as quitté ce projet.", diff --git a/src/scripts/intl.js b/src/scripts/intl.js index e607b94..30ea140 100644 --- a/src/scripts/intl.js +++ b/src/scripts/intl.js @@ -39,12 +39,18 @@ class JsI18n { if (attr == "html") { this.translateNodeContent(node, k); } else { - if(node.tagName == "SOLID-DELETE") { + if (node.tagName == "SOLID-DELETE") { let button = node.querySelector('button'); - if(button != null) { + if (button != null) { this.translateNodeContent(button, k); } } + if (attr.startsWith('label-')) { + let label = node.querySelector('[name="'+attr.replace("label-", "")+'"] > label'); + if(label != null) { + this.translateNodeContent(label, k); + } + } this.translateNodeContent(node.attributes[attr], k); } } @@ -60,12 +66,15 @@ class JsI18n { if (node != null && translation != undefined) { if (node.nodeType == 1) { //Element try { - node.innerHTML = translation; + if(node.innerHTML != translation) + node.innerHTML = translation; } catch (e) { - node.text = translation; + if(node.text != translation) + node.text = translation; } } else if (node.nodeType == 2) { //Attribute - node.value = translation; + if(node.value != translation) + node.value = translation; } } } @@ -120,12 +129,12 @@ class JsI18n { } }); } else { - if (locale != "fr") { - console.warn(`Locale not found: ${locale}, fallback to french`); - this.setLocale("fr"); - } else { - console.error("Language not found"); - } + if (locale != "fr") { + console.warn(`Locale not found: ${locale}, fallback to french`); + this.setLocale("fr"); + } else { + console.error("Language not found"); + } } }); this.locale = locale; @@ -146,7 +155,7 @@ class JsI18n { var translations = this.locales[this.locale]; if (translations != undefined) { let translation = key.toString().split('.').reduce((o, i) => (o ? o[i] : undefined), translations); - if(typeof translation == "string") { + if (typeof translation == "string") { return translation; } else { return translations[key.toString()]; @@ -178,25 +187,17 @@ document.addEventListener("DOMContentLoaded", () => { // Detect the lang & initialize, based on the browser or "language" item from localstorage jsI18n.detectLanguage(); - - /* - recursivePopulate(DOMElement) - Will listen for the populate event of any sib element - Process the changed node every time it populate - Recursively add a populate listener for children elements - */ - function recursivePopulate(element) { - Array.from(element.querySelectorAll('*')).forEach((e) => { - if(e.content && e.content instanceof DocumentFragment) { - recursivePopulate(e.content); - } else if(e instanceof HTMLElement) { - e.addEventListener("populate", (el) => { - recursivePopulate(el.target); - jsI18n.processNode(el.target); - }); + (new MutationObserver((mutations) => { + mutations.forEach(mutation => { + if(mutation.target.attributes["data-trans"] != null) { + // Render the target of the mutation instantly + jsI18n.processNode(mutation.target); + // Then wait one arbitrary second to re-render the whole document in case a widget re-rendered + setTimeout(() => jsI18n.processNode(document.querySelector('body')), 1000); } }); - } - // Process every children from document - recursivePopulate(document); + }).observe(document.body, { + subtree: true, + childList: true + })); }); \ No newline at end of file diff --git a/src/views/partials/admin/page-admin-circles.pug b/src/views/partials/admin/page-admin-circles.pug index 02eea1c..6e40bc8 100644 --- a/src/views/partials/admin/page-admin-circles.pug +++ b/src/views/partials/admin/page-admin-circles.pug @@ -83,6 +83,15 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac widget-name='admin-circle-link' ) + solid-form-search.form( + 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 half sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading" + ) + .segment.table-wrapper .table @@ -122,9 +131,10 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac solid-display( class='table-body' + filtered-by="admin-circle-filter" bind-user nested-field='circles' - fields='cell1(circle.name, counter, circle.subtitle), cell2(circle.owner), cell3(leaveButton)' + fields='cell1(name(circle.name), counter, circle.subtitle), cell2(circle.owner), cell3(leaveButton)' loader-id='loader-admin-circles' class-cell1='segment table-cell third whitespace-normal' @@ -154,7 +164,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac value-user.username='hubl-workaround-493' widget-user.username='solid-form-hidden' - submit-button='Join' + submit-button='' data-trans='submit-button=circle.list.buttonJoin' ) hubl-reactivity(data-src=`${endpoints.get.circles}` target-src='${value}') @@ -165,6 +175,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-normal.whitespac solid-display( class='table-body' + filtered-by="admin-circle-filter" data-src=`${endpoints.circles || endpoints.get.circles}joinable/` fields='cell1(name, counter, subtitle), cell2(owner), cell3(members)' diff --git a/src/views/partials/admin/page-admin-communities.pug b/src/views/partials/admin/page-admin-communities.pug index 06fa213..f5e1733 100644 --- a/src/views/partials/admin/page-admin-communities.pug +++ b/src/views/partials/admin/page-admin-communities.pug @@ -29,6 +29,15 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac ) span.icon.icon-people.icon-xsmall.margin-right-xxsmall + solid-form-search.form( + 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 half sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading" + ) + .segment.table-wrapper .table div.table-header.bg-color-third.text-color-heading @@ -37,6 +46,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac solid-display( class='table-body' + filtered-by='admin-community-filter' bind-user nested-field='communities' fields='cell1(community.name, counter), cell2(community)' diff --git a/src/views/partials/admin/page-admin-projects.pug b/src/views/partials/admin/page-admin-projects.pug index 1ff4c57..a098d2b 100644 --- a/src/views/partials/admin/page-admin-projects.pug +++ b/src/views/partials/admin/page-admin-projects.pug @@ -58,6 +58,15 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac widget-name='admin-project-link' ) + solid-form-search.form( + 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 half sm-full padding-right-small sm-padding-none text-small text-semibold text-uppercase text-color-heading" + ) + .segment.table-wrapper .table @@ -132,6 +141,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac solid-display( class='table-body' + filtered-by="admin-project-filter" bind-user nested-field="projects" @@ -180,6 +190,7 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac solid-display( class='table-body' + filtered-by="admin-project-filter" data-src=`${endpoints.projects || endpoints.get.projects}joinable/` fields='cell1(customer.name, counter, name), cell2(members), cell3(captain), cell4(joinButton)' diff --git a/src/views/partials/admin/page-admin-users-create.pug b/src/views/partials/admin/page-admin-users-create.pug index ebd20a7..ecc00e5 100644 --- a/src/views/partials/admin/page-admin-users-create.pug +++ b/src/views/partials/admin/page-admin-users-create.pug @@ -20,14 +20,14 @@ div.segment.full.padding-large.sm-padding-xsmall.sm-padding-top-medium.whitespac solid-widget(name='hubl-username-field') template - label(data-trans='user.create.labelUsername') - input(type="text" title='' pattern="[a-zA-Z0-9]+" label="" data-trans='title=user.create.labelUsernameTitle;label=user.create.labelUsername' name="username" required value="\${value}" data-holder) + label ${label} + input(type="text" title='' pattern="[a-zA-Z0-9]+" label="${label}" data-trans='title=user.create.labelUsernameTitle' name="username" required value="\${value}" data-holder) solid-widget(name='hubl-email-field') template div.segment.margin-bottom-medium.half.sm-full.padding-left-small.sm-padding-none.text-small.text-semibold.text-uppercase.text-color-heading - label(data-trans='user.create.labelEmail') - input(type="email" label='' data-trans='label=user.create.labelEmail' name="email" required value="\${value}" data-holder) + label ${label} + input(type="email" label='${label}' name="email" required value="\${value}" data-holder) div.segment.margin-bottom-medium div.segment