From c947d499c8d944340054e526c25d78dc5a121406 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 17 Mar 2021 12:11:22 +0000 Subject: [PATCH 01/24] Bump @testing-library/user-event from 12.8.3 to 13.0.1 in /frontend Bumps [@testing-library/user-event](https://github.com/testing-library/user-event) from 12.8.3 to 13.0.1. - [Release notes](https://github.com/testing-library/user-event/releases) - [Changelog](https://github.com/testing-library/user-event/blob/master/CHANGELOG.md) - [Commits](https://github.com/testing-library/user-event/compare/v12.8.3...v13.0.1) Signed-off-by: dependabot-preview[bot] --- frontend/package.json | 2 +- frontend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 744399c51f..7e1926dd1d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -107,7 +107,7 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.4", "@testing-library/react-hooks": "^5.1.0", - "@testing-library/user-event": "^12.8.3", + "@testing-library/user-event": "^13.0.1", "combine-react-intl-messages": "^4.0.0", "jest-canvas-mock": "^2.3.1", "msw": "^0.27.1", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 5be9da36d1..946baf6f73 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3158,10 +3158,10 @@ "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" -"@testing-library/user-event@^12.8.3": - version "12.8.3" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-12.8.3.tgz#1aa3ed4b9f79340a1e1836bc7f57c501e838704a" - integrity sha512-IR0iWbFkgd56Bu5ZI/ej8yQwrkCv8Qydx6RzwbKz9faXazR/+5tvYKsZQgyXJiwgpcva127YO6JcWy7YlCfofQ== +"@testing-library/user-event@^13.0.1": + version "13.0.1" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.1.tgz#a1c0727ca3eefa6f9bd0ccce98d02770e6446e8f" + integrity sha512-7n3Y5Vohib6yVFW60JlCvQOqBDIlE1SRyo78nmoHwePAg3SVhnfyOI30RYNj3yFF7qy7e0uVlewzTyvNxyJjEA== dependencies: "@babel/runtime" "^7.12.5" From fc4f1bee9c9457044ce0f3dba9cbaff27de4a212 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 18 Mar 2021 14:06:32 +0000 Subject: [PATCH 02/24] Bump @testing-library/user-event from 13.0.1 to 13.0.2 in /frontend Bumps [@testing-library/user-event](https://github.com/testing-library/user-event) from 13.0.1 to 13.0.2. - [Release notes](https://github.com/testing-library/user-event/releases) - [Changelog](https://github.com/testing-library/user-event/blob/master/CHANGELOG.md) - [Commits](https://github.com/testing-library/user-event/compare/v13.0.1...v13.0.2) Signed-off-by: dependabot-preview[bot] --- frontend/package.json | 2 +- frontend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 7e1926dd1d..0d46a17efa 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -107,7 +107,7 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.4", "@testing-library/react-hooks": "^5.1.0", - "@testing-library/user-event": "^13.0.1", + "@testing-library/user-event": "^13.0.2", "combine-react-intl-messages": "^4.0.0", "jest-canvas-mock": "^2.3.1", "msw": "^0.27.1", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 946baf6f73..276c6224ae 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3158,10 +3158,10 @@ "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" -"@testing-library/user-event@^13.0.1": - version "13.0.1" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.1.tgz#a1c0727ca3eefa6f9bd0ccce98d02770e6446e8f" - integrity sha512-7n3Y5Vohib6yVFW60JlCvQOqBDIlE1SRyo78nmoHwePAg3SVhnfyOI30RYNj3yFF7qy7e0uVlewzTyvNxyJjEA== +"@testing-library/user-event@^13.0.2": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.2.tgz#f629bfd44fb09c9e3b18e048076b397e6e97952d" + integrity sha512-OYlNDcoqNZJhQvP5tsNM4/i27XIyA5DMi8xMwAJ0VLGW5BqjsSrYtL29WvHEdHu+cI6wo6UMHy6atdwtTNVUiw== dependencies: "@babel/runtime" "^7.12.5" From 33e5b1408b931f7facb71421cbde8352be8bfac8 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Wed, 17 Mar 2021 09:57:54 -0300 Subject: [PATCH 03/24] Fix link on fallback component and improve style of contact form. --- frontend/src/components/homepage/contactForm.js | 6 +++--- frontend/src/views/contact.js | 4 ++-- frontend/src/views/fallback.js | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/src/components/homepage/contactForm.js b/frontend/src/components/homepage/contactForm.js index 7a2353a50f..f50eefcf16 100644 --- a/frontend/src/components/homepage/contactForm.js +++ b/frontend/src/components/homepage/contactForm.js @@ -4,13 +4,13 @@ import { Form, Field } from 'react-final-form'; import messages from './messages'; import { FormSubmitButton } from '../button'; -export const ContactForm = props => { +export const ContactForm = (props) => { const labelClasses = 'db pt3 pb2'; const fieldClasses = 'blue-grey w-100 pv3 ph2 input-reset ba b--grey-light bg-transparent'; return (
props.submitMessage(values)} + onSubmit={(values) => props.submitMessage(values)} initialValues={props.contactUsValues} render={({ handleSubmit, pristine, form, submitting, values }) => { return ( @@ -19,7 +19,7 @@ export const ContactForm = props => {

-
+
diff --git a/frontend/src/views/contact.js b/frontend/src/views/contact.js index c30963d088..02e3517031 100644 --- a/frontend/src/views/contact.js +++ b/frontend/src/views/contact.js @@ -77,8 +77,8 @@ export const ContactPage = (props) => { return (
} /> -
-
+
+
{popups}
diff --git a/frontend/src/views/fallback.js b/frontend/src/views/fallback.js index 1ea5642e22..dc8370a6fc 100644 --- a/frontend/src/views/fallback.js +++ b/frontend/src/views/fallback.js @@ -1,5 +1,5 @@ import React from 'react'; -import { navigate } from '@reach/router'; +import { navigate, Link } from '@reach/router'; import { FormattedMessage } from 'react-intl'; import messages from './messages'; @@ -17,11 +17,11 @@ export const FallbackComponent = (props) => {

- + - + From adfafe8fa2992a3e628d24bcda49eac6e8a622e2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 19 Mar 2021 12:08:59 +0000 Subject: [PATCH 04/24] Bump @testing-library/user-event from 13.0.2 to 13.0.3 in /frontend Bumps [@testing-library/user-event](https://github.com/testing-library/user-event) from 13.0.2 to 13.0.3. - [Release notes](https://github.com/testing-library/user-event/releases) - [Changelog](https://github.com/testing-library/user-event/blob/master/CHANGELOG.md) - [Commits](https://github.com/testing-library/user-event/compare/v13.0.2...v13.0.3) Signed-off-by: dependabot-preview[bot] --- frontend/package.json | 2 +- frontend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 0d46a17efa..d828cf8f99 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -107,7 +107,7 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.4", "@testing-library/react-hooks": "^5.1.0", - "@testing-library/user-event": "^13.0.2", + "@testing-library/user-event": "^13.0.3", "combine-react-intl-messages": "^4.0.0", "jest-canvas-mock": "^2.3.1", "msw": "^0.27.1", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 276c6224ae..78d6f7bd64 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3158,10 +3158,10 @@ "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" -"@testing-library/user-event@^13.0.2": - version "13.0.2" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.2.tgz#f629bfd44fb09c9e3b18e048076b397e6e97952d" - integrity sha512-OYlNDcoqNZJhQvP5tsNM4/i27XIyA5DMi8xMwAJ0VLGW5BqjsSrYtL29WvHEdHu+cI6wo6UMHy6atdwtTNVUiw== +"@testing-library/user-event@^13.0.3": + version "13.0.3" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.3.tgz#14f1d2a117f13529ea31ce6f7414b003c76f17e1" + integrity sha512-q9CAkTO+fV6dskQRttxsFVAzqMIhOVN0H0dSEssL5oz1H7QY7cMfQ/KPOt57lgXXPVRJ1pzGlKQotZ27E+PgvA== dependencies: "@babel/runtime" "^7.12.5" From 53182b5f86599e0be89f4a3b26b9d4709f6b9807 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Mon, 22 Mar 2021 11:20:16 -0300 Subject: [PATCH 05/24] Update translations and frontend dependencies --- frontend/package.json | 8 +-- frontend/src/locales/cs.json | 26 +++---- frontend/src/locales/it.json | 90 ++++++++++++------------ frontend/src/locales/nl_NL.json | 20 +++--- frontend/src/locales/uk.json | 44 ++++++------ frontend/yarn.lock | 120 ++++++++++++++++---------------- 6 files changed, 154 insertions(+), 154 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index d828cf8f99..02eb267371 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,8 +17,8 @@ "@mapbox/mapbox-gl-language": "^0.10.1", "@mapbox/togeojson": "^0.16.0", "@reach/router": "^1.3.4", - "@sentry/react": "^6.2.2", - "@sentry/tracing": "^6.2.2", + "@sentry/react": "^6.2.3", + "@sentry/tracing": "^6.2.3", "@turf/area": "^6.3.0", "@turf/bbox": "^6.3.0", "@turf/bbox-polygon": "^6.3.0", @@ -50,7 +50,7 @@ "react-datepicker": "^3.6.0", "react-dom": "^17.0.1", "react-dropzone": "^11.3.1", - "react-final-form": "^6.5.2", + "react-final-form": "^6.5.3", "react-intl": "^5.13.0", "react-meta-elements": "^1.0.0", "react-placeholder": "^4.1.0", @@ -107,7 +107,7 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.4", "@testing-library/react-hooks": "^5.1.0", - "@testing-library/user-event": "^13.0.3", + "@testing-library/user-event": "^13.0.7", "combine-react-intl-messages": "^4.0.0", "jest-canvas-mock": "^2.3.1", "msw": "^0.27.1", diff --git a/frontend/src/locales/cs.json b/frontend/src/locales/cs.json index 900ccf8ae7..8e8ac388a0 100644 --- a/frontend/src/locales/cs.json +++ b/frontend/src/locales/cs.json @@ -33,7 +33,7 @@ "mytasks.unlock": "odemknuto {time}", "mytasks.tasks.title": "Úloha #{task} · Projekt #{project}", "mytasks.tasks.button.retry": "Zkusit znovu", - "mytasks.tasks.comments.number": "{number, plural, one {} few {} many {} other {}}", + "mytasks.tasks.comments.number": "{number, plural, one {# komentář} few {# komentáře} many {# komentářů} other {# komentáře}}", "deleteModal.status.processing": "Probíhá", "deleteModal.status.success": "{type} úspěšně smazán.", "deleteModal.status.failure.projects": "Nastala chyba při pokusu o smazání projektu.", @@ -244,8 +244,8 @@ "project.detail.coordination": "Koordinace", "project.detail.coordination.description": "Tento projekt je koordinován organizací {organisation} a byl vytvořen uživatelem {user}.", "project.detail.createdBy": "Projekt vytvořil {user}.", - "project.detail.contributorCount.zero": "", - "project.detail.contributorCount": "{number, plural, one {} few {} many {} other {}}", + "project.detail.contributorCount.zero": "Zatím žádní přispěvatelé", + "project.detail.contributorCount": "{number, plural, one { # přispěvatel} few { # přispěvatelé} many { # přispěvatelů} other { # přispěvatelé}}", "project.detail.lastContribution": "Poslední příspěvek", "project.detail.percentMapped": "Zmapováno", "project.detail.percentValidated": "Validováno", @@ -670,12 +670,12 @@ "management.messages.notAllowed": "Nemáte práva ke správě organizací.", "management.messages.imageUpload.error": "Nahrávání obrázku se nezdařilo.", "management.fields.managers": "Správci", - "management.fields.managers.empty": "", + "management.fields.managers.empty": "Zatím nejsou žádní manažeři.", "management.link.manage": "Spravovat {entity}", "management.link.edit.team": "Upravit tým", "management.members.edit": "Upravit", "management.members": "Členové", - "management.members.empty": "", + "management.members.empty": "Zatím nejsou žádní členové.", "management.teams.mapping": "Mapovací týmy", "management.teams.validation": "Validační týmy", "management.teams.members": "Členové týmu", @@ -683,7 +683,7 @@ "management.teams.members.send_message.button": "Poslat", "management.teams.members.send_message.subject": "Předmět", "management.teams.join_requests": "Žádosti o připojení", - "management.teams.join_requests.empty": "", + "management.teams.join_requests.empty": "Nejsou žádné žádosti o vstup do týmu.", "management.teams": "Týmy", "management.team": "Tým", "management.projects": "Projekty", @@ -709,7 +709,7 @@ "management.organisations.type": "Typ", "management.organisations.publicUrl": "Veřejné URL", "management.organisations.publicUrl.copy": "Kopírovat veřejné URL", - "management.organisations.tier.select": "", + "management.organisations.tier.select": "Vybrat úroveň", "management.organisations.type.select": "Vybrat typ", "management.organisations.type.free": "Zdarma", "management.organisations.type.discounted": "Zlevněné", @@ -726,7 +726,7 @@ "management.organisations.stats.actions_needed": "Potřebná opatření", "management.organisations.stats.completed_actions": "Dokončené akce", "management.organisations.stats.actions_needed.help": "Akce se rozumí operace mapování nebo validování. Vzhledem k tomu, že každý úkol je třeba mapovat a ověřit, jedná se o počet akcí potřebných k dokončení všech publikovaných projektů dané organizace.", - "management.organisations.stats.tier.subscribed": "", + "management.organisations.stats.tier.subscribed": "Úroveň odebírání", "management.organisations.stats.level.tooltip": "{n} z {total} ({percent}%) dokončeno pro přechod na úroveň {nextLevel}", "management.organisations.stats.tier.tooltip": "{n} z {total} ({percent}%) dokončeno pro přesun na úroveň {nextTier}", "management.organisations.stats.level.description": "{org} je na organizační úrovni {level}.", @@ -769,8 +769,8 @@ "teamsAndOrgs.management.teams.messages.waiting_approval": "Vaše žádost o členství čeká na schválení.", "management.projects.no_found": "Tato {entity} zatím neobsahuje žádný projekt.", "management.organisation.teams.no_found": "Žádný tým nenalezen.", - "management.stats.new_users.month": "{number, plural, one {registrovaný uživatel za posledních 30 dní} few {Počet registrovaných uživatelů za posledních 30 dní} many {Počet registrovaných uživatelů za posledních 30 dní} other {Počet registrovaných uživatelů za posledních 30 dní}}", - "management.stats.new_users.week": "{number, plural, one {uživatel registrovaný za posledních 7 dní} few {Počet registrovaných uživatelů za posledních 7 dní} many {Počet registrovaných uživatelů za posledních 7 dní} other {Počet registrovaných uživatelů za posledních 7 dní}}", + "management.stats.new_users.month": "{number, plural, one {# registrovaný uživatel za posledních 30 dní} few {Počet registrovaných uživatelů za posledních 30 dní} many {Počet registrovaných uživatelů za posledních 30 dní} other {Počet registrovaných uživatelů za posledních 30 dní}}", + "management.stats.new_users.week": "{number, plural, one {# uživatel registrovaný za posledních 7 dní} few {Počet registrovaných uživatelů za posledních 7 dní} many {Počet registrovaných uživatelů za posledních 7 dní} other {Počet registrovaných uživatelů za posledních 7 dní}}", "management.stats.new_users.active": "Mapovaná alespoň jedna úloha", "management.stats.new_users.email_verified": "Potvrzená e-mailová adresa", "management.stats.title": "Statistiky", @@ -786,8 +786,8 @@ "user.gender.male": "Muž", "user.gender.preferNotToSay": "Nepřeji si uvést", "user.gender.selfDescribe": "Upřednostňuji vlastní popis:", - "user.gender.privacy": "", - "user.email.privacy": "", + "user.gender.privacy": "Vaše údaje o pohlaví budou použity pouze pro statistické účely a nebudou vystaveny jiným uživatelům.", + "user.email.privacy": "Vaše e-mailová adresa bude použita pouze k zasílání oznámení a aktualizací o Tasking Manager. Nebude sdílena s ostatními uživateli nebo organizacemi.", "user.slack": "Uživatelské jméno na {org} Slack", "user.personalInfo.error": "Zadejte pouze své uživatelské jméno, nikoli adresu URL.", "user.form.save": "Uložit", @@ -904,7 +904,7 @@ "management.managers": "Správci", "management.users.title": "Spravovat uživatele", "management.stats.users.title": "Noví uživatelé", - "management.stats.features": "", + "management.stats.features": "Celkem vlastností", "teamsAndOrgs.management.organisation.creation": "Vytvořit novou organizaci", "teamsAndOrgs.management.organisation.edit": "Úprava organizace", "teamsAndOrgs.management.team.creation": "Vytvořit nový tým", diff --git a/frontend/src/locales/it.json b/frontend/src/locales/it.json index aee359bc1c..2bb05afb6e 100644 --- a/frontend/src/locales/it.json +++ b/frontend/src/locales/it.json @@ -33,7 +33,7 @@ "mytasks.unlock": "sblocca {time}", "mytasks.tasks.title": "Compito #{task} · progetto #{project}", "mytasks.tasks.button.retry": "Riprova", - "mytasks.tasks.comments.number": "{number, plural, one {} other {}}", + "mytasks.tasks.comments.number": "{number, plural, one {# commento} other {# commenti}}", "deleteModal.status.processing": "In lavorazione", "deleteModal.status.success": "{type} eliminato con successo.", "deleteModal.status.failure.projects": "Errore durante la cancellazione del progetto.", @@ -123,11 +123,11 @@ "home.contact.submit": "Invia", "home.testimonials.title": "Tu puoi fare la differenza", "home.testimonials.ifrc.citation": "Nei primi giorni della risposta al Cyclone Idai, l'IFRC era alla ricerca di mappe dettagliate per avere un'idea della portata dell'inondazione, mappe che sono state poi utilizzate anche per le operazioni di ricerca e salvataggio. In seguito abbiamo avuto richieste di identificare dove si trovavano alcuni edifici, come centri sanitari o ospedali, in modo che il nostro team sanitario potesse valutare i danni e le esigenze mediche dei pazienti.", - "home.testimonials.ifrc.bio": "Coordinatore a distanza per il team di gestione delle informazioni dell'IFRC per il ciclone Idai", + "home.testimonials.ifrc.bio": "Coordinatore a distanza per il gruppo di gestione delle informazioni dell'IFRC per il ciclone Idai", "localeSelect.language": "Lingua", "formInputs.organisation.select": "Scegli un'organizzazione", "formInputs.country.select": "Nazione", - "foooter.definition": "Tasking Manager è una piattaforma in cui i singoli possono lavorare in team per mappare in OpenStreetMap", + "foooter.definition": "Tasking Manager è una piattaforma in cui i singoli possono lavorare in gruppo per mappare in OpenStreetMap", "footer.credits": "Software libero e Open Source fornito dal team umanitario OpenStreetMap.", "footer.learn": "Scopri di più su OpenStreetMap.", "footer.privacyPolicy": "Regole sulla privacy", @@ -169,11 +169,11 @@ "notifications.refresh": "Aggiorna", "notifications.message.type.system": "Sistema", "notifications.message.type.broadcast": "Trasmissione", - "notifications.message.type.team": "Annuncio del team", + "notifications.message.type.team": "Annuncio del gruppo", "notifications.message.type.mention_notification": "Menzione", "notifications.message.type.validation_notification": "Validazione", "notifications.message.type.invalidation_notification": "Annullamento", - "notifications.message.type.request_team_notification": "Richiesta team", + "notifications.message.type.request_team_notification": "Richiesta gruppo", "notifications.message.type.invitation_notification": "Invito", "notifications.message.type.task_comment_notification": "Commento al compito", "notifications.message.type.project_chat_notification": "Chat di progetto", @@ -195,7 +195,7 @@ "project.card.edit_project.button": "Modifica", "project.card.project_page.button": "Pagina del progetto", "project.card.project_tasks.button": "Compiti", - "management.projects.create.title": "", + "management.projects.create.title": "Crea nuovo progetto", "management.projects.clone.message": "Il nuovo progetto sarà un clone del progetto #{id} ({name}).", "management.projects.create.clone": "Clona", "management.projects.create.area_size": "Dimensioni dell'area: {area} km{sq}", @@ -244,8 +244,8 @@ "project.detail.coordination": "Coordinamento", "project.detail.coordination.description": "Questo progetto è coordinato da {organisation} ed è stato creato da {user}.", "project.detail.createdBy": "Progetto creato da {user}.", - "project.detail.contributorCount.zero": "", - "project.detail.contributorCount": "{number, plural, one {} other {}}", + "project.detail.contributorCount.zero": "Ancora nessun contributore", + "project.detail.contributorCount": "{number, plural, one {# contributore} other {# contributori}}", "project.detail.lastContribution": "Ultimo contributo", "project.detail.percentMapped": "Mappato", "project.detail.percentValidated": "Validato", @@ -278,7 +278,7 @@ "project.detail.author": "Autore", "project.detail.mapping_permissions": "Chi può mappare?", "project.detail.validation_permissions": "Chi può validare?", - "project.detail.zoomToTasks": "Ingradisci ai compiti", + "project.detail.zoomToTasks": "Ingrandisci ai compiti", "project.detail.cards.selectATask.title": "1. Compito selezionato", "project.detail.cards.mapthroughosm.title": "2. Mappa con OpenStreetMap", "project.detail.cards.submityourwork.title": "3. Invia il tuo lavoro", @@ -323,7 +323,7 @@ "projects.formInputs.permissions.any": "Qualsiasi utente", "projects.formInputs.permissions.level": "Solo utenti con livello intermedio o avanzato", "projects.formInputs.permissions.teams": "Solo membri del gruppo", - "projects.formInputs.permissions.teamsAndLevel": "Solo membri del team di livello intermedio o avanzato", + "projects.formInputs.permissions.teamsAndLevel": "Solo membri del gruppo di livello intermedio o avanzato", "projects.formInputs.permissions.mapping.description": "Definisci quali utenti possono mappare questo progetto.", "projects.formInputs.permissions.validation.description": "Definisci quali utenti possono validare questo progetto.", "projects.formInputs.permissions.mapping.title": "Permessi di mappatura", @@ -428,8 +428,8 @@ "project.formInputs.mapper_level.options.advanced": "Esperto", "project.formInputs.mapper_level.options.intermediate": "Intermedio", "project.formInputs.mapper_level.options.beginner": "Principiante", - "project.formInputs.teams.actions.filter.organisations": "FIltra i team per organizzazione", - "project.formInputs.teams.actions.select": "Seleziona un team...", + "project.formInputs.teams.actions.filter.organisations": "Filtra i gruppi per organizzazione", + "project.formInputs.teams.actions.select": "Seleziona un gruppo…", "project.formInputs.teams.actions.select.role": "Seleziona un ruolo...", "project.formInputs.teams.actions.add": "Aggiungi", "project.formInputs.teams.actions.update": "Aggiorna", @@ -670,20 +670,20 @@ "management.messages.notAllowed": "Non è consentito gestire le organizzazioni.", "management.messages.imageUpload.error": "Caricamento dell'immagine non riuscito.", "management.fields.managers": "Dirigenti", - "management.fields.managers.empty": "", + "management.fields.managers.empty": "Non ci sono ancora gestori.", "management.link.manage": "Gestisci {entity}", - "management.link.edit.team": "Modifica team", + "management.link.edit.team": "Modifica gruppo", "management.members.edit": "Modifica", "management.members": "Membri", - "management.members.empty": "", - "management.teams.mapping": "Team dei mappatura", + "management.members.empty": "Non ci sono ancora membri.", + "management.teams.mapping": "Gruppi di mappatura", "management.teams.validation": "Gruppi di validatori", - "management.teams.members": "Membri del team", + "management.teams.members": "Membri del gruppo", "management.teams.members.send_message": "Messaggi di gruppo", "management.teams.members.send_message.button": "Invia", "management.teams.members.send_message.subject": "Oggetto", "management.teams.join_requests": "Richieste di iscrizione", - "management.teams.join_requests.empty": "", + "management.teams.join_requests.empty": "Non ci sono richieste di unirsi al gruppo.", "management.teams": "Gruppi", "management.team": "Gruppo", "management.projects": "Progetti", @@ -698,8 +698,8 @@ "management.edit_members": "Potrai aggiungere altri utenti dopo aver salvato per la prima volta.", "management.filter.buttons.myOrganisations": "Le mie organizzazioni", "management.filter.buttons.all": "Tutti", - "management.myTeams": "My gruppi", - "management.buttons.new": "", + "management.myTeams": "I miei gruppi", + "management.buttons.new": "Nuovo", "management.buttons.delete": "Cancella", "management.buttons.accept": "Accetta", "management.buttons.reject": "Rifiuta", @@ -707,14 +707,14 @@ "management.organisation": "Organizzazione", "management.organisations": "Organizzazioni", "management.organisations.type": "Tipo", - "management.organisations.publicUrl": "", - "management.organisations.publicUrl.copy": "", - "management.organisations.tier.select": "", + "management.organisations.publicUrl": "URL pubblico", + "management.organisations.publicUrl.copy": "Copia URL pubblico", + "management.organisations.tier.select": "Seleziona livello", "management.organisations.type.select": "Seleziona il tipo", "management.organisations.type.free": "Libero", "management.organisations.type.discounted": "Scontato", "management.organisations.type.defaultFee": "Tariffa predefinita", - "management.organisations.list.empty": "", + "management.organisations.list.empty": "Nessuna organizzazione trovata.", "management.organisations.stats.retry": "Riprova", "management.organisations.stats.error": "Si è verificato un errore durante il caricamento delle statistiche.", "management.organisations.stats.error.start_date": "La data di inizio non deve essere successiva alla data di fine.", @@ -726,7 +726,7 @@ "management.organisations.stats.actions_needed": "Azioni necessarie", "management.organisations.stats.completed_actions": "Azioni completate", "management.organisations.stats.actions_needed.help": "Azione indica un'operazione di mappatura o validazione. Poiché ogni compito deve essere mappato e validato, questo è il numero di azioni necessarie per completare tutti i progetti pubblicati di tale organizzazione.", - "management.organisations.stats.tier.subscribed": "", + "management.organisations.stats.tier.subscribed": "Iscritto al livello", "management.organisations.stats.level.tooltip": "{n} di {total} ({percent}%) completati per passare al livello {nextLevel}", "management.organisations.stats.tier.tooltip": "{n} di {total} ({percent}%) completato per passare al livello {nextTier}", "management.organisations.stats.level.description": "{org} è un livello di organizzazione {level}.", @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Livello stimato entro la fine di {year}", "management.organisations.stats.cost.estimation": "Costo stimato entro la fine di {year}", "management.organisations.stats.next_level.actions": "Azioni per raggiungere il livello {n}", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.next_tier.actions": "Azioni per salire al prossimo livello", "management.organisations.tier.free": "Libero", "management.organisations.tier.low": "Bassa", "management.organisations.tier.medium": "Medio", @@ -768,12 +768,12 @@ "management.teams.invite_only.description": "I manager devono approvare la richiesta di adesione di un membro.", "teamsAndOrgs.management.teams.messages.waiting_approval": "La tua richiesta di unirsi a questo gruppo è in attesa di approvazione.", "management.projects.no_found": "Questo {entity} non ha ancora progetti.", - "management.organisation.teams.no_found": "Nessuna squadra trovata.", - "management.stats.new_users.month": "{number, plural, one {} other {}}", - "management.stats.new_users.week": "{number, plural, one {} other {}}", - "management.stats.new_users.active": "", - "management.stats.new_users.email_verified": "", - "management.stats.title": "", + "management.organisation.teams.no_found": "Nessun gruppo trovato.", + "management.stats.new_users.month": "{number, plural, one {# utente registrato negli ultimi 30 giorni} other {# utenti registrati negli ultimi 30 giorni}}", + "management.stats.new_users.week": "{number, plural, one {# utente registrato negli ultimi 7 giorni} other {# utenti registrati negli ultimi 7 giorni}}", + "management.stats.new_users.active": "Mappato almeno un compito", + "management.stats.new_users.email_verified": "Indirizzo email confermato", + "management.stats.title": "Statistiche", "user.nextLevel": "{changesets} / {nextLevelThreshold} set di cambi per {level}", "user.personalInfo": "Informazioni personali", "user.name": "Nome", @@ -786,8 +786,8 @@ "user.gender.male": "Maschio", "user.gender.preferNotToSay": "Preferisco non dirlo", "user.gender.selfDescribe": "Preferisco auto-descrivermi:", - "user.gender.privacy": "", - "user.email.privacy": "", + "user.gender.privacy": "Le informazioni sul tuo genere sono usate solo a fini statistici e non verranno divulgate ad altri utenti.", + "user.email.privacy": "Il tuo indirizzo email verrà usato solamente per inviarti le notifiche e gli aggiornamenti sul Tasking Manager. Non verrà condiviso con altri utenti e organizzazioni.", "user.slack": "Nome utente su Slack del gruppo {org}", "user.personalInfo.error": "Digita solo il tuo nome utente, non l'URL.", "user.form.save": "Salva", @@ -868,7 +868,7 @@ "users.detail.buildingsMapped": "Edifici mappati", "users.detail.roadMapped": "Km di strade mappati", "users.detail.poiMapped": "Punti di interesse mappati", - "users.detail.waterwaysMapped": "", + "users.detail.waterwaysMapped": "Km di corsi d’acqua mappati", "users.detail.tasksMapped": "{user} ha mappato", "users.detail.you": "È", "users.detail.tasksValidated": "{user} ha validato", @@ -901,19 +901,19 @@ "teamsAndOrgs.management.project.forbidden": "Non sei autorizzato a modificare questo progetto.", "teamsAndOrgs.management.team.forbidden": "Non sei autorizzato a modificare questo gruppo.", "loginPage.title": "Accedi o registra un account", - "management.managers": "", + "management.managers": "Gestori", "management.users.title": "Gestire gli utenti", - "management.stats.users.title": "", - "management.stats.features": "", + "management.stats.users.title": "Nuovi utenti", + "management.stats.features": "Elementi totali", "teamsAndOrgs.management.organisation.creation": "Crea nuova organizzazione", - "teamsAndOrgs.management.organisation.edit": "", - "teamsAndOrgs.management.team.creation": "Crea un nuovo team", + "teamsAndOrgs.management.organisation.edit": "Modifica organizzazione", + "teamsAndOrgs.management.team.creation": "Crea un nuovo gruppo", "teamsAndOrgs.management.campaign.creation": "Crea nuova campagna", "teamsAndOrgs.management.organisation.button.create": "Crea organizzazione", - "teamsAndOrgs.management.team.button.create": "Crea team", + "teamsAndOrgs.management.team.button.create": "Crea gruppo", "teamsAndOrgs.management.campaign.button.create": "Crea campagna", - "teamsAndOrgs.management.button.my_teams": "My gruppi", - "teamsAndOrgs.management.button.join_team": "Unisciti al team", + "teamsAndOrgs.management.button.my_teams": "I miei gruppi", + "teamsAndOrgs.management.button.join_team": "Unisciti al gruppo", "teamsAndOrgs.management.button.cancel_request": "Annulla richiesta", "teamsAndOrgs.management.button.leave_team": "Lascia il gruppo", "teamsAndOrgs.management.button.cancel": "Annulla", @@ -924,9 +924,9 @@ "teamsAndOrgs.management.organisation.usage_tier": "Livello", "teamsAndOrgs.management.organisation.usage_level": "Livello", "teamsAndOrgs.management.organisation.manage": "Gestire l'organizzazione", - "teamsAndOrgs.management.team.manage": "Gestisci il team", + "teamsAndOrgs.management.team.manage": "Gestisci il gruppo", "teamsAndOrgs.management.campaign.manage": "Gestisci campagna", - "teamsAndOrgs.management.titles.team_information": "Informazioni del team", + "teamsAndOrgs.management.titles.team_information": "Informazioni del gruppo", "teamsAndOrgs.management.titles.campaign_information": "Informazioni sulla campagna", "management.license.manage": "Gestisci licenza", "management.category.manage": "Gestisci categoria", diff --git a/frontend/src/locales/nl_NL.json b/frontend/src/locales/nl_NL.json index 11b49aa642..2de7d9d721 100644 --- a/frontend/src/locales/nl_NL.json +++ b/frontend/src/locales/nl_NL.json @@ -33,7 +33,7 @@ "mytasks.unlock": "Vergrendeling opheffen {time}", "mytasks.tasks.title": "Taak #{task} · Project #{project}", "mytasks.tasks.button.retry": "Opnieuw proberen", - "mytasks.tasks.comments.number": "{number, plural, one {} other {}}", + "mytasks.tasks.comments.number": "{number, plural, one {# opmerking} other {# opmerkingen}}", "deleteModal.status.processing": "Verwerken", "deleteModal.status.success": "{type} werd met succes verwijderd.", "deleteModal.status.failure.projects": "Er trad een fout op bij het proberen te verwijderen van dit project.", @@ -244,8 +244,8 @@ "project.detail.coordination": "Coördinatie", "project.detail.coordination.description": "Dit project wordt gecoördineerd door {organisation} en werd gemaakt door {user}.", "project.detail.createdBy": "Project gemaakt door {user}.", - "project.detail.contributorCount.zero": "", - "project.detail.contributorCount": "{number, plural, one {} other {}}", + "project.detail.contributorCount.zero": "Nog geen deelnemers", + "project.detail.contributorCount": "{number, plural, one {# deelnemer} other {# deelnemers}}", "project.detail.lastContribution": "Laatste bijdrage", "project.detail.percentMapped": "In kaart gebracht", "project.detail.percentValidated": "Gevalideerd", @@ -670,12 +670,12 @@ "management.messages.notAllowed": "U bent niet gerechtigd organisaties te beheren.", "management.messages.imageUpload.error": "Uploaden van de afbeelding is mislukt.", "management.fields.managers": "Beheerders", - "management.fields.managers.empty": "", + "management.fields.managers.empty": "Er zijn nog geen beheerders.", "management.link.manage": "Beheren {entity}", "management.link.edit.team": "Team bewerken", "management.members.edit": "Bewerken", "management.members": "Leden", - "management.members.empty": "", + "management.members.empty": "Er zijn nog geen leden.", "management.teams.mapping": "Teams voor in kaart brengen", "management.teams.validation": "Teams voor valideren ", "management.teams.members": "Teamleden", @@ -683,7 +683,7 @@ "management.teams.members.send_message.button": "Versturen", "management.teams.members.send_message.subject": "Onderwerp", "management.teams.join_requests": "Verzoeken om bij te dragen", - "management.teams.join_requests.empty": "", + "management.teams.join_requests.empty": "Er zijn geen verzoeken om aan het team te worden toegevoegd.", "management.teams": "Teams", "management.team": "Team", "management.projects": "Projecten", @@ -709,7 +709,7 @@ "management.organisations.type": "Type", "management.organisations.publicUrl": "Publieke URL", "management.organisations.publicUrl.copy": "Publieke URL kopiëren", - "management.organisations.tier.select": "", + "management.organisations.tier.select": "Niveau selecteren", "management.organisations.type.select": "Type selecteren ", "management.organisations.type.free": "Vrij", "management.organisations.type.discounted": "Niet geteld", @@ -726,7 +726,7 @@ "management.organisations.stats.actions_needed": "Benodigde acties", "management.organisations.stats.completed_actions": "Voltooide acties", "management.organisations.stats.actions_needed.help": "Actie betekent een bewerking voor in kaart brengen of valideren. Omdat elke taak in kaart gebracht en gevalideerd moet worden, is dat het aantal benodigde acties om alle gepubliceerde projecten van die organisatie te voltooien.", - "management.organisations.stats.tier.subscribed": "", + "management.organisations.stats.tier.subscribed": "Geabonneerd niveau", "management.organisations.stats.level.tooltip": "{n} van {total} ({percent}%) voltooid om te verplaatsen naar niveau {nextLevel}", "management.organisations.stats.tier.tooltip": "{n} van {total} ({percent}%) voltooid om te verplaatsen naar fase {nextTier}", "management.organisations.stats.level.description": "{org} is een organisatie niveau {level}.", @@ -786,8 +786,8 @@ "user.gender.male": "Mannelijk", "user.gender.preferNotToSay": "Voorkeur om niet te zeggen", "user.gender.selfDescribe": "Voorkeur om zelf te beschrijven", - "user.gender.privacy": "", - "user.email.privacy": "", + "user.gender.privacy": "Uw informatie over uw geslacht zal alleen worden gebruikt voor statistische doeleinden en zal niet worden weergegeven voor andere gebruikers.", + "user.email.privacy": "Uw e-mailadres zal alleen worden gebruikt om u notificaties en updates over Tasking Manager te sturen. Het zal niet worden gedeeld met andere gebruikers of organisaties.", "user.slack": "Gebruikersnaam op {org} Slack", "user.personalInfo.error": "Typ alleen uw gebruikersnaam, niet de URL.", "user.form.save": "Opslaan", diff --git a/frontend/src/locales/uk.json b/frontend/src/locales/uk.json index cef1b17599..a0492b3071 100644 --- a/frontend/src/locales/uk.json +++ b/frontend/src/locales/uk.json @@ -33,7 +33,7 @@ "mytasks.unlock": "розблокування {time}", "mytasks.tasks.title": "Завдання #{task} · Проєкт #{project}", "mytasks.tasks.button.retry": "Повторити", - "mytasks.tasks.comments.number": "{number, plural, one {} few {} many {} other {}}", + "mytasks.tasks.comments.number": "{number, plural, one {# коментар} few {# коментаря} many {# коментарів} other {# коментаря}}", "deleteModal.status.processing": "Обробка", "deleteModal.status.success": "{type} вилучено.", "deleteModal.status.failure.projects": "Виникла помилка під час спроби вилучення цього проєкту.", @@ -244,8 +244,8 @@ "project.detail.coordination": "Координація", "project.detail.coordination.description": "Координація проєкту відбувається за участі {organisation}. Проєкт був створений {user}.", "project.detail.createdBy": "Проєкт створений {user}.", - "project.detail.contributorCount.zero": "", - "project.detail.contributorCount": "{number, plural, one {} few {} many {} other {}}", + "project.detail.contributorCount.zero": "Немає учасників (поки що)", + "project.detail.contributorCount": "{number, plural, one {# учасник} few {# учасники} many {# учасників} other {# учасники}}", "project.detail.lastContribution": "Останній внесок", "project.detail.percentMapped": "Замаплено", "project.detail.percentValidated": "Перевірено", @@ -670,12 +670,12 @@ "management.messages.notAllowed": "У вас немає дозволу на керування організацією.", "management.messages.imageUpload.error": "Помилка завантаження зображення.", "management.fields.managers": "Менеджери", - "management.fields.managers.empty": "", + "management.fields.managers.empty": "Менеджери поки що немає.", "management.link.manage": "Керування - {entity}", "management.link.edit.team": "Редагувати команду", "management.members.edit": "Редагувати", "management.members": "Члени", - "management.members.empty": "", + "management.members.empty": "Учасників поки що немає.", "management.teams.mapping": "Команди з мапінгу", "management.teams.validation": "Команди контролерів", "management.teams.members": "Члени команди", @@ -683,7 +683,7 @@ "management.teams.members.send_message.button": "Надіслати", "management.teams.members.send_message.subject": "Тема", "management.teams.join_requests": "Запит на приєднання", - "management.teams.join_requests.empty": "", + "management.teams.join_requests.empty": "Поки що немає жодного запиту на приєднання до команди.", "management.teams": "Команди", "management.team": "Команда", "management.projects": "Проєкти", @@ -699,7 +699,7 @@ "management.filter.buttons.myOrganisations": "Ваші організації", "management.filter.buttons.all": "Всі", "management.myTeams": "Команди", - "management.buttons.new": "", + "management.buttons.new": "Додати", "management.buttons.delete": "Вилучити", "management.buttons.accept": "Прийняти", "management.buttons.reject": "Відхилити", @@ -707,14 +707,14 @@ "management.organisation": "Організація", "management.organisations": "Організації", "management.organisations.type": "Тип", - "management.organisations.publicUrl": "", - "management.organisations.publicUrl.copy": "", - "management.organisations.tier.select": "", + "management.organisations.publicUrl": "Посилання URL", + "management.organisations.publicUrl.copy": "Скопіювати посилання", + "management.organisations.tier.select": "Обрати рівень", "management.organisations.type.select": "Оберіть тип", "management.organisations.type.free": "Вільно", "management.organisations.type.discounted": "Зі знижкою", "management.organisations.type.defaultFee": "Звичайна плата", - "management.organisations.list.empty": "", + "management.organisations.list.empty": "Організації не знайдено.", "management.organisations.stats.retry": "Спробувати ще раз", "management.organisations.stats.error": "Під час завантаження статистики виникли проблеми.", "management.organisations.stats.error.start_date": "Початкова дата має бути раніше за кінцеву дату.", @@ -726,7 +726,7 @@ "management.organisations.stats.actions_needed": "Вимагають уваги", "management.organisations.stats.completed_actions": "Завершені завдання", "management.organisations.stats.actions_needed.help": "Завдання що вимагають уваги потребують перевірки або завершення мапінгу. Кожне завдання має бути замаплене та перевірене, це число показує кількість дій потрібних для завершення всіх опублікованих проєктів для цієї організації.", - "management.organisations.stats.tier.subscribed": "", + "management.organisations.stats.tier.subscribed": "Поточний рівень", "management.organisations.stats.level.tooltip": "{n} з {total} ({percent}%) завершено для переходу на рівень {nextLevel}", "management.organisations.stats.tier.tooltip": "{n} з {total} ({percent}%) завершено для переходу на {nextTier} рівень", "management.organisations.stats.level.description": "{org} – організація {level} рівня.", @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Прогнозований рівень до кінця {year} року", "management.organisations.stats.cost.estimation": "Орієнтовна вартість до кінця {year} року", "management.organisations.stats.next_level.actions": "Дій залишилось до рівня {n}", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.next_tier.actions": "Для переходу не наступний рівень виконайте", "management.organisations.tier.free": "Вільно", "management.organisations.tier.low": "Неважливий", "management.organisations.tier.medium": "Середній", @@ -769,10 +769,10 @@ "teamsAndOrgs.management.teams.messages.waiting_approval": "Ваш запит на приєднання до команди очікує на розгляд.", "management.projects.no_found": "{entity} поки що не має проєктів.", "management.organisation.teams.no_found": "Команди не знайдено.", - "management.stats.new_users.month": "{number, plural, one {} few {} many {} other {}}", - "management.stats.new_users.week": "{number, plural, one {} few {} many {} other {}}", - "management.stats.new_users.active": "", - "management.stats.new_users.email_verified": "", + "management.stats.new_users.month": "{number, plural, one {# користувач зареєструвався за останні 30 днів} few {# користувачі зареєструвались за останні 30 днів} many {# користувачів зареєструвались за останні 30 днів} other {# користувачі зареєструвались за останні 30 днів}}", + "management.stats.new_users.week": "{number, plural, one {# користувач зареєструвався за останні 7 днів} few {# користувачі зареєструвались за останні 7 днів} many {# користувачів зареєструвались за останні 7 днів} other {# користувачі зареєструвались за останні 7 днів}}", + "management.stats.new_users.active": "Замаплено принаймні одне завдання", + "management.stats.new_users.email_verified": "Адресу е-пошти підтверджено", "management.stats.title": "Статистика", "user.nextLevel": "{changesets} / {nextLevelThreshold} наборів змін до {level}", "user.personalInfo": "Особисті дані", @@ -786,8 +786,8 @@ "user.gender.male": "Чоловік", "user.gender.preferNotToSay": "Не бажаю зазначати", "user.gender.selfDescribe": "Вважаю що я:", - "user.gender.privacy": "", - "user.email.privacy": "", + "user.gender.privacy": "Інформація про вашу стать буде використовуватись лише для підбиття підсумків та не буде показуватись іншим учасникам.", + "user.email.privacy": "Ваша адреса е-пошти буде використовуватись лише для надсилання вам новин та повідомлень з Менеджера завдань. Вона не буде передана іншим користувачам чи організаціям.", "user.slack": "Логін користувача в {org} Slack", "user.personalInfo.error": "Зазначте лише ваш логін, не URL.", "user.form.save": "Зберегти", @@ -868,7 +868,7 @@ "users.detail.buildingsMapped": "Будинків замаплено", "users.detail.roadMapped": "Замаплено доріг, км", "users.detail.poiMapped": "Додано ПОІ", - "users.detail.waterwaysMapped": "", + "users.detail.waterwaysMapped": "км водних шляхів замаплено", "users.detail.tasksMapped": "{user} замапили", "users.detail.you": "Ви", "users.detail.tasksValidated": "{user} перевірили", @@ -904,9 +904,9 @@ "management.managers": "Менеджери", "management.users.title": "Керування учасниками", "management.stats.users.title": "Нові учасники", - "management.stats.features": "", + "management.stats.features": "Всього об'єктів", "teamsAndOrgs.management.organisation.creation": "Створити нову організацію", - "teamsAndOrgs.management.organisation.edit": "", + "teamsAndOrgs.management.organisation.edit": "Редагувати організацію", "teamsAndOrgs.management.team.creation": "Створити нову команду", "teamsAndOrgs.management.campaign.creation": "Створити нову кампанію", "teamsAndOrgs.management.organisation.button.create": "Створити організацію", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 78d6f7bd64..21141030fd 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2905,79 +2905,79 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@sentry/browser@6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.2.2.tgz#4df4ad7026b269d85b63b79a75387ce5370bc705" - integrity sha512-K5UGyEePtVPZIFMoiRafhd4Ov0M1kdozVsVKIPZrOpJyjQdPNX+fYDNL/h0nVmgOlE2S/uu4fl4mEfe/6aLShw== +"@sentry/browser@6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.2.3.tgz#b622b3fb62340574e395b6ae12ffbb9d25d98bd4" + integrity sha512-QUqrZdAosY2MPAUfJYpyCT+dA6v7A2h8imO8R3Lbi0hRSPr+L7zjqHgFs3CTHJLmLV74cxHt6rVVUPSksYNQDQ== dependencies: - "@sentry/core" "6.2.2" - "@sentry/types" "6.2.2" - "@sentry/utils" "6.2.2" + "@sentry/core" "6.2.3" + "@sentry/types" "6.2.3" + "@sentry/utils" "6.2.3" tslib "^1.9.3" -"@sentry/core@6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.2.2.tgz#ec86b5769f8855f43cb58e839f81f87074ec9a3f" - integrity sha512-qqWbvvXtymfXh7N5eEvk97MCnMURuyFIgqWdVD4MQM6yIfDCy36CyGfuQ3ViHTLZGdIfEOhLL9/f4kzf1RzqBA== +"@sentry/core@6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.2.3.tgz#ed5d21fd8b18ddc289d04c669393a437fb09639f" + integrity sha512-GpfHoSJiXchVXgyaMWVtIPVw2t97KkD1OJ4JdL3/TeH3auX5XvsN5iHTk+x/Er8t13IpOnvidH1xWdV1dnax2w== dependencies: - "@sentry/hub" "6.2.2" - "@sentry/minimal" "6.2.2" - "@sentry/types" "6.2.2" - "@sentry/utils" "6.2.2" + "@sentry/hub" "6.2.3" + "@sentry/minimal" "6.2.3" + "@sentry/types" "6.2.3" + "@sentry/utils" "6.2.3" tslib "^1.9.3" -"@sentry/hub@6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.2.2.tgz#f451d8d3ad207e81556b4846d810226693e0444e" - integrity sha512-VR6uQGRYt6RP633FHShlSLj0LUKGVrlTeSlwCoooWM5FR9lmi6akAaweuxpG78/kZvXrAWpjX6/nuYwHKGwzGA== +"@sentry/hub@6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.2.3.tgz#07fba07627b7523f69f8b862f00cd197e5e4e5bd" + integrity sha512-D5Horfo2l0p52S7KPvy7qwWNMrE4IsCN8ODbfcCsfJu7hEXJmItbkbohIVSqO5neukhn5nu+x8kyCe9Q5u1Q6g== dependencies: - "@sentry/types" "6.2.2" - "@sentry/utils" "6.2.2" + "@sentry/types" "6.2.3" + "@sentry/utils" "6.2.3" tslib "^1.9.3" -"@sentry/minimal@6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.2.2.tgz#01f41e0a6a6a2becfc99f6bb6f9c4bddf54f8dae" - integrity sha512-l0IgoGQgg1lTd4qDU8bQn25sbZBg8PwIHfuTLbGMlRr1flDXHOM1UXajWK/UKbAPelnU7M2JBSVzgl7PwjprzA== +"@sentry/minimal@6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.2.3.tgz#462ce7739fa85fd7d6dd13d56d20f17ff91e46d0" + integrity sha512-Gpn9x4NQAG7E94EK1+hAz9GUcYrffTuqJ/XgqvHYk0jsHZ6RfsXYrmBac0ZwUxOivMf2t0n5opK0v5rhMDfF2w== dependencies: - "@sentry/hub" "6.2.2" - "@sentry/types" "6.2.2" + "@sentry/hub" "6.2.3" + "@sentry/types" "6.2.3" tslib "^1.9.3" -"@sentry/react@^6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.2.2.tgz#6a93fa1013b2b9e37a8c0bc16cf0cbf4353de4c6" - integrity sha512-yDuxPOD4j2WE5nX1p48GIqXwrrmwkjryFjtYvLgzGJkiGWLmGTrxrSqtUKrbqahJpKt3mi24Nkg0cMlsFB178g== +"@sentry/react@^6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.2.3.tgz#66e8a2073acd74677e4daf850e165273eb8eea7a" + integrity sha512-T2mBD9ZFxzLQ3Kc5cey7A5fBA+qN67NdmRw9W1Grk6cEoJIrQYg3LnFbM5YnBBK86ciXQlgz7ZsF7rbjRcmWMQ== dependencies: - "@sentry/browser" "6.2.2" - "@sentry/minimal" "6.2.2" - "@sentry/types" "6.2.2" - "@sentry/utils" "6.2.2" + "@sentry/browser" "6.2.3" + "@sentry/minimal" "6.2.3" + "@sentry/types" "6.2.3" + "@sentry/utils" "6.2.3" hoist-non-react-statics "^3.3.2" tslib "^1.9.3" -"@sentry/tracing@^6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.2.2.tgz#77097fb1dad7e8ad6ccd93c57b1ef5fa85219099" - integrity sha512-mAkPoqtofNfka/u9rOVVDQPaEoTmr0AQh654g9ZqsaqsOJLKjB4FDLVNubWs90fjeKqHiYkI3ZHPak2TzHBPkw== +"@sentry/tracing@^6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.2.3.tgz#fefa55b1f2265973a747b30da14a54b779b5090e" + integrity sha512-OnQZKp7qVera+Z4ly6hgybGgyf10p2VDXqwueXkMVeLD+PwlPG8a8NMpKkZ+QxwRbQbSFhRLQaib3NX34tusBQ== dependencies: - "@sentry/hub" "6.2.2" - "@sentry/minimal" "6.2.2" - "@sentry/types" "6.2.2" - "@sentry/utils" "6.2.2" + "@sentry/hub" "6.2.3" + "@sentry/minimal" "6.2.3" + "@sentry/types" "6.2.3" + "@sentry/utils" "6.2.3" tslib "^1.9.3" -"@sentry/types@6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.2.2.tgz#9fc7795156680d3da5fc6ecc66702d8f7917f2b1" - integrity sha512-Y/1sRtw3a5JU4YdNBig8lLSVJ1UdYtuge+QP1CVLcLSAbq07Ok1bvF+Z+BlNcnHqle2Fl8aKuryG5Yu86enOyQ== +"@sentry/types@6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.2.3.tgz#0c06a475a51d28c73a69b05f0d43db05310ec241" + integrity sha512-BpA+9FherWgYlkMD/82bGFh/gAqZNlZX5UE8vWLKyyzNyOEEz3v9ScxE8dOSWE4v5iXJR1O3jjxaTcRQxPVgCA== -"@sentry/utils@6.2.2": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.2.2.tgz#69f7151db74e65a010cec062cc9ab3e30bf2c80a" - integrity sha512-qaee6X6VDNZ8HeO83/veaKw0KuhDE7j1R+Yryme3PywFzsoTzutDrEQjb7gvcHAhBaAYX8IHUBHgxcFI9BxI+w== +"@sentry/utils@6.2.3": + version "6.2.3" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.2.3.tgz#c96539571a67fb2eed56897133649f35309e3f74" + integrity sha512-YnkJm97wSvck39eRpqWjIuuwbvzPilvAcMqhbUy9yK/UBQMDGUzAKCOKH40udw1DwMUCWjJ71mOCDgUorE4Fog== dependencies: - "@sentry/types" "6.2.2" + "@sentry/types" "6.2.3" tslib "^1.9.3" "@sindresorhus/is@^0.7.0": @@ -3158,10 +3158,10 @@ "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" -"@testing-library/user-event@^13.0.3": - version "13.0.3" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.3.tgz#14f1d2a117f13529ea31ce6f7414b003c76f17e1" - integrity sha512-q9CAkTO+fV6dskQRttxsFVAzqMIhOVN0H0dSEssL5oz1H7QY7cMfQ/KPOt57lgXXPVRJ1pzGlKQotZ27E+PgvA== +"@testing-library/user-event@^13.0.7": + version "13.0.7" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.7.tgz#835634e4cd6db6d63eb9398bd62fb26120f85dfd" + integrity sha512-EJBruqe7mV9OwPrZBx9HhFXt84KLinNNiGB0gqVp6+gPJ1ZP99Nq5FieChb/54fzmddGLkMp5ndbZBaEADdxrQ== dependencies: "@babel/runtime" "^7.12.5" @@ -12286,10 +12286,10 @@ react-error-overlay@^6.0.9: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== -react-final-form@^6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-6.5.2.tgz#d04d1eb7d92eabc6f6c35206bb0eebfc4bfd924b" - integrity sha512-c5l45FYOoxtfpvsvMFh3w2WW8KNxbuebBUrM16rUrooQkewTs0Zahmv0TuKFX5jsC9BKn5Fo84j3ZVXQdURS4w== +react-final-form@^6.5.3: + version "6.5.3" + resolved "https://registry.yarnpkg.com/react-final-form/-/react-final-form-6.5.3.tgz#b60955837fe9d777456ae9d9c48e3e2f21547d29" + integrity sha512-FCs6GC0AMWJl2p6YX7kM+a0AvuSLAZUgbVNtRBskOs4g984t/It0qGtx51O+9vgqnqk6JyoxmIzxKMq+7ch/vg== dependencies: "@babel/runtime" "^7.12.1" From 604119de6961aa4a464cd570adf71d0cfc7d6406 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 19 Mar 2021 18:24:05 +0000 Subject: [PATCH 06/24] Bump react-select from 4.2.1 to 4.3.0 in /frontend Bumps [react-select](https://github.com/JedWatson/react-select) from 4.2.1 to 4.3.0. - [Release notes](https://github.com/JedWatson/react-select/releases) - [Changelog](https://github.com/JedWatson/react-select/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/JedWatson/react-select/compare/react-select@4.2.1...react-select@4.3.0) Signed-off-by: dependabot-preview[bot] --- frontend/package.json | 2 +- frontend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 02eb267371..81f72d13cd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -56,7 +56,7 @@ "react-placeholder": "^4.1.0", "react-redux": "^7.2.2", "react-scripts": "^4.0.3", - "react-select": "^4.2.1", + "react-select": "^4.3.0", "react-tooltip": "^4.2.13", "reactjs-popup": "^1.5.0", "redux": "^4.0.5", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 21141030fd..b058c2d924 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -12449,10 +12449,10 @@ react-select-event@^5.2.0: dependencies: "@testing-library/dom" ">=7" -react-select@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.2.1.tgz#15c4837dffc1c23e91b7fde606c468cc10000a06" - integrity sha512-JwwZjsR10AD5RXmx4iEkN0Ndim/uSaQ8j8cxMwOg8SJFeyXwu/m+sdSQ0ds0AWFm7hhXG9kusC3CQ/s4UNcOIg== +react-select@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-4.3.0.tgz#6bde634ae7a378b49f3833c85c126f533483fa2e" + integrity sha512-SBPD1a3TJqE9zoI/jfOLCAoLr/neluaeokjOixr3zZ1vHezkom8K0A9J4QG9IWDqIDE9K/Mv+0y1GjidC2PDtQ== dependencies: "@babel/runtime" "^7.12.0" "@emotion/cache" "^11.0.0" From 0c31345b35f68df52f1fe60fef273cc49f114b21 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Mon, 22 Mar 2021 15:07:40 -0300 Subject: [PATCH 07/24] Separate OrganisationUsageLevel and OrganisationTier, add subscribed tier info (#4380) * Separate OrganisationUsageLevel and OrganisationTier, add subscribed tier info * Add completedActions for organisation tier Co-authored-by: Diana Rita Nanyanzi <31903212+d-rita@users.noreply.github.com> --- .../src/components/teamsAndOrgs/messages.js | 6 +- .../components/teamsAndOrgs/orgUsageLevel.js | 231 +++++++++++------ .../teamsAndOrgs/tests/orgUsageLevel.test.js | 241 +++++------------- frontend/src/locales/en.json | 2 +- frontend/src/views/organisationStats.js | 25 +- 5 files changed, 236 insertions(+), 269 deletions(-) diff --git a/frontend/src/components/teamsAndOrgs/messages.js b/frontend/src/components/teamsAndOrgs/messages.js index e669de8774..face407c5a 100644 --- a/frontend/src/components/teamsAndOrgs/messages.js +++ b/frontend/src/components/teamsAndOrgs/messages.js @@ -273,9 +273,9 @@ export default defineMessages({ id: 'management.organisations.stats.next_level.actions', defaultMessage: 'Actions to reach the level {n}', }, - actionsToNextTier: { - id: 'management.organisations.stats.next_tier.actions', - defaultMessage: 'Actions to move to the next tier', + actionsRemaining: { + id: 'management.organisations.stats.tier.actions_remaining', + defaultMessage: 'Actions remaining on the {name} tier', }, freeTier: { id: 'management.organisations.tier.free', diff --git a/frontend/src/components/teamsAndOrgs/orgUsageLevel.js b/frontend/src/components/teamsAndOrgs/orgUsageLevel.js index 2943eaafc0..5e05422d3f 100644 --- a/frontend/src/components/teamsAndOrgs/orgUsageLevel.js +++ b/frontend/src/components/teamsAndOrgs/orgUsageLevel.js @@ -10,55 +10,38 @@ import { useOrganisationLevel, usePredictLevel, useGetLevel, + levels, } from '../../hooks/UseOrganisationLevel'; -export function OrganisationUsageLevel({ completedActions, orgName, type, userIsOrgManager }) { +// this component is designed to the FREE organisation type +export function OrganisationUsageLevel({ completedActions, orgName }) { const [currentLevel, nextLevelThreshold] = useOrganisationLevel(completedActions); - const nextLevel = useGetLevel(nextLevelThreshold); const percent = parseInt((completedActions / nextLevelThreshold) * 100); const yearPrediction = usePredictYearlyTasks(completedActions, new Date()); - const levelPrediction = usePredictLevel(yearPrediction, type); - - const showTierInfo = ['DISCOUNTED', 'FULL_FEE'].includes(type) && userIsOrgManager; - const showDiscountLabel = levelPrediction.tier !== 'free' && type === 'DISCOUNTED'; + const levelPrediction = usePredictLevel(yearPrediction, 'FREE'); const currentYear = getYear(new Date()); return (

-
- {showTierInfo ? ( -

- -

- ) : ( -

- {currentLevel.level} -

- )} +
+

+ {currentLevel.level} +

-
+
{nextLevelThreshold && ( - +

, total: , percent: percent, - nextTier: ( - - - - ), nextLevel: {currentLevel.level + 1}, }} /> @@ -67,92 +50,172 @@ export function OrganisationUsageLevel({ completedActions, orgName, type, userIs )}

- {(nextLevelThreshold || showTierInfo) && ( + {nextLevelThreshold && (
+ } className="tc" - value={ - showTierInfo ? ( - - - - ) : ( - - ) - } + value={} />
)} - {showTierInfo && ( + {nextLevelThreshold && (
+ } className="tc" - value={ - <> - - {showDiscountLabel ? ( - - {' '} - () - - ) : ( - '' - )} - - } + value={} />
)} - {nextLevelThreshold && ( +
+ {!nextLevelThreshold && ( // message on level 5 organisations +
+
+ {orgName}, + level: currentLevel.level, + }} + />{' '} + +
+
+ )} +
+
+ ); +} + +// this component is designed to the DISCOUNTED and FULL_FEE organisations +export function OrganisationTier({ completedActions, type, subscriptionTier }) { + const yearPrediction = usePredictYearlyTasks(completedActions, new Date()); + const levelPrediction = usePredictLevel(yearPrediction, type); + const selectedTier = subscriptionTier + ? levels.filter((level) => level.level === subscriptionTier)[0] + : null; + const selectedTierMax = + selectedTier && selectedTier.level < 5 + ? levels.filter((level) => level.level === selectedTier.level + 1)[0].minActions + : null; + const nextLevel = useGetLevel(selectedTierMax); + const percent = parseInt((completedActions / selectedTierMax) * 100); + const showDiscountLabel = levelPrediction.tier !== 'free' && type === 'DISCOUNTED'; + const currentYear = getYear(new Date()); + + return ( +
+
+
+

+ {selectedTier && } +

+ + + +
+
+ {selectedTierMax && ( + +

+ , + total: , + percent: percent, + nextTier: ( + + + + ), + }} + /> +

+
+ )} +
+
+
+
+ + } + className="tc" + value={ + + + + } + /> +
+
+
+
+ + } + className="tc" + value={ + <> + + {showDiscountLabel ? ( + + {' '} + () + + ) : ( + '' + )} + + } + /> +
+
+ {selectedTierMax && (
, + }} /> } className="tc" - value={} + value={ + + } />
)}
- {!nextLevelThreshold && - !showTierInfo && ( // message on level 5 FREE tier organisations -
-
- {orgName}, - level: currentLevel.level, - }} - />{' '} - -
-
- )}
); diff --git a/frontend/src/components/teamsAndOrgs/tests/orgUsageLevel.test.js b/frontend/src/components/teamsAndOrgs/tests/orgUsageLevel.test.js index 958571344f..10668726a0 100644 --- a/frontend/src/components/teamsAndOrgs/tests/orgUsageLevel.test.js +++ b/frontend/src/components/teamsAndOrgs/tests/orgUsageLevel.test.js @@ -4,14 +4,14 @@ import { getYear } from 'date-fns'; import '@testing-library/jest-dom'; import { ReduxIntlProviders } from '../../../utils/testWithIntl'; -import { OrganisationUsageLevel } from '../orgUsageLevel'; +import { OrganisationUsageLevel, OrganisationTier } from '../orgUsageLevel'; describe('OrganisationUsageLevel', () => { const currentYear = getYear(new Date()); it('with level 1', () => { const { container } = render( - + , ); expect(container.querySelector('h1').className).toBe( @@ -26,74 +26,6 @@ describe('OrganisationUsageLevel', () => { expect(screen.queryByText(/tier/)).not.toBeInTheDocument(); }); - it('with level 1, under tier, but accessed by a normal user ', () => { - const { container } = render( - - - , - ); - expect(container.querySelector('h1').className).toBe( - 'relative tc w-100 dib red barlow-condensed ma0 ph4 v-mid top--1', - ); - expect(container.querySelector('h1').style.fontSize).toBe('8rem'); - expect(within(container.querySelector('h1')).getByText('1')).toBeTruthy(); - expect(screen.getAllByRole('progressbar')[1].style.width).toBe('10%'); - expect(screen.getByText('900')).toBeInTheDocument(); - expect(screen.getByText(/reach the level 2/)).toBeInTheDocument(); - expect(screen.getByText(/Estimated level by the end of/)).toBeInTheDocument(); - expect(screen.queryByText(/tier/)).not.toBeInTheDocument(); - }); - - it('with level 1, under tier and accessed by an organisation manager', () => { - const { container } = render( - - - , - ); - expect(container.querySelector('h1').className).toBe( - 'relative f1 tc w-100 dib ttu red barlow-condensed ma0 pv2 mt3', - ); - expect(within(container.querySelector('h1')).getByText('Free')).toBeTruthy(); - expect(screen.getAllByRole('progressbar')[1].style.width).toBe('10%'); - expect(screen.getByText('900')).toBeInTheDocument(); - expect(screen.getByText('Actions to move to the next tier')).toBeInTheDocument(); - expect(screen.getByText(`Estimated tier by the end of ${currentYear}`)).toBeInTheDocument(); - expect(screen.getByText(`Estimated cost by the end of ${currentYear}`)).toBeInTheDocument(); - }); - - it('with level 1, under DISCOUNTED tier and accessed by an organisation manager', () => { - const { container } = render( - - - , - ); - expect(container.querySelector('h1').className).toBe( - 'relative f1 tc w-100 dib ttu red barlow-condensed ma0 pv2 mt3', - ); - expect(within(container.querySelector('h1')).getByText('Free')).toBeTruthy(); - expect(screen.getAllByRole('progressbar')[1].style.width).toBe('10%'); - expect(screen.getByText('900')).toBeInTheDocument(); - expect(screen.getByText('Actions to move to the next tier')).toBeInTheDocument(); - expect(screen.getByText(`Estimated tier by the end of ${currentYear}`)).toBeInTheDocument(); - expect(screen.getByText(`Estimated cost by the end of ${currentYear}`)).toBeInTheDocument(); - expect(screen.queryByText('(discounted)')).not.toBeInTheDocument(); - }); - it('with level 2', () => { const { container } = render( @@ -106,23 +38,6 @@ describe('OrganisationUsageLevel', () => { expect(screen.getByText(/reach the level 3/)).toBeInTheDocument(); }); - it('with level 2, under tier and accessed by an organisation manager', () => { - const { container } = render( - - - , - ); - expect(within(container.querySelector('h1')).getByText('Low')).toBeTruthy(); - expect(screen.getByText('Actions to move to the next tier')).toBeInTheDocument(); - expect(screen.getByText(/Estimated cost by the end of/)).toBeInTheDocument(); - expect(screen.getByText(/Estimated tier by the end of/)).toBeInTheDocument(); - }); - it('with level 3', () => { const { container } = render( @@ -135,20 +50,6 @@ describe('OrganisationUsageLevel', () => { expect(screen.getByText(/reach the level 4/)).toBeInTheDocument(); }); - it('with level 3, under tier and accessed by an organisation manager', () => { - const { container } = render( - - - , - ); - expect(within(container.querySelector('h1')).getByText('Medium')).toBeTruthy(); - }); - it('with level 4', () => { const { container } = render( @@ -164,20 +65,6 @@ describe('OrganisationUsageLevel', () => { ).not.toBeInTheDocument(); }); - it('with level 4, under tier and accessed by an organisation manager', () => { - const { container } = render( - - - , - ); - expect(within(container.querySelector('h1')).getByText('High')).toBeTruthy(); - }); - it('with level 5', () => { const { container } = render( @@ -191,82 +78,95 @@ describe('OrganisationUsageLevel', () => { screen.getByText(/It is the highest level an organization can be on Tasking Manager!/), ).toBeInTheDocument(); }); +}); - it('with level 5, under tier and accessed by an organisation manager', () => { +describe('OrganisationTier', () => { + const currentYear = getYear(new Date()); + it('with 1000 actions on Low subscription tier', () => { const { container } = render( - , ); - expect(within(container.querySelector('h1')).getByText('Very High')).toBeTruthy(); - expect(screen.queryByText('Actions to move to the next tier')).not.toBeInTheDocument(); - expect(screen.queryByText(/Another organization/)).not.toBeInTheDocument(); - expect( - screen.queryByText(/It is the highest level an organization can be on Tasking Manager!/), - ).not.toBeInTheDocument(); - expect(screen.queryByText(/(Discounted)/)).not.toBeInTheDocument(); + expect(container.querySelector('h1').className).toBe( + 'relative f1 tc w-100 dib ttu red barlow-condensed ma0 pt2 mt3', + ); + expect(within(container.querySelector('h1')).getByText('Low')).toBeTruthy(); + expect(screen.getAllByRole('progressbar')[1].style.width).toBe('10%'); + expect(screen.getByText('Subscribed tier')).toBeInTheDocument(); + expect(screen.getAllByText('Low').length).toBe(2); + expect(screen.getByText('9,000')).toBeInTheDocument(); + expect(screen.getByText('Actions remaining on the Low tier')).toBeInTheDocument(); }); - it('with level 5, under tier, but accessed by a normal user', () => { + it('with 200 actions on Free subscription tier', () => { const { container } = render( - + , ); - expect(within(container.querySelector('h1')).getByText('5')).toBeTruthy(); - expect(screen.queryByText(/tier/)).not.toBeInTheDocument(); - expect(screen.queryByText(/Very High/)).not.toBeInTheDocument(); - expect(screen.queryByText(/reach the level/)).not.toBeInTheDocument(); - expect(screen.queryByText(/move to the next tier/)).not.toBeInTheDocument(); - expect(screen.getByText(/Another organization/)).toBeInTheDocument(); - expect( - screen.getByText(/It is the highest level an organization can be on Tasking Manager!/), - ).toBeInTheDocument(); - expect(screen.queryByText(/(Discounted)/)).not.toBeInTheDocument(); + expect(within(container.querySelector('h1')).getByText('Free')).toBeTruthy(); + expect(screen.getAllByRole('progressbar')[1].style.width).toBe('20%'); + expect(screen.getByText('800')).toBeInTheDocument(); + expect(screen.getByText('Actions remaining on the Free tier')).toBeInTheDocument(); + expect(screen.getByText(`Estimated tier by the end of ${currentYear}`)).toBeInTheDocument(); + expect(screen.getByText(`Estimated cost by the end of ${currentYear}`)).toBeInTheDocument(); }); - it('shows the $0 cost and a discounted label for an organization on the level 2 tier ', () => { + it('with 5000 actions on High and DISCOUNTED subscription tier', () => { const { container } = render( - + , ); - expect(container.querySelector('h1').className).toBe( - 'relative f1 tc w-100 dib ttu red barlow-condensed ma0 pv2 mt3', + expect(within(container.querySelector('h1')).getByText('High')).toBeTruthy(); + expect(screen.getAllByRole('progressbar')[1].style.width).toBe('10%'); + expect(screen.getByText('Actions remaining on the High tier')).toBeInTheDocument(); + expect(screen.getByText('45,000')).toBeInTheDocument(); + }); + + it('with 5000 actions on High and FULL_FEE subscription tier', () => { + const { container } = render( + + + , ); - expect(within(container.querySelector('h1')).getByText('Low')).toBeTruthy(); - expect(screen.getAllByRole('progressbar')[1].style.width).toBe('11%'); - expect(screen.getByText('8,900')).toBeInTheDocument(); - expect(screen.getByText('Actions to move to the next tier')).toBeInTheDocument(); - expect(screen.getByText(`Estimated tier by the end of ${currentYear}`)).toBeInTheDocument(); - expect(screen.getByText(`Estimated cost by the end of ${currentYear}`)).toBeInTheDocument(); - expect(screen.getByText(/(Discounted)/)).toBeInTheDocument(); + expect(within(container.querySelector('h1')).getByText('Very High')).toBeTruthy(); + expect(screen.queryByRole('progressbar')).not.toBeInTheDocument(); + expect(screen.queryByText(/Actions remaining/)).not.toBeInTheDocument(); + expect(screen.queryByText('45,000')).not.toBeInTheDocument(); }); - it('does not show the discounted label for a discounted level 1 org', () => { + it('with more completed actions than the subscription tier, shows 0 on remaining actions card', () => { + const { container } = render( + + + , + ); + expect(within(container.querySelector('h1')).getByText('Free')).toBeTruthy(); + expect(screen.getAllByRole('progressbar')[1].style.width).toBe('100%'); + expect(screen.getByText('0')).toBeInTheDocument(); + }); + + it('does not show the discounted label for a FREE subscribed tier org', () => { render( - + + , + ); + expect(screen.getByText('$0.00')).toBeInTheDocument(); + expect(screen.queryByText(/(Discounted)/)).not.toBeInTheDocument(); + }); + + it('does not show the discounted label for a VERY HIGH subscribed tier org with only 1 action', () => { + render( + + , ); expect(screen.getByText('$0.00')).toBeInTheDocument(); @@ -276,12 +176,7 @@ describe('OrganisationUsageLevel', () => { it('shows the discounted cost 20000 for a discounted level 5 org', () => { render( - + , ); expect(screen.getByText('$20,000.00')).toBeInTheDocument(); diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index ba88e79b84..32b638a0ec 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Estimated tier by the end of {year}", "management.organisations.stats.cost.estimation": "Estimated cost by the end of {year}", "management.organisations.stats.next_level.actions": "Actions to reach the level {n}", - "management.organisations.stats.next_tier.actions": "Actions to move to the next tier", + "management.organisations.stats.tier.actions_remaining": "Actions remaining on the {name} tier", "management.organisations.tier.free": "Free", "management.organisations.tier.low": "Low", "management.organisations.tier.medium": "Medium", diff --git a/frontend/src/views/organisationStats.js b/frontend/src/views/organisationStats.js index 0b62fa7ce2..4e355a1cba 100644 --- a/frontend/src/views/organisationStats.js +++ b/frontend/src/views/organisationStats.js @@ -13,7 +13,7 @@ import { useCurrentYearStats } from '../hooks/UseOrgYearStats'; import { useFetch } from '../hooks/UseFetch'; import { useSetTitleTag } from '../hooks/UseMetaTags'; import { RemainingTasksStats } from '../components/teamsAndOrgs/remainingTasksStats'; -import { OrganisationUsageLevel } from '../components/teamsAndOrgs/orgUsageLevel'; +import { OrganisationUsageLevel, OrganisationTier } from '../components/teamsAndOrgs/orgUsageLevel'; import { TasksStats } from '../components/teamsAndOrgs/tasksStats'; export const OrganisationStats = ({ id }) => { @@ -44,7 +44,10 @@ export const OrganisationStats = ({ id }) => { const currentYearStats = useCurrentYearStats(id, query, apiState.stats); const totalStats = useTotalTasksStats(currentYearStats); const completedActions = totalStats.mapped + totalStats.validated; - const showTierInfo = ['DISCOUNTED', 'FULL_FEE'].includes(organisation.type) && isOrgManager; + const showTierInfo = + ['DISCOUNTED', 'FULL_FEE'].includes(organisation.type) && + organisation.subscriptionTier && + isOrgManager; useSetTitleTag(`${organisation.name || 'Organization'} stats`); if (token) { @@ -95,12 +98,18 @@ export const OrganisationStats = ({ id }) => { )} - + {showTierInfo ? ( + + ) : ( + + )}
From 2472288caffdcfb70b16ba7fcc674ed6ba5d21d2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 22 Mar 2021 22:08:47 +0000 Subject: [PATCH 08/24] Bump react, react-dom and react-test-renderer in /frontend Bumps [react](https://github.com/facebook/react/tree/HEAD/packages/react), [react-dom](https://github.com/facebook/react/tree/HEAD/packages/react-dom) and [react-test-renderer](https://github.com/facebook/react/tree/HEAD/packages/react-test-renderer). These dependencies needed to be updated together. Updates `react` from 17.0.1 to 17.0.2 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v17.0.2/packages/react) Updates `react-dom` from 17.0.1 to 17.0.2 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v17.0.2/packages/react-dom) Updates `react-test-renderer` from 17.0.1 to 17.0.2 - [Release notes](https://github.com/facebook/react/releases) - [Changelog](https://github.com/facebook/react/blob/master/CHANGELOG.md) - [Commits](https://github.com/facebook/react/commits/v17.0.2/packages/react-test-renderer) Signed-off-by: dependabot-preview[bot] --- frontend/package.json | 6 +++--- frontend/yarn.lock | 46 +++++++++++++++++++++---------------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 81f72d13cd..3f646fc7a8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -42,13 +42,13 @@ "marked": "^2.0.1", "osmtogeojson": "^3.0.0-beta.3", "query-string": "^6.14.1", - "react": "^17.0.1", + "react": "^17.0.2", "react-accessible-accordion": "^3.3.4", "react-calendar-heatmap": "^1.8.1", "react-chartjs-2": "^2.11.1", "react-click-outside": "^3.0.1", "react-datepicker": "^3.6.0", - "react-dom": "^17.0.1", + "react-dom": "^17.0.2", "react-dropzone": "^11.3.1", "react-final-form": "^6.5.3", "react-intl": "^5.13.0", @@ -113,7 +113,7 @@ "msw": "^0.27.1", "prettier": "^2.2.1", "react-select-event": "^5.2.0", - "react-test-renderer": "^17.0.1", + "react-test-renderer": "^17.0.2", "source-map-explorer": "^2.5.2" }, "jest": { diff --git a/frontend/yarn.lock b/frontend/yarn.lock index b058c2d924..30301d9620 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -12256,14 +12256,14 @@ react-dom@^16.9.0: prop-types "^15.6.2" scheduler "^0.19.1" -react-dom@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.1.tgz#1de2560474ec9f0e334285662ede52dbc5426fc6" - integrity sha512-6eV150oJZ9U2t9svnsspTMrWNyHc6chX0KzDeAOXftRa8bNeOKTTfCJ7KorIwenkHd2xqVTBTCZd79yk/lx/Ug== +react-dom@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" + integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" - scheduler "^0.20.1" + scheduler "^0.20.2" react-dropzone@^11.3.1: version "11.3.1" @@ -12323,10 +12323,10 @@ react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== -"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.1.tgz#5b3531bd76a645a4c9fb6e693ed36419e3301339" - integrity sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA== +"react-is@^16.12.0 || ^17.0.0", react-is@^17.0.1, react-is@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== react-lifecycles-compat@^3.0.4: version "3.0.4" @@ -12470,15 +12470,15 @@ react-shallow-renderer@^16.13.1: object-assign "^4.1.1" react-is "^16.12.0 || ^17.0.0" -react-test-renderer@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3187e636c3063e6ae498aedf21ecf972721574c7" - integrity sha512-/dRae3mj6aObwkjCcxZPlxDFh73XZLgvwhhyON2haZGUEhiaY5EjfAdw+d/rQmlcFwdTpMXCSGVk374QbCTlrA== +react-test-renderer@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-17.0.2.tgz#4cd4ae5ef1ad5670fc0ef776e8cc7e1231d9866c" + integrity sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ== dependencies: object-assign "^4.1.1" - react-is "^17.0.1" + react-is "^17.0.2" react-shallow-renderer "^16.13.1" - scheduler "^0.20.1" + scheduler "^0.20.2" react-tooltip@^4.2.13: version "4.2.13" @@ -12507,10 +12507,10 @@ react@^16.9.0: object-assign "^4.1.1" prop-types "^15.6.2" -react@^17.0.1: - version "17.0.1" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127" - integrity sha512-lG9c9UuMHdcAexXtigOZLX8exLWkW0Ku29qPRU8uhF2R9BN96dLCt0psvzPLlHc5OWkgymP3qwTRgbnw5BKx3w== +react@^17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" + integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -13169,10 +13169,10 @@ scheduler@^0.19.1: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.20.1: - version "0.20.1" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.1.tgz#da0b907e24026b01181ecbc75efdc7f27b5a000c" - integrity sha512-LKTe+2xNJBNxu/QhHvDR14wUXHRQbVY5ZOYpOGWRzhydZUqrLb2JBvLPY7cAqFmqrWuDED0Mjk7013SZiOz6Bw== +scheduler@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" + integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" From f04f37b92cf1929ff6b86ac8c8bdd6c2551d550c Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Tue, 23 Mar 2021 07:27:29 -0300 Subject: [PATCH 09/24] Update react-redux and translations --- frontend/package.json | 2 +- frontend/src/locales/ar.json | 2 +- frontend/src/locales/cs.json | 2 +- frontend/src/locales/de.json | 2 +- frontend/src/locales/el.json | 2 +- frontend/src/locales/es.json | 2 +- frontend/src/locales/fa_IR.json | 2 +- frontend/src/locales/fr.json | 2 +- frontend/src/locales/he.json | 2 +- frontend/src/locales/hu.json | 2 +- frontend/src/locales/id.json | 2 +- frontend/src/locales/it.json | 2 +- frontend/src/locales/ja.json | 2 +- frontend/src/locales/ko.json | 2 +- frontend/src/locales/mg.json | 2 +- frontend/src/locales/ml.json | 2 +- frontend/src/locales/nl_NL.json | 2 +- frontend/src/locales/pt.json | 2 +- frontend/src/locales/pt_BR.json | 2 +- frontend/src/locales/sv.json | 2 +- frontend/src/locales/sw.json | 2 +- frontend/src/locales/tl.json | 2 +- frontend/src/locales/tr.json | 2 +- frontend/src/locales/uk.json | 2 +- frontend/src/locales/zh_TW.json | 2 +- frontend/yarn.lock | 23 +++++++++++++++++------ 26 files changed, 42 insertions(+), 31 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 3f646fc7a8..73f2fa303a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -54,7 +54,7 @@ "react-intl": "^5.13.0", "react-meta-elements": "^1.0.0", "react-placeholder": "^4.1.0", - "react-redux": "^7.2.2", + "react-redux": "^7.2.3", "react-scripts": "^4.0.3", "react-select": "^4.3.0", "react-tooltip": "^4.2.13", diff --git a/frontend/src/locales/ar.json b/frontend/src/locales/ar.json index 41b7d1a57d..cfc4c12009 100644 --- a/frontend/src/locales/ar.json +++ b/frontend/src/locales/ar.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "", "management.organisations.tier.medium": "", diff --git a/frontend/src/locales/cs.json b/frontend/src/locales/cs.json index 8e8ac388a0..3b0ebc8632 100644 --- a/frontend/src/locales/cs.json +++ b/frontend/src/locales/cs.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Odhadovaná úroveň do konce {year}", "management.organisations.stats.cost.estimation": "Odhadované náklady do konce {year}", "management.organisations.stats.next_level.actions": "Akce k dosažení stupně {n}", - "management.organisations.stats.next_tier.actions": "Akce pro přechod na další úroveň", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "Zdarma", "management.organisations.tier.low": "Nízká", "management.organisations.tier.medium": "Střední", diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index 9bb2166e94..bcbce9944b 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Niedrig", "management.organisations.tier.medium": "Mittel", diff --git a/frontend/src/locales/el.json b/frontend/src/locales/el.json index c2e6dec312..8e1731b30b 100644 --- a/frontend/src/locales/el.json +++ b/frontend/src/locales/el.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Χαμηλή", "management.organisations.tier.medium": "Μεσαία", diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index d9eb3f85db..5d135b57aa 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Nivel estimado al final de {year}", "management.organisations.stats.cost.estimation": "Costo estimado al final de {year}", "management.organisations.stats.next_level.actions": "Acciones para alcanzar el nivel {n}", - "management.organisations.stats.next_tier.actions": "Acciones para pasar al siguiente nivel", + "management.organisations.stats.tier.actions_remaining": "Acciones restantes en el nivel {name}", "management.organisations.tier.free": "Libre", "management.organisations.tier.low": "Bajo", "management.organisations.tier.medium": "Medio", diff --git a/frontend/src/locales/fa_IR.json b/frontend/src/locales/fa_IR.json index 8e0f763160..fd4eeaff54 100644 --- a/frontend/src/locales/fa_IR.json +++ b/frontend/src/locales/fa_IR.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "پایین", "management.organisations.tier.medium": "متوسط", diff --git a/frontend/src/locales/fr.json b/frontend/src/locales/fr.json index 783d9c0d52..0ae0cc3ccf 100644 --- a/frontend/src/locales/fr.json +++ b/frontend/src/locales/fr.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Palier estimé à la fin de {year}", "management.organisations.stats.cost.estimation": "Coût estimé à la fin de {year}", "management.organisations.stats.next_level.actions": "Actions pour atteindre le niveau {n}", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "Libre", "management.organisations.tier.low": "Bas", "management.organisations.tier.medium": "Moyen", diff --git a/frontend/src/locales/he.json b/frontend/src/locales/he.json index d7481dbc70..1ee2d1544c 100644 --- a/frontend/src/locales/he.json +++ b/frontend/src/locales/he.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "שכבה משוערכת עד סוף {year}", "management.organisations.stats.cost.estimation": "עלות משוערכת עד לסוף {year}", "management.organisations.stats.next_level.actions": "פעולות כדי להגיע לשלב {n}", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "בחינם", "management.organisations.tier.low": "נמוכה", "management.organisations.tier.medium": "בינונית", diff --git a/frontend/src/locales/hu.json b/frontend/src/locales/hu.json index 0300cc4d98..fe5fe51162 100644 --- a/frontend/src/locales/hu.json +++ b/frontend/src/locales/hu.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Alacsony", "management.organisations.tier.medium": "Közepes", diff --git a/frontend/src/locales/id.json b/frontend/src/locales/id.json index f06f95b2f0..4208ca8df0 100644 --- a/frontend/src/locales/id.json +++ b/frontend/src/locales/id.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Rendah", "management.organisations.tier.medium": "Sedang", diff --git a/frontend/src/locales/it.json b/frontend/src/locales/it.json index 2bb05afb6e..16ae5b0396 100644 --- a/frontend/src/locales/it.json +++ b/frontend/src/locales/it.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Livello stimato entro la fine di {year}", "management.organisations.stats.cost.estimation": "Costo stimato entro la fine di {year}", "management.organisations.stats.next_level.actions": "Azioni per raggiungere il livello {n}", - "management.organisations.stats.next_tier.actions": "Azioni per salire al prossimo livello", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "Libero", "management.organisations.tier.low": "Bassa", "management.organisations.tier.medium": "Medio", diff --git a/frontend/src/locales/ja.json b/frontend/src/locales/ja.json index bf96c59f8d..5e78f6a348 100644 --- a/frontend/src/locales/ja.json +++ b/frontend/src/locales/ja.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "薄い", "management.organisations.tier.medium": "中", diff --git a/frontend/src/locales/ko.json b/frontend/src/locales/ko.json index d7a38e5a4e..f8c6c46724 100644 --- a/frontend/src/locales/ko.json +++ b/frontend/src/locales/ko.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "{year}년 말의 예상 티어", "management.organisations.stats.cost.estimation": "{year}년 말의 예상 비용", "management.organisations.stats.next_level.actions": "레벨 {n}에 도달하는 데 필요한 행동 수", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "없음", "management.organisations.tier.low": "낮음", "management.organisations.tier.medium": "중간", diff --git a/frontend/src/locales/mg.json b/frontend/src/locales/mg.json index cc6c300b27..bb420d25e6 100644 --- a/frontend/src/locales/mg.json +++ b/frontend/src/locales/mg.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Ambany", "management.organisations.tier.medium": "Antoniny", diff --git a/frontend/src/locales/ml.json b/frontend/src/locales/ml.json index 2cfbcf6055..bc5680f8e1 100644 --- a/frontend/src/locales/ml.json +++ b/frontend/src/locales/ml.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "", "management.organisations.tier.medium": "", diff --git a/frontend/src/locales/nl_NL.json b/frontend/src/locales/nl_NL.json index 2de7d9d721..a16af4627f 100644 --- a/frontend/src/locales/nl_NL.json +++ b/frontend/src/locales/nl_NL.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Geschatte fase aan het einde van {year}", "management.organisations.stats.cost.estimation": "Geschatte kosten aan het einde van {year}", "management.organisations.stats.next_level.actions": "Acties om het niveau {n} te bereiken", - "management.organisations.stats.next_tier.actions": "Acties om door te gaan naar de volgende fase", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "Vrij", "management.organisations.tier.low": "Laag", "management.organisations.tier.medium": "Normaal", diff --git a/frontend/src/locales/pt.json b/frontend/src/locales/pt.json index 663d15fb77..5ca74ac7ff 100644 --- a/frontend/src/locales/pt.json +++ b/frontend/src/locales/pt.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Baixa", "management.organisations.tier.medium": "Média", diff --git a/frontend/src/locales/pt_BR.json b/frontend/src/locales/pt_BR.json index efa8f80e2b..015a5577bf 100644 --- a/frontend/src/locales/pt_BR.json +++ b/frontend/src/locales/pt_BR.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Nível estimado até o final de {year}", "management.organisations.stats.cost.estimation": "Custo estimado até o final de {year}", "management.organisations.stats.next_level.actions": "Ações para atingir o nível {n}", - "management.organisations.stats.next_tier.actions": "Ações para passar ao próximo nível", + "management.organisations.stats.tier.actions_remaining": "Ações restantes no nível {name}", "management.organisations.tier.free": "Grátis", "management.organisations.tier.low": "Baixo", "management.organisations.tier.medium": "Média", diff --git a/frontend/src/locales/sv.json b/frontend/src/locales/sv.json index b5073fc4ca..8412283582 100644 --- a/frontend/src/locales/sv.json +++ b/frontend/src/locales/sv.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Låg", "management.organisations.tier.medium": "Medium", diff --git a/frontend/src/locales/sw.json b/frontend/src/locales/sw.json index df6e1190bb..43a5c7c78c 100644 --- a/frontend/src/locales/sw.json +++ b/frontend/src/locales/sw.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Chini", "management.organisations.tier.medium": "Kati", diff --git a/frontend/src/locales/tl.json b/frontend/src/locales/tl.json index 2cfbcf6055..bc5680f8e1 100644 --- a/frontend/src/locales/tl.json +++ b/frontend/src/locales/tl.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "", "management.organisations.tier.medium": "", diff --git a/frontend/src/locales/tr.json b/frontend/src/locales/tr.json index 49c819d3eb..56235ba1e4 100644 --- a/frontend/src/locales/tr.json +++ b/frontend/src/locales/tr.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "Düşük", "management.organisations.tier.medium": "Orta", diff --git a/frontend/src/locales/uk.json b/frontend/src/locales/uk.json index a0492b3071..a39f147d3a 100644 --- a/frontend/src/locales/uk.json +++ b/frontend/src/locales/uk.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "Прогнозований рівень до кінця {year} року", "management.organisations.stats.cost.estimation": "Орієнтовна вартість до кінця {year} року", "management.organisations.stats.next_level.actions": "Дій залишилось до рівня {n}", - "management.organisations.stats.next_tier.actions": "Для переходу не наступний рівень виконайте", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "Вільно", "management.organisations.tier.low": "Неважливий", "management.organisations.tier.medium": "Середній", diff --git a/frontend/src/locales/zh_TW.json b/frontend/src/locales/zh_TW.json index 6930ab236e..5f8e5e3cc5 100644 --- a/frontend/src/locales/zh_TW.json +++ b/frontend/src/locales/zh_TW.json @@ -734,7 +734,7 @@ "management.organisations.stats.tier.estimation": "", "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", - "management.organisations.stats.next_tier.actions": "", + "management.organisations.stats.tier.actions_remaining": "", "management.organisations.tier.free": "", "management.organisations.tier.low": "低", "management.organisations.tier.medium": "中等", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 30301d9620..3ff7db2aa4 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -3432,7 +3432,7 @@ dependencies: "@types/node" "*" -"@types/hoist-non-react-statics@^3.3.1": +"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== @@ -3560,6 +3560,16 @@ dependencies: "@types/react" "*" +"@types/react-redux@^7.1.16": + version "7.1.16" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.16.tgz#0fbd04c2500c12105494c83d4a3e45c084e3cb21" + integrity sha512-f/FKzIrZwZk7YEO9E1yoxIuDNRiDducxkFlkw/GNMGEnK9n4K8wJzlJBghpSuOVDgEUHoDkDF7Gi9lHNQR4siw== + dependencies: + "@types/hoist-non-react-statics" "^3.3.0" + "@types/react" "*" + hoist-non-react-statics "^3.3.0" + redux "^4.0.0" + "@types/react-test-renderer@>=16.9.0": version "17.0.0" resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.0.tgz#9be47b375eeb906fced37049e67284a438d56620" @@ -12360,12 +12370,13 @@ react-popper@^1.3.8: typed-styles "^0.0.7" warning "^4.0.2" -react-redux@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.2.tgz#03862e803a30b6b9ef8582dadcc810947f74b736" - integrity sha512-8+CQ1EvIVFkYL/vu6Olo7JFLWop1qRUeb46sGtIMDCSpgwPQq8fPLpirIB0iTqFe9XYEFPHssdX8/UwN6pAkEA== +react-redux@^7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.3.tgz#4c084618600bb199012687da9e42123cca3f0be9" + integrity sha512-ZhAmQ1lrK+Pyi0ZXNMUZuYxYAZd59wFuVDGUt536kSGdD0ya9Q7BfsE95E3TsFLE3kOSFp5m6G5qbatE+Ic1+w== dependencies: "@babel/runtime" "^7.12.1" + "@types/react-redux" "^7.1.16" hoist-non-react-statics "^3.3.2" loose-envify "^1.4.0" prop-types "^15.7.2" @@ -12643,7 +12654,7 @@ redux-thunk@^2.3.0: resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== -redux@^4.0.5: +redux@^4.0.0, redux@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== From f375c2a3af94e7310a1c95a6517799c0985bc892 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Tue, 23 Mar 2021 09:08:23 -0300 Subject: [PATCH 10/24] Add some predefined global imagery options to project edit page (#4404) * Add some predefined global imagery options to project edit page * Update Imagery component to handle new imagery predefined settings * handle other imagery when loading tasks on external iD / RapiD editors --- frontend/src/components/editor.js | 21 +- .../projectDetail/tests/infoPanel.test.js | 4 +- .../src/components/projectEdit/imageryForm.js | 93 ++++--- .../src/components/projectEdit/messages.js | 8 +- frontend/src/components/svgIcons/clipboard.js | 2 +- .../src/components/taskSelection/action.js | 2 +- .../src/components/taskSelection/imagery.js | 75 +++--- .../src/components/taskSelection/messages.js | 4 + .../taskSelection/tests/imagery.test.js | 228 +++++++++++++----- frontend/src/hooks/UseImageryOption.js | 26 ++ .../src/hooks/tests/UseImageryOption.test.js | 28 +++ frontend/src/locales/en.json | 4 +- frontend/src/utils/openEditor.js | 8 +- frontend/src/utils/tests/openEditor.test.js | 8 +- 14 files changed, 373 insertions(+), 138 deletions(-) create mode 100644 frontend/src/hooks/UseImageryOption.js create mode 100644 frontend/src/hooks/tests/UseImageryOption.test.js diff --git a/frontend/src/components/editor.js b/frontend/src/components/editor.js index 4ac60fdc80..298f2a83b8 100644 --- a/frontend/src/components/editor.js +++ b/frontend/src/components/editor.js @@ -5,7 +5,7 @@ import '@hotosm/id/dist/iD.css'; import { OSM_CONSUMER_KEY, OSM_CONSUMER_SECRET, OSM_SERVER_URL } from '../config'; -export default function Editor({ setDisable, comment, presets, imageryUrl, gpxUrl }) { +export default function Editor({ setDisable, comment, presets, imagery, gpxUrl }) { const dispatch = useDispatch(); const session = useSelector((state) => state.auth.get('session')); const iDContext = useSelector((state) => state.editor.context); @@ -16,13 +16,20 @@ export default function Editor({ setDisable, comment, presets, imageryUrl, gpxUr iDContext && iDContext.background() && iDContext.background().findSource('custom'); useEffect(() => { - if (!customImageryIsSet && imageryUrl && customSource) { - iDContext.background().baseLayerSource(customSource.template(imageryUrl)); - setCustomImageryIsSet(true); - // this line is needed to update the value on the custom background dialog - window.iD.prefs('background-custom-template', imageryUrl); + if (!customImageryIsSet && imagery && customSource) { + if (imagery.startsWith('http')) { + iDContext.background().baseLayerSource(customSource.template(imagery)); + setCustomImageryIsSet(true); + // this line is needed to update the value on the custom background dialog + window.iD.prefs('background-custom-template', imagery); + } else { + const imagerySource = iDContext.background().findSource(imagery); + if (imagerySource) { + iDContext.background().baseLayerSource(imagerySource); + } + } } - }, [customImageryIsSet, imageryUrl, iDContext, customSource]); + }, [customImageryIsSet, imagery, iDContext, customSource]); useEffect(() => { return () => { diff --git a/frontend/src/components/projectDetail/tests/infoPanel.test.js b/frontend/src/components/projectDetail/tests/infoPanel.test.js index 291f8f5d99..54ad9207f2 100644 --- a/frontend/src/components/projectDetail/tests/infoPanel.test.js +++ b/frontend/src/components/projectDetail/tests/infoPanel.test.js @@ -107,7 +107,7 @@ describe('if projectInfoPanel', () => { render( { ); expect(screen.getByText('Types of Mapping')).toBeInTheDocument(); expect(screen.getByText('Imagery')).toBeInTheDocument(); - expect(screen.queryByText('Custom')).toBeInTheDocument(); + expect(screen.queryByText('Mapbox Satellite')).toBeInTheDocument(); expect(screen.queryByText(/No contributors yet/)).toBeInTheDocument(); expect(screen.queryByText('Last contribution 1 hour ago')).toBeInTheDocument(); expect(screen.queryByText('Intermediate mapper')).toBeInTheDocument(); diff --git a/frontend/src/components/projectEdit/imageryForm.js b/frontend/src/components/projectEdit/imageryForm.js index bbd7ae1bb2..1bd3d34a93 100644 --- a/frontend/src/components/projectEdit/imageryForm.js +++ b/frontend/src/components/projectEdit/imageryForm.js @@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl'; import messages from './messages'; import { StateContext, styleClasses } from '../../views/projectEdit'; import { fetchLocalJSONAPI } from '../../network/genericJSONRequest'; +import { useImageryOption, IMAGERY_OPTIONS } from '../../hooks/UseImageryOption'; export const ImageryForm = () => { const { projectInfo, setProjectInfo } = useContext(StateContext); @@ -19,38 +20,18 @@ export const ImageryForm = () => { fetchLicenses(); }, [setLicenses]); - const handleChange = (event) => { - setProjectInfo({ ...projectInfo, [event.target.name]: event.target.value }); - }; - let defaultValue = null; if (licenses !== null && projectInfo.licenseId !== null) { defaultValue = licenses.filter((l) => l.licenseId === projectInfo.licenseId)[0]; - //defaultValue = { name: license.name, value: license.licenseId }; } return (
- -

- -

+
); }; + +const ImageryField = ({ imagery, setProjectInfo }) => { + const imageryValue = useImageryOption(imagery); + const [showInputField, setShowInputField] = useState( + imageryValue && imageryValue.value === 'custom' ? true : false, + ); + + const onInputChange = (e) => setProjectInfo((p) => ({ ...p, imagery: e.target.value })); + + const onSelectChange = (option) => { + if (option) { + if (option.value === 'custom') { + setShowInputField(true); + setProjectInfo((p) => ({ ...p, imagery: 'https://...' })); + } else { + setShowInputField(false); + setProjectInfo((p) => ({ ...p, imagery: option.value })); + } + } else { + setShowInputField(false); + setProjectInfo((p) => ({ ...p, imagery: null })); + } + }; + + return ( + <> + +

+ +

+ + )} + + ); +}; diff --git a/frontend/src/components/projectEdit/messages.js b/frontend/src/components/projectEdit/messages.js index ed3bcb821a..4ac00dc69c 100644 --- a/frontend/src/components/projectEdit/messages.js +++ b/frontend/src/components/projectEdit/messages.js @@ -38,6 +38,10 @@ export default defineMessages({ defaultMessage: 'Organization that is coordinating the project, if there is any. The managers of that organization will have administration rights over the project.', }, + selectImagery: { + id: 'projects.formInputs.imagery.select', + defaultMessage: 'Select imagery', + }, selectLicense: { id: 'projects.formInputs.license.select', defaultMessage: 'Select license', @@ -335,9 +339,9 @@ export default defineMessages({ defaultMessage: 'If checked, users must edit tasks at random for the initial editing stage (managers and admins are exempt).', }, - imageryURL: { + imagery: { id: 'projects.formInputs.imagery', - defaultMessage: 'Imagery URL', + defaultMessage: 'Imagery', }, imageryURLNote: { id: 'projects.formInputs.imagery.note', diff --git a/frontend/src/components/svgIcons/clipboard.js b/frontend/src/components/svgIcons/clipboard.js index 2b5058459d..b37ffdf6cb 100644 --- a/frontend/src/components/svgIcons/clipboard.js +++ b/frontend/src/components/svgIcons/clipboard.js @@ -5,7 +5,7 @@ import React from 'react'; export class ClipboardIcon extends React.PureComponent { render() { return ( - + diff --git a/frontend/src/components/taskSelection/imagery.js b/frontend/src/components/taskSelection/imagery.js index 44df574023..a593e7da12 100644 --- a/frontend/src/components/taskSelection/imagery.js +++ b/frontend/src/components/taskSelection/imagery.js @@ -1,49 +1,60 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; +import { FormattedMessage, useIntl } from 'react-intl'; import { useCopyClipboard } from '@lokibai/react-use-copy-clipboard'; import messages from './messages'; import { ClipboardIcon } from '../svgIcons'; +import { useImageryOption } from '../../hooks/UseImageryOption'; -export function Imagery({ value = '' }: Object) { - //eslint-disable-next-line - const [isCopied, setCopied] = useCopyClipboard(); - - let content = {value}; - let copyButton; - let messageId; - if (value) { - if (value.startsWith('tms')) { - messageId = 'customTMSLayer'; +function getCustomMessageId(imagery) { + if (imagery) { + if (imagery.startsWith('tms')) { + return 'customTMSLayer'; } - if (value.startsWith('wms')) { - messageId = 'customWMSLayer'; + if (imagery.startsWith('wms')) { + return 'customWMSLayer'; } - if (value.startsWith('wmts')) { - messageId = 'customWMTSLayer'; + if (imagery.startsWith('wmts')) { + return 'customWMTSLayer'; } - if (value.startsWith('http') || value.startsWith('https')) { - messageId = 'customLayer'; + if (imagery.startsWith('http') || imagery.startsWith('https')) { + return 'customLayer'; } - if (messageId) { - content = ( + } +} + +export function Imagery({ value = '' }: Object) { + const intl = useIntl(); + //eslint-disable-next-line + const [isCopied, setCopied] = useCopyClipboard(); + const imageryOption = useImageryOption(value); + const customMessageId = getCustomMessageId(value); + + return ( +

+ {customMessageId && ( // show wms, wmts, tms, or other custom layers - + - ); - copyButton = ( - + )} + + {imageryOption !== null && imageryOption.value !== 'custom' && ( + // show Bing, Mapbox, ESRI and Maxar layers + {imageryOption.label} + )} + {!customMessageId && imageryOption !== null && imageryOption.value === 'custom' && ( + // other not recognized custom layers, example: Digital Globe + {value} + )} + {!imageryOption && } + {customMessageId && ( + setCopied(value)} /> - ); - } - } else { - content = ; - } - return ( -

- {content} - {copyButton} + )}

); } diff --git a/frontend/src/components/taskSelection/messages.js b/frontend/src/components/taskSelection/messages.js index 1b2a31c00c..baa7a01509 100644 --- a/frontend/src/components/taskSelection/messages.js +++ b/frontend/src/components/taskSelection/messages.js @@ -191,6 +191,10 @@ export default defineMessages({ id: 'project.imagery.noDefined', defaultMessage: 'Any available source', }, + copyImageryURL: { + id: 'project.imagery.copy', + defaultMessage: 'Copy imagery URL', + }, mapATask: { id: 'project.selectTask.footer.button.mapRandomTask', defaultMessage: 'Map a task', diff --git a/frontend/src/components/taskSelection/tests/imagery.test.js b/frontend/src/components/taskSelection/tests/imagery.test.js index e761251097..1fda1c1c07 100644 --- a/frontend/src/components/taskSelection/tests/imagery.test.js +++ b/frontend/src/components/taskSelection/tests/imagery.test.js @@ -1,71 +1,179 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; -import { createComponentWithIntl } from '../../../utils/testWithIntl'; +import { IntlProviders } from '../../../utils/testWithIntl'; import { Imagery } from '../imagery'; -it('test if Imagery returns the correct FormattedMessage to TMS', () => { - const element = createComponentWithIntl( - , - ); - const testInstance = element.root; - expect(testInstance.findByType(FormattedMessage).props.id).toBe('project.imagery.tms'); -}); +describe('Imagery', () => { + it('with a TMS layer starting with tms[]', () => { + render( + + + , + ); + expect(screen.getByText('Custom TMS Layer')).toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); + expect(screen.getByRole('img').closest('span').className).toBe( + 'pointer pl2 blue-light hover-blue-dark', + ); + expect(screen.getByRole('img').closest('span').title).toBe('Copy imagery URL'); + }); -it('test if Imagery returns the correct FormattedMessage to TMS, even without the zoom level information', () => { - const element = createComponentWithIntl( - , - ); - const testInstance = element.root; - expect(testInstance.findByType(FormattedMessage).props.id).toBe('project.imagery.tms'); -}); + it('with a TMS layer starting with tms:', () => { + render( + + + , + ); + expect(screen.getByText('Custom TMS Layer')).toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); + }); -it('test if Imagery returns the correct FormattedMessage to WMS', () => { - const element = createComponentWithIntl( - , - ); - const testInstance = element.root; - expect(testInstance.findByType(FormattedMessage).props.id).toBe('project.imagery.wms'); -}); + it('with a WMS layer starting with wms[]', () => { + render( + + + , + ); + expect(screen.getByText('Custom WMS Layer')).toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); + }); -it('test if Imagery returns the correct FormattedMessage to WMTS', () => { - const element = createComponentWithIntl( - , - ); - const testInstance = element.root; - expect(testInstance.findByType(FormattedMessage).props.id).toBe('project.imagery.wmts'); -}); + it('with a WMTS layer starting with wmts', () => { + render( + + + , + ); + expect(screen.getByText('Custom WMTS Layer')).toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); + }); -it('test if Imagery returns the correct FormattedMessage to custom layer', () => { - const element = createComponentWithIntl( - , - ); - const testInstance = element.root; - expect(testInstance.findByType(FormattedMessage).props.id).toBe('project.imagery.customLayer'); -}); + it('with a custom https layer', () => { + render( + + + , + ); + expect(screen.getByText('Custom Layer')).toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); + }); -it('test if Imagery returns the correct imagery layer name', () => { - const element = createComponentWithIntl(); - const testInstance = element.root; - expect(testInstance.findByType('span').children).toEqual(['Mapbox Satellite']); -}); + it('with a custom http layer', () => { + render( + + + , + ); + expect(screen.getByText('Custom Layer')).toBeInTheDocument(); + expect( + screen.queryByText('http://s3.amazonaws.com/layer/{zoom}/{x}/{y}.jpg'), + ).not.toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); + }); + + it('with a Mapbox layer', () => { + render( + + + , + ); + expect(screen.getByText('Mapbox Satellite')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('with a Bing layer', () => { + render( + + + , + ); + expect(screen.getByText('Bing')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('with a EsriWorldImagery layer', () => { + render( + + + , + ); + expect(screen.getByText('ESRI World Imagery')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('with a EsriWorldImageryClarity layer', () => { + render( + + + , + ); + expect(screen.getByText('ESRI World Imagery (Clarity) Beta')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('with a Maxar-Premium layer', () => { + render( + + + , + ); + expect(screen.getByText('Maxar Premium')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('with a Maxar-Standard layer', () => { + render( + + + , + ); + expect(screen.getByText('Maxar Standard')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('with a null imagery value', () => { + render( + + + , + ); + expect(screen.getByText('Any available source')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); + + it('with a Mapbox Satellite layer', () => { + render( + + + , + ); + expect(screen.getByText('Mapbox Satellite')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); -it('test if Imagery returns the correct FormattedMessage to undefined imagery', () => { - const element = createComponentWithIntl(); - const testInstance = element.root; - expect(testInstance.findByType(FormattedMessage).props.id).toEqual('project.imagery.noDefined'); + it('with a Mapbox Satellite layer', () => { + render( + + + , + ); + expect(screen.getByText('Digital Globe')).toBeInTheDocument(); + expect(screen.queryByRole('img')).not.toBeInTheDocument(); + }); }); diff --git a/frontend/src/hooks/UseImageryOption.js b/frontend/src/hooks/UseImageryOption.js new file mode 100644 index 0000000000..e455306295 --- /dev/null +++ b/frontend/src/hooks/UseImageryOption.js @@ -0,0 +1,26 @@ +import { useMemo } from 'react'; + +export const IMAGERY_OPTIONS = [ + { label: 'Bing', value: 'Bing' }, + { label: 'Mapbox Satellite', value: 'Mapbox' }, + { label: 'ESRI World Imagery', value: 'EsriWorldImagery' }, + { label: 'ESRI World Imagery (Clarity) Beta', value: 'EsriWorldImageryClarity' }, + { label: 'Maxar Premium', value: 'Maxar-Premium' }, + { label: 'Maxar Standard', value: 'Maxar-Standard' }, + { label: 'Custom', value: 'custom' }, +]; + +export const useImageryOption = (imagery) => { + const getImagery = useMemo(() => { + if (imagery) { + const filtered = IMAGERY_OPTIONS.filter((i) => i.value === imagery); + if (filtered.length) { + return filtered[0]; + } + return IMAGERY_OPTIONS[IMAGERY_OPTIONS.length - 1]; + } else { + return null; + } + }, [imagery]); + return getImagery; +}; diff --git a/frontend/src/hooks/tests/UseImageryOption.test.js b/frontend/src/hooks/tests/UseImageryOption.test.js new file mode 100644 index 0000000000..c1f071ecb3 --- /dev/null +++ b/frontend/src/hooks/tests/UseImageryOption.test.js @@ -0,0 +1,28 @@ +import { renderHook } from '@testing-library/react-hooks'; + +import { useImageryOption } from '../UseImageryOption'; + +describe('useImageryOption', () => { + it('returns custom if a custom imagery is used', () => { + const { result } = renderHook(() => + useImageryOption('https://tiles.osm.org/{zoom}/{x}/{y}.png'), + ); + expect(result.current).toEqual({ label: 'Custom', value: 'custom' }); + }); + it('with Bing', () => { + const { result } = renderHook(() => useImageryOption('Bing')); + expect(result.current).toEqual({ label: 'Bing', value: 'Bing' }); + }); + it('with Maxar-Premium', () => { + const { result } = renderHook(() => useImageryOption('Maxar-Premium')); + expect(result.current).toEqual({ label: 'Maxar Premium', value: 'Maxar-Premium' }); + }); + it('with EsriWorldImagery', () => { + const { result } = renderHook(() => useImageryOption('EsriWorldImagery')); + expect(result.current).toEqual({ label: 'ESRI World Imagery', value: 'EsriWorldImagery' }); + }); + it('when receives null, returns null', () => { + const { result } = renderHook(() => useImageryOption(null)); + expect(result.current).toEqual(null); + }); +}); diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 32b638a0ec..b563d34016 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -317,6 +317,7 @@ "projects.formInputs.campaign.title": "Campaign", "projects.formInputs.categories.title": "Categories", "projects.formInputs.organisation.description": "Organization that is coordinating the project, if there is any. The managers of that organization will have administration rights over the project.", + "projects.formInputs.imagery.select": "Select imagery", "projects.formInputs.license.select": "Select license", "projects.formInputs.organisation.select": "Select organization", "projects.formInputs.campaign.select": "Select campaigns", @@ -388,7 +389,7 @@ "projects.formInputs.random_task_selection": "Enforce random task selection", "projects.formInputs.random_task_selection.mapping": "Enforce random task selection on mapping", "projects.formInputs.random_task_selection.description": "If checked, users must edit tasks at random for the initial editing stage (managers and admins are exempt).", - "projects.formInputs.imagery": "Imagery URL", + "projects.formInputs.imagery": "Imagery", "projects.formInputs.imagery.note": "Follow this format for TMS URLs: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Draw polygon", "projects.formInputs.priority_areas.options.rectangle": "Draw rectangle", @@ -556,6 +557,7 @@ "project.imagery.wmts": "Custom WMTS Layer", "project.imagery.customLayer": "Custom Layer", "project.imagery.noDefined": "Any available source", + "project.imagery.copy": "Copy imagery URL", "project.selectTask.footer.button.mapRandomTask": "Map a task", "project.selectTask.footer.button.mapSelectedTask": "Map selected task", "project.selectTask.footer.button.mapAnotherTask": "Map another task", diff --git a/frontend/src/utils/openEditor.js b/frontend/src/utils/openEditor.js index 761ff3b242..d9b2d3194e 100644 --- a/frontend/src/utils/openEditor.js +++ b/frontend/src/utils/openEditor.js @@ -80,8 +80,12 @@ export function getIdUrl(project, centroid, zoomLevel, selectedTasks, customUrl) if (project.changesetComment) { url += '&comment=' + encodeURIComponent(project.changesetComment); } - if (project.imagery && project.imagery.includes('http')) { - url += '&background=custom:' + encodeURIComponent(formatImageryUrl(project.imagery)); + if (project.imagery) { + if (project.imagery.includes('http')) { + url += '&background=custom:' + encodeURIComponent(formatImageryUrl(project.imagery)); + } else { + url += '&background=' + encodeURIComponent(formatImageryUrl(project.imagery)); + } } // add GPX if (project.projectId && selectedTasks) { diff --git a/frontend/src/utils/tests/openEditor.test.js b/frontend/src/utils/tests/openEditor.test.js index 63a607add4..1bc513c972 100644 --- a/frontend/src/utils/tests/openEditor.test.js +++ b/frontend/src/utils/tests/openEditor.test.js @@ -89,12 +89,13 @@ describe('test if getIdUrl', () => { const testProject = { changesetComment: '#hotosm-project-5522', projectId: 1234, - imagery: 'Bing', + imagery: 'Maxar-Premium', }; expect(getIdUrl(testProject, [120.25684, -9.663953], 18, [1, 2])).toBe( 'https://www.openstreetmap.org/edit?editor=id&' + '#map=18/-9.663953/120.25684' + '&comment=%23hotosm-project-5522' + + '&background=Maxar-Premium' + '&gpx=http%3A%2F%2F127.0.0.1%3A5000%2Fapi%2Fv2%2Fprojects%2F1234%2Ftasks%2Fqueries%2Fgpx%2F%3Ftasks%3D1%2C2', ); }); @@ -205,4 +206,9 @@ describe('formatImageryUrl', () => { 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', ); }); + it('in case the imagery is not an URL, return the same string', () => { + expect(formatImageryUrl('Bing')).toBe('Bing'); + expect(formatImageryUrl('EsriWorldImageryClarity')).toBe('EsriWorldImageryClarity'); + expect(formatImageryUrl('Maxar-Premium')).toBe('Maxar-Premium'); + }); }); From 0b2d9d0fba053dd2a32d4b62a3d2f149a283f3ca Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Mon, 22 Mar 2021 18:21:58 -0300 Subject: [PATCH 11/24] Update react-intl to 5.13.5. Fix and improve DueDateBox & TaskCard tests --- frontend/package.json | 2 +- .../contributions/tests/taskCard.test.js | 3 +- .../src/components/projectCard/dueDateBox.js | 20 ++-- .../projectCard/tests/dueDateBox.test.js | 60 ++++++---- frontend/src/components/svgIcons/clock.js | 2 +- frontend/src/views/tests/projectStats.test.js | 6 +- frontend/yarn.lock | 113 +++++++----------- 7 files changed, 96 insertions(+), 110 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 73f2fa303a..3030165afd 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -51,7 +51,7 @@ "react-dom": "^17.0.2", "react-dropzone": "^11.3.1", "react-final-form": "^6.5.3", - "react-intl": "^5.13.0", + "react-intl": "^5.13.5", "react-meta-elements": "^1.0.0", "react-placeholder": "^4.1.0", "react-redux": "^7.2.3", diff --git a/frontend/src/components/contributions/tests/taskCard.test.js b/frontend/src/components/contributions/tests/taskCard.test.js index c38aa319e3..36a778b549 100644 --- a/frontend/src/components/contributions/tests/taskCard.test.js +++ b/frontend/src/components/contributions/tests/taskCard.test.js @@ -84,7 +84,8 @@ describe('TaskCard', () => { taskStatus={'LOCKED_FOR_VALIDATION'} lockHolder={'user_1'} taskHistory={[]} - lastUpdated={'2021-01-22T12:59:37.238281Z'} + lastUpdated={new Date()} + autoUnlockSeconds={120 * 60} /> , ); diff --git a/frontend/src/components/projectCard/dueDateBox.js b/frontend/src/components/projectCard/dueDateBox.js index 8d70e98fbc..983e93dc21 100644 --- a/frontend/src/components/projectCard/dueDateBox.js +++ b/frontend/src/components/projectCard/dueDateBox.js @@ -27,24 +27,24 @@ export function DueDateBox({ dueDate, intervalMili, align = 'right', tooltipMsg let options = { language: intl.locale.slice(0, 2), fallbacks: ['en'], largest: 1 }; - let className = `dib relative lh-solid f7 tr ${ - align === 'right' ? 'fr' : 'fl' - } br1 link ph1 pv2 bg-grey-light blue-grey truncate mw4`; - if (intervalMili !== undefined) { - className = className.replace('mw4', ''); options = { units: ['h', 'm'], round: true }; } - const milliDifference = new Date(dueDate) - timer; - if (milliDifference < 60000 * 20 && intervalMili !== undefined) { - className = className.replace('bg-grey-light', 'bg-red').replace('blue-grey', 'white'); - } if (milliDifference > 0) { return ( <> - + diff --git a/frontend/src/components/projectCard/tests/dueDateBox.test.js b/frontend/src/components/projectCard/tests/dueDateBox.test.js index 633faf31ac..3358e4c398 100644 --- a/frontend/src/components/projectCard/tests/dueDateBox.test.js +++ b/frontend/src/components/projectCard/tests/dueDateBox.test.js @@ -1,38 +1,56 @@ import React from 'react'; -import ReactTooltip from 'react-tooltip'; +import userEvent from '@testing-library/user-event'; +import { render, screen } from '@testing-library/react'; +import '@testing-library/jest-dom'; import { DueDateBox } from '../../../components/projectCard/dueDateBox'; -import { createComponentWithIntl } from '../../../utils/testWithIntl'; +import { ReduxIntlProviders } from '../../../utils/testWithIntl'; describe('test DueDate', () => { it('relative date formatting in English', () => { // six days of milliseconds plus a few seconds for the test const sixDaysOut = 6 * 86400 * 1000 + 10000 + Date.now(); - const testDueDateBox = createComponentWithIntl(); - const testInstance = testDueDateBox.root; - expect(testInstance.findByType(DueDateBox).props.dueDate).toBe(sixDaysOut); - expect(() => testInstance.findByType(ReactTooltip)).toThrow( - new Error('No instances found with node type: "ReactTooltip"'), + const { container } = render( + + + , ); - expect( - //find the FormattedMessage rendered component - testInstance.findByProps({ className: 'indent' }).children, - ).toContain('6 days left'); + expect(container.querySelectorAll('span')[0].className).toContain('fr'); + expect(container.querySelectorAll('span')[0].className).not.toContain('fl'); + expect(screen.getByText('6 days left')).toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); }); it('with tooltip message', () => { // five days of milliseconds plus a few seconds for the test const fiveDaysOut = 5 * 86400 * 1000 + 10000 + Date.now(); - const testDueDateBox = createComponentWithIntl( - , + const { container } = render( + + + , ); - const testInstance = testDueDateBox.root; - expect(testInstance.findByType(DueDateBox).props.dueDate).toBe(fiveDaysOut); - expect(testInstance.findByType(ReactTooltip).props.place).toBe('bottom'); - expect(testInstance.findAllByType('span')[0].props['data-tip']).toBe('Tooltip works'); - expect( - //find the FormattedMessage rendered component - testInstance.findByProps({ className: 'indent' }).children, - ).toContain('5 days left'); + expect(screen.queryByText('Tooltip works')).not.toBeInTheDocument(); + userEvent.hover(screen.getByText('5 days left')); + expect(screen.getByText('Tooltip works')).toBeInTheDocument(); + expect(container.querySelectorAll('span')[0].className).toContain('fl'); + expect(container.querySelectorAll('span')[0].className).toContain('bg-grey-light blue-grey'); + expect(container.querySelectorAll('span')[0].className).not.toContain('fr'); + expect(container.querySelectorAll('span')[0].className).not.toContain('bg-red white fw6'); + }); + + it('relative date formatting in English', () => { + const { container } = render( + + + , + ); + expect(container.querySelectorAll('span')[0].className).toContain('fr'); + expect(container.querySelectorAll('span')[0].className).toContain('bg-red white fw6'); + expect(container.querySelectorAll('span')[0].className).not.toContain('fl'); + expect(container.querySelectorAll('span')[0].className).not.toContain( + 'bg-grey-light blue-grey', + ); + expect(screen.getByText('9 minutes left')).toBeInTheDocument(); + expect(screen.getByRole('img')).toBeInTheDocument(); }); }); diff --git a/frontend/src/components/svgIcons/clock.js b/frontend/src/components/svgIcons/clock.js index e43d6e3970..f61991a0e0 100644 --- a/frontend/src/components/svgIcons/clock.js +++ b/frontend/src/components/svgIcons/clock.js @@ -3,7 +3,7 @@ import React from 'react'; export class ClockIcon extends React.PureComponent { render() { return ( - + diff --git a/frontend/src/views/tests/projectStats.test.js b/frontend/src/views/tests/projectStats.test.js index 19d3df47bc..9053667e31 100644 --- a/frontend/src/views/tests/projectStats.test.js +++ b/frontend/src/views/tests/projectStats.test.js @@ -47,10 +47,10 @@ describe('ProjectStats dashboard', () => { expect(screen.getByText('Changesets')).toBeInTheDocument(); expect(screen.getByText('Total map edits')).toBeInTheDocument(); expect(screen.getByText('Tasks by status')).toBeInTheDocument(); - expect(screen.getByText('Contributors')).toBeInTheDocument(); expect(screen.getByText('Project timeline')).toBeInTheDocument(); - await waitFor(() => screen.getByText('Time statistics')); expect(screen.getByText('Time statistics')).toBeInTheDocument(); - }, 10000); + await waitFor(() => screen.getByText('Contributors')); + expect(screen.getByText('Contributors')).toBeInTheDocument(); + }); }); diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 3ff7db2aa4..ed972d9659 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2208,13 +2208,6 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@formatjs/ecma402-abstract@1.6.1": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.6.1.tgz#05eb0d879a00509525818e89ef2a0a833aa52b27" - integrity sha512-GQJ+mK4rrbpdXjFzwK/5NIalxBOjCLI4ZuCCvReLQGwq1ICViIIgLQw1wP95doZFjH5Y9WaQ8Zzl8+A9IkxAsQ== - dependencies: - tslib "^2.1.0" - "@formatjs/ecma402-abstract@1.6.3": version "1.6.3" resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.6.3.tgz#f82bd2cf3aa8aaa0f12f9339902942b8d4b96912" @@ -2222,20 +2215,12 @@ dependencies: tslib "^2.1.0" -"@formatjs/intl-datetimeformat@3.2.11": - version "3.2.11" - resolved "https://registry.yarnpkg.com/@formatjs/intl-datetimeformat/-/intl-datetimeformat-3.2.11.tgz#9c4af24231126a70766b0147aec1f859d00de286" - integrity sha512-43r8MMqnHyqj8cSpiKucuTkI3erSk9BW6LQgy3xetHz43ibVRXlPcIadJFd/SQxHAVzUTw72FPLKWJqnmOfPXg== - dependencies: - "@formatjs/ecma402-abstract" "1.6.1" - tslib "^2.1.0" - -"@formatjs/intl-displaynames@4.0.9": - version "4.0.9" - resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-4.0.9.tgz#9c6ee00ed1d6c082758395300959b073bf1b5561" - integrity sha512-dGztRkkCzlGWH3WJYIZhBoR6wKCG1LOSH7T6dv3z08P7Ec9OKPM9481MzLh/xM58AWNhTjpwKSplTCbK/vus5w== +"@formatjs/intl-displaynames@4.0.11": + version "4.0.11" + resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-4.0.11.tgz#7872625234c15f6e9ab91473a6de1ab26def1fda" + integrity sha512-e3917+HmXStxb2fNP3sOr3R1DMALdWrUteBb3nerA2AKa12mXwmL0lDavrdltwZWqF7/Egh8fF/esB0Z/fqOgQ== dependencies: - "@formatjs/ecma402-abstract" "1.6.1" + "@formatjs/ecma402-abstract" "1.6.3" tslib "^2.1.0" "@formatjs/intl-getcanonicallocales@1.5.7": @@ -2246,12 +2231,12 @@ cldr-core "38" tslib "^2.1.0" -"@formatjs/intl-listformat@5.0.9": - version "5.0.9" - resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-5.0.9.tgz#803f877596c4edada5b87bac0f9bf8c1239be0e5" - integrity sha512-Y7o9+wFuKWmhENxJT1eocIWVbhOlU0SohvZsyMb1m8CyyWQ3esTBKPtmqbK64rAV0twqjcY+16rb8/mKcEJOJw== +"@formatjs/intl-listformat@5.0.12": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-5.0.12.tgz#da0daa1988bc753be915e5361b7c237a3bca314e" + integrity sha512-xWAndG73lqJ1+ar6SljCpM9nUsi2YoZfKi45F2YZRSxtUx4JbWYkhpbroOwxjCQ8ppZFoPc2mlLZjhPZiTyG7g== dependencies: - "@formatjs/ecma402-abstract" "1.6.1" + "@formatjs/ecma402-abstract" "1.6.3" tslib "^2.1.0" "@formatjs/intl-locale@^2.4.20": @@ -2272,14 +2257,6 @@ "@formatjs/ecma402-abstract" "1.6.3" tslib "^2.1.0" -"@formatjs/intl-relativetimeformat@8.1.1": - version "8.1.1" - resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-8.1.1.tgz#9583a2a20caf432e86001c76fa257b27a62146b6" - integrity sha512-6ylno7/nE1UOaNxbrMJhtai3PVaOgklI82Y1MdDdoWyDobNznE+ywxdEVUoe+C2u1JmQnIXMN9a9H1AKDFqTRw== - dependencies: - "@formatjs/ecma402-abstract" "1.6.1" - tslib "^2.1.0" - "@formatjs/intl-relativetimeformat@^8.1.3": version "8.1.3" resolved "https://registry.yarnpkg.com/@formatjs/intl-relativetimeformat/-/intl-relativetimeformat-8.1.3.tgz#e0b6a9abd1a8e2c848d14d5fbb97c534e0a1d7d2" @@ -2300,19 +2277,17 @@ resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.2.1.tgz#0eeefe92d317acfcd179c14826e719b3b130d82a" integrity sha512-WF3oU6l2WqJjN4OWvnjF9AHyQjHpjcfpyuckM7euFeX6ZGRPpPj+ZCqzf41g81MSksf9aZI4fFCZXWTBusgcWA== -"@formatjs/intl@1.8.1": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.8.1.tgz#96708c8cc373c51241614d0015689077ed7bf1b2" - integrity sha512-KEkQ4ktCm7aqyOvu9K81KO2lGUKyLwtsYNP1pCjtIwzsbpj0aW4+//AEoZalpLqIVbGe/iNHsTDxdPPIRFQe8A== - dependencies: - "@formatjs/ecma402-abstract" "1.6.1" - "@formatjs/intl-datetimeformat" "3.2.11" - "@formatjs/intl-displaynames" "4.0.9" - "@formatjs/intl-listformat" "5.0.9" - "@formatjs/intl-relativetimeformat" "8.1.1" +"@formatjs/intl@1.8.4": + version "1.8.4" + resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.8.4.tgz#66418092611777f050ab99ba5fe66b89dbcbd846" + integrity sha512-m0/5ZRQZZfzXmeDieoG8kxu3QRvJazv2VbXhROs5khJKfUKu1rz6xfuUrh3gkmydWYtHuwJDIoC9oGR0ik4+/g== + dependencies: + "@formatjs/ecma402-abstract" "1.6.3" + "@formatjs/intl-displaynames" "4.0.11" + "@formatjs/intl-listformat" "5.0.12" fast-memoize "^2.5.2" - intl-messageformat "9.5.1" - intl-messageformat-parser "6.4.1" + intl-messageformat "9.5.3" + intl-messageformat-parser "6.4.3" tslib "^2.1.0" "@formatjs/macro@^0.2.8": @@ -8323,12 +8298,12 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" -intl-messageformat-parser@6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-6.4.1.tgz#5573b2655a67240564338c3e0956b94d2640f5b4" - integrity sha512-plJDJXkcZiDGJ5iYae4mjELeTFvWeJhl9dXzFeizc5TBqLc/VtNDvV9JBJmXY4XLOViH0lwOhS5+iBdQ4w0ufg== +intl-messageformat-parser@6.4.3: + version "6.4.3" + resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-6.4.3.tgz#4326201256c52907f342c7bb058208113c3c7f95" + integrity sha512-gpB7OeKDSd9wqjIQ7wVQM9byrpMlokGoUfJND7DS9SjoBbOsZIHAHw+lrmAWYmq+MI3WQUeLouSFdYAZ6zSX9A== dependencies: - "@formatjs/ecma402-abstract" "1.6.1" + "@formatjs/ecma402-abstract" "1.6.3" tslib "^2.1.0" intl-messageformat-parser@^3.6.4: @@ -8338,13 +8313,13 @@ intl-messageformat-parser@^3.6.4: dependencies: "@formatjs/intl-unified-numberformat" "^3.2.0" -intl-messageformat@9.5.1: - version "9.5.1" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.5.1.tgz#84d64ee7f1d88e38c0b52bacea006153b325de22" - integrity sha512-hFGON7KcnfNHXAtCeiJlTtWHgu6toOBeouVC/Ee6BI3n2eFBG5JukKsJ0K0W7ILc0t05n+67rvt9sngCVPesxg== +intl-messageformat@9.5.3: + version "9.5.3" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.5.3.tgz#cb89a91cc2da875c5c824d374ba8209fac63a3ca" + integrity sha512-Ei8vH41/icJsc16ZfWk1FzZ2SpaVn0gElXsQCKKPerxK/28m1gVdH0G26GuCqAyz5ETEJiSRn8sPMaSWJDuTjg== dependencies: fast-memoize "^2.5.2" - intl-messageformat-parser "6.4.1" + intl-messageformat-parser "6.4.3" tslib "^2.1.0" into-stream@^3.1.0: @@ -12310,22 +12285,19 @@ react-input-autosize@^3.0.0: dependencies: prop-types "^15.5.8" -react-intl@^5.13.0: - version "5.13.1" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.13.1.tgz#6e043414be6eccb810446dd2813b899c7ca53d9e" - integrity sha512-eGqREjjb7fYtpzQY+IKumADUmfOTJcR0mbeSgcJVXtM3saouP3+2y99Nuo3TVpvbOYf6W4V+Wau61CkzETHpQw== +react-intl@^5.13.5: + version "5.13.5" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.13.5.tgz#32bb74120b67950fe63329db58aa83cfac73f6c8" + integrity sha512-Ym6knnC04k070vwe3UDcRHQUDE2rGn1PNfmYNhDHVPL6vbusuFbefjnt8ZC1GEjnfo29WUHn/tkGd9SMudzD+g== dependencies: - "@formatjs/ecma402-abstract" "1.6.1" - "@formatjs/intl" "1.8.1" - "@formatjs/intl-displaynames" "4.0.9" - "@formatjs/intl-listformat" "5.0.9" - "@formatjs/intl-relativetimeformat" "8.1.1" + "@formatjs/ecma402-abstract" "1.6.3" + "@formatjs/intl" "1.8.4" + "@formatjs/intl-displaynames" "4.0.11" + "@formatjs/intl-listformat" "5.0.12" "@types/hoist-non-react-statics" "^3.3.1" - fast-memoize "^2.5.2" hoist-non-react-statics "^3.3.2" - intl-messageformat "9.5.1" - intl-messageformat-parser "6.4.1" - shallow-equal "^1.2.1" + intl-messageformat "9.5.3" + intl-messageformat-parser "6.4.3" tslib "^2.1.0" react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: @@ -13378,11 +13350,6 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -shallow-equal@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/shallow-equal/-/shallow-equal-1.2.1.tgz#4c16abfa56043aa20d050324efa68940b0da79da" - integrity sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA== - sharkdown@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/sharkdown/-/sharkdown-0.1.1.tgz#64484bd0f08f347f8319e9ff947a670f6b48b1b2" From b5376d6b33cdd4f745fce08fc036cfd2f0bdfc39 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Wed, 24 Mar 2021 17:21:33 -0300 Subject: [PATCH 12/24] Update blue colour on charts --- frontend/src/config/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/config/index.js b/frontend/src/config/index.js index edf876f7f5..57e3f12dc9 100644 --- a/frontend/src/config/index.js +++ b/frontend/src/config/index.js @@ -69,7 +69,7 @@ export const TASK_COLOURS = { export const CHART_COLOURS = { red: '#d73f3f', green: '#3e9c67', - blue: '#1757c4', + blue: '#3389D6', orange: '#f09733', }; From e04e53044e6ce99b6bf2bdebfe22031f4cee9538 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Wed, 24 Mar 2021 16:53:49 -0300 Subject: [PATCH 13/24] Set map view to fit the AoI's bounds on step 2 of project creation --- frontend/src/components/projectCreate/setTaskSizes.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frontend/src/components/projectCreate/setTaskSizes.js b/frontend/src/components/projectCreate/setTaskSizes.js index 3ea026c10e..f782dfa93f 100644 --- a/frontend/src/components/projectCreate/setTaskSizes.js +++ b/frontend/src/components/projectCreate/setTaskSizes.js @@ -122,6 +122,9 @@ const splitTaskGrid = (taskGrid, geom) => { export default function SetTaskSizes({ metadata, mapObj, updateMetadata }) { const [splitMode, setSplitMode] = useState(null); + // center the map view on the AoI + useEffect(() => mapObj.map.fitBounds(bbox(metadata.geom), { padding: 200 })); + const splitHandler = useCallback( (event) => { const taskGrid = mapObj.map.getSource('grid')._data; From 9b26a6ad28f089a76b4cabaeb296f8e94e1ebc9e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Mar 2021 14:08:23 +0000 Subject: [PATCH 14/24] Bump react-select-event from 5.2.0 to 5.3.0 in /frontend Bumps [react-select-event](https://github.com/romgain/react-select-event) from 5.2.0 to 5.3.0. - [Release notes](https://github.com/romgain/react-select-event/releases) - [Commits](https://github.com/romgain/react-select-event/compare/v5.2.0...v5.3.0) Signed-off-by: dependabot-preview[bot] --- frontend/package.json | 2 +- frontend/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 3030165afd..bddc4b446d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -112,7 +112,7 @@ "jest-canvas-mock": "^2.3.1", "msw": "^0.27.1", "prettier": "^2.2.1", - "react-select-event": "^5.2.0", + "react-select-event": "^5.3.0", "react-test-renderer": "^17.0.2", "source-map-explorer": "^2.5.2" }, diff --git a/frontend/yarn.lock b/frontend/yarn.lock index ed972d9659..5685f49987 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -12425,10 +12425,10 @@ react-scripts@^4.0.3: optionalDependencies: fsevents "^2.1.3" -react-select-event@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/react-select-event/-/react-select-event-5.2.0.tgz#ab0e77bc81e02b4dca2926a04d28ba9c94f39f55" - integrity sha512-9+C+lFQZRrhXs/+czZdlbUlEjIW+raiHK0QIVLD4IJMspvlf2TTqcepm5tm5GCIvUHFuw5VF0oL2ebyKrMbDZg== +react-select-event@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/react-select-event/-/react-select-event-5.3.0.tgz#4548fffd615a47176951cbb301ee21a0c60b582a" + integrity sha512-Novkl7X9JJKmDV5LyYaKwl0vffWtqPrBa1vuI0v43P/f87mSA7JfdYxU93SFb99RssphVzBSIAbcnbX1w21QIQ== dependencies: "@testing-library/dom" ">=7" From 51257aa49638f11d5e0f5a6769eb3969c54fc026 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Thu, 25 Mar 2021 07:30:14 -0300 Subject: [PATCH 15/24] =?UTF-8?q?Add=20option=20to=20discard=20tasks=20sma?= =?UTF-8?q?ller=20than=202000m=C2=B2=20+=20refactoring?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/projectCreate/index.js | 90 ++++++------------- .../src/components/projectCreate/messages.js | 9 ++ .../components/projectCreate/navButtons.js | 16 ++-- .../projectCreate/projectCreationMap.js | 77 ++++++++++++++-- .../components/projectCreate/setTaskSizes.js | 3 +- .../components/projectCreate/trimProject.js | 87 +++++++++++++----- frontend/src/locales/en.json | 2 + 7 files changed, 180 insertions(+), 104 deletions(-) diff --git a/frontend/src/components/projectCreate/index.js b/frontend/src/components/projectCreate/index.js index 5193c565d2..af07b6a415 100644 --- a/frontend/src/components/projectCreate/index.js +++ b/frontend/src/components/projectCreate/index.js @@ -1,19 +1,21 @@ import React, { useState, useLayoutEffect, useCallback, Suspense } from 'react'; import { useSelector } from 'react-redux'; -import { Redirect } from '@reach/router'; +import { Redirect, navigate } from '@reach/router'; +import { useQueryParam, NumberParam } from 'use-query-params'; +import { FormattedMessage, FormattedNumber, useIntl } from 'react-intl'; import ReactPlaceholder from 'react-placeholder'; import area from '@turf/area'; import bbox from '@turf/bbox'; import { featureCollection } from '@turf/helpers'; import lineToPolygon from '@turf/line-to-polygon'; -import { useQueryParam, NumberParam } from 'use-query-params'; -import { FormattedMessage, FormattedNumber, useIntl } from 'react-intl'; +import truncate from '@turf/truncate'; import MapboxDraw from '@mapbox/mapbox-gl-draw'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'; + +import messages from './messages'; import { createProject } from '../../store/actions/project'; import { store } from '../../store'; import { pushToLocalJSONAPI } from '../../network/genericJSONRequest'; -import messages from './messages'; import SetAOI from './setAOI'; import SetTaskSizes from './setTaskSizes'; import TrimProject from './trimProject'; @@ -21,11 +23,8 @@ import NavButtons from './navButtons'; import Review from './review'; import { AlertMessage } from './alertMessage'; import { fetchLocalJSONAPI } from '../../network/genericJSONRequest'; -import { MAX_AOI_AREA } from '../../config'; -import { navigate } from '@reach/router'; -import truncate from '@turf/truncate'; import { makeGrid } from './setTaskSizes'; -import { MAX_FILESIZE } from '../../config'; +import { MAX_AOI_AREA, MAX_FILESIZE } from '../../config'; const ProjectCreationMap = React.lazy(() => import('./projectCreationMap' /* webpackChunkName: "projectCreationMap" */), @@ -35,64 +34,26 @@ var toGeojson = require('@mapbox/togeojson'); var osmToGeojson = require('osmtogeojson'); var shpjs = require('shpjs'); -const aoiPaintOptions = { - 'fill-color': '#00004d', - 'fill-opacity': 0.3, -}; - -const taskGridPaintOptions = { - 'fill-color': '#fff', - 'fill-outline-color': '#00f', - 'fill-opacity': 0.5, -}; - -export const addLayer = (layerName, data, map) => { - if (map.getLayer(layerName)) { - map.removeLayer(layerName); - } - if (map.getSource(layerName)) { - map.removeSource(layerName); - } - - let options = aoiPaintOptions; - if (layerName === 'grid') { - options = taskGridPaintOptions; - } - - map.addLayer({ - id: layerName, - type: 'fill', - source: { - type: 'geojson', - data: data, - }, - paint: options, - }); -}; - const ProjectCreate = (props) => { - const intl = useIntl(); - + const intl = useIntl(); const token = useSelector((state) => state.auth.get('token')); const [drawModeIsActive, setDrawModeIsActive] = useState(false); - const layer_name = 'aoi'; const setDataGeom = (geom, display) => { - mapObj.map.fitBounds(bbox(geom), { padding: 20 }); - const geomArea = area(geom) / 1e6; + mapObj.map.fitBounds(bbox(geom), { padding: 200 }); const zoomLevel = 11; const grid = makeGrid(geom, zoomLevel, {}); updateMetadata({ ...metadata, geom: geom, - area: geomArea.toFixed(2), + area: (area(geom) / 1e6).toFixed(2), zoomLevel: zoomLevel, taskGrid: grid, tempTaskGrid: grid, }); if (display === true) { - addLayer('aoi', geom, mapObj.map); + mapObj.map.getSource('aoi').setData(geom); } }; @@ -205,11 +166,8 @@ const ProjectCreate = (props) => { mapObj.draw.delete(id); } - if (mapObj.map.getLayer(layer_name)) { - mapObj.map.removeLayer(layer_name); - } - if (mapObj.map.getSource(layer_name)) { - mapObj.map.removeSource(layer_name); + if (mapObj.map.getSource('aoi')) { + mapObj.map.getSource('aoi').setData(featureCollection([])); } updateMetadata({ ...metadata, area: 0, geom: null, arbitraryTasks: false }); }; @@ -297,13 +255,14 @@ const ProjectCreate = (props) => { draw: new MapboxDraw(drawOptions), }); - const handleCreate = useCallback((cloneProjectData) => { + const handleCreate = useCallback( + (cloneProjectData) => { if (!metadata.geom) { - setErr({error: true, message: intl.formatMessage(messages.noGeometry)}); + setErr({ error: true, message: intl.formatMessage(messages.noGeometry) }); return; } if (!metadata.organisation && !cloneProjectData.organisation) { - setErr({error: true, message:intl.formatMessage(messages.noOrganization)}); + setErr({ error: true, message: intl.formatMessage(messages.noOrganization) }); return; } @@ -322,12 +281,15 @@ const ProjectCreate = (props) => { } pushToLocalJSONAPI('projects/', JSON.stringify(projectParams), token) .then((res) => navigate(`/manage/projects/${res.projectId}`)) - .catch((e) => setErr({ - error: true, - message: , - }) ); - }, [metadata, setErr, intl, token]); - + .catch((e) => + setErr({ + error: true, + message: , + }), + ); + }, + [metadata, setErr, intl, token], + ); if (!token) { return ; diff --git a/frontend/src/components/projectCreate/messages.js b/frontend/src/components/projectCreate/messages.js index c2e6f7b00d..efe25545c4 100644 --- a/frontend/src/components/projectCreate/messages.js +++ b/frontend/src/components/projectCreate/messages.js @@ -85,6 +85,15 @@ export default defineMessages({ id: 'management.projects.create.trim_tasks.trim_to_aoi', defaultMessage: 'Trim the tasks to define the exact Area of Interest for mapping.', }, + tinyTasks: { + id: 'management.projects.create.trim_tasks.tiny_tasks', + defaultMessage: + '{number, plural, one {There is # task smaller than {area}m². Would you like to discard them?} other {There are # tasks smaller than {area}m². Would you like to discard them?}}', + }, + discard: { + id: 'management.projects.create.trim_tasks.tiny_tasks.discard', + defaultMessage: 'Discard', + }, taskSizes: { id: 'management.projects.create.task_sizes.description', defaultMessage: 'General task size', diff --git a/frontend/src/components/projectCreate/navButtons.js b/frontend/src/components/projectCreate/navButtons.js index 3594da5b14..d29606fbf6 100644 --- a/frontend/src/components/projectCreate/navButtons.js +++ b/frontend/src/components/projectCreate/navButtons.js @@ -1,16 +1,18 @@ import React from 'react'; +import { featureCollection } from '@turf/helpers'; import { FormattedMessage, useIntl } from 'react-intl'; -import { addLayer } from './index'; + import messages from './messages'; import { Button } from '../button'; const clearParamsStep = (props) => { switch (props.index) { case 2: //clear Tasks - props.mapObj.map.removeLayer('grid'); + props.mapObj.map.getSource('grid').setData(featureCollection([])); props.updateMetadata({ ...props.metadata, tasksNumber: 0 }); break; case 3: + props.mapObj.map.getSource('tiny-tasks').setData(featureCollection([])); props.updateMetadata({ ...props.metadata, taskGrid: props.metadata.tempTaskGrid, @@ -45,7 +47,7 @@ const NavButtons = (props) => { } else { const id = props.metadata.geom.features[0].id; props.mapObj.draw.delete(id); - addLayer('aoi', props.metadata.geom, props.mapObj.map); + props.mapObj.map.getSource('aoi').setData(props.metadata.geom); props.updateMetadata({ ...props.metadata, tasksNumber: props.metadata.taskGrid.features.length, @@ -85,16 +87,14 @@ const NavButtons = (props) => { )} {props.index === 4 ? ( - + ) : ( diff --git a/frontend/src/components/projectCreate/projectCreationMap.js b/frontend/src/components/projectCreate/projectCreationMap.js index 7e663add6f..e728571f05 100644 --- a/frontend/src/components/projectCreate/projectCreationMap.js +++ b/frontend/src/components/projectCreate/projectCreationMap.js @@ -2,12 +2,18 @@ import React, { useLayoutEffect, useState } from 'react'; import { useSelector } from 'react-redux'; import mapboxgl from 'mapbox-gl'; import 'mapbox-gl/dist/mapbox-gl.css'; +import { featureCollection } from '@turf/helpers'; import MapboxLanguage from '@mapbox/mapbox-gl-language'; import MapboxGeocoder from '@mapbox/mapbox-gl-geocoder'; import '@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css'; -import { addLayer } from './index'; -import { MAPBOX_TOKEN, BASEMAP_OPTIONS, MAP_STYLE, MAPBOX_RTL_PLUGIN_URL } from '../../config'; +import { + MAPBOX_TOKEN, + BASEMAP_OPTIONS, + MAP_STYLE, + CHART_COLOURS, + MAPBOX_RTL_PLUGIN_URL, +} from '../../config'; import { useDropzone } from 'react-dropzone'; mapboxgl.accessToken = MAPBOX_TOKEN; @@ -89,18 +95,71 @@ const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step, } setMapObj({ ...mapObj, map: map }); - return () => { mapObj.map && mapObj.map.remove(); }; // eslint-disable-next-line }, []); + const addMapLayers = (map) => { + if (map.getSource('aoi') === undefined) { + map.addSource('aoi', { + type: 'geojson', + data: featureCollection([]), + }); + map.addLayer({ + id: 'aoi', + type: 'fill', + source: 'aoi', + paint: { + 'fill-color': CHART_COLOURS.orange, + 'fill-outline-color': '#929db3', + 'fill-opacity': 0.3, + }, + }); + } + + if (map.getSource('grid') === undefined) { + map.addSource('grid', { + type: 'geojson', + data: featureCollection([]), + }); + map.addLayer({ + id: 'grid', + type: 'fill', + source: 'grid', + paint: { + 'fill-color': '#68707f', + 'fill-outline-color': '#00f', + 'fill-opacity': 0.3, + }, + }); + } + + if (map.getSource('tiny-tasks') === undefined) { + map.addSource('tiny-tasks', { + type: 'geojson', + data: featureCollection([]), + }); + map.addLayer({ + id: 'tiny-tasks', + type: 'fill', + source: 'tiny-tasks', + paint: { + 'fill-color': '#f0f', + 'fill-outline-color': '#f0f', + 'fill-opacity': 0.3, + }, + }); + } + }; + useLayoutEffect(() => { if (mapObj.map !== null) { mapObj.map.on('load', () => { mapObj.map.addControl(new mapboxgl.NavigationControl()); mapObj.map.addControl(mapObj.draw); + addMapLayers(mapObj.map); }); // Remove area and geometry when aoi is deleted. @@ -112,15 +171,17 @@ const ProjectCreationMap = ({ mapObj, setMapObj, metadata, updateMetadata, step, if (!MAPBOX_TOKEN) { return; } + addMapLayers(mapObj.map); const features = mapObj.draw.getAll(); - if (features.features.length === 0) { - addLayer('aoi', metadata.geom, mapObj.map); + if (features.features.length === 0 && mapObj.map.getSource('aoi') !== undefined) { + mapObj.map.getSource('aoi').setData(metadata.geom); } - if (metadata.taskGrid && step !== 1) { - addLayer('grid', metadata.taskGrid, mapObj.map); + if (metadata.taskGrid && step !== 1 && mapObj.map.getSource('grid') !== undefined) { + mapObj.map.getSource('grid').setData(metadata.taskGrid); } else { - mapObj.map.removeLayer('grid'); + mapObj.map.getSource('grid') && + mapObj.map.getSource('grid').setData(featureCollection([])); } }); } diff --git a/frontend/src/components/projectCreate/setTaskSizes.js b/frontend/src/components/projectCreate/setTaskSizes.js index f782dfa93f..81fbda65e8 100644 --- a/frontend/src/components/projectCreate/setTaskSizes.js +++ b/frontend/src/components/projectCreate/setTaskSizes.js @@ -16,7 +16,6 @@ import { FourCellsGridIcon, NineCellsGridIcon, } from '../svgIcons'; -import { addLayer } from './index'; // Maximum resolution of OSM const MAXRESOLUTION = 156543.0339; @@ -224,7 +223,7 @@ export default function SetTaskSizes({ metadata, mapObj, updateMetadata }) { }, [metadata, updateMetadata]); useLayoutEffect(() => { - addLayer('grid', metadata.taskGrid, mapObj.map); + mapObj.map.getSource('grid').setData(metadata.taskGrid); return () => { // remove the split on click function when leaving the page mapObj.map.off('click', 'grid', splitHandler); diff --git a/frontend/src/components/projectCreate/trimProject.js b/frontend/src/components/projectCreate/trimProject.js index 820ddce234..1d4b9eb96d 100644 --- a/frontend/src/components/projectCreate/trimProject.js +++ b/frontend/src/components/projectCreate/trimProject.js @@ -1,12 +1,13 @@ import React, { useState, useEffect } from 'react'; import { useSelector } from 'react-redux'; -import { FormattedMessage } from 'react-intl'; +import area from '@turf/area'; +import { featureCollection } from '@turf/helpers'; +import { FormattedMessage, FormattedNumber } from 'react-intl'; import messages from './messages'; -import { addLayer } from './index'; import { CustomButton } from '../button'; import { SwitchToggle } from '../formInputs'; -import { CutIcon } from '../svgIcons'; +import { CutIcon, WasteIcon } from '../svgIcons'; import { pushToLocalJSONAPI } from '../../network/genericJSONRequest'; const clipProject = (clip, metadata, map, updateMetadata, token) => { @@ -22,13 +23,30 @@ const clipProject = (clip, metadata, map, updateMetadata, token) => { }); }; -export default function TrimProject({ metadata, mapObj, updateMetadata }) { - useEffect(() => { - addLayer('grid', metadata.taskGrid, mapObj.map); - }, [metadata, mapObj]); +const removeTinyTasks = (metadata, updateMetadata) => { + const newTaskGrid = featureCollection( + metadata.taskGrid.features.filter((task) => area(task) >= 2000), + ); + updateMetadata({ + ...metadata, + tasksNumber: newTaskGrid.features.length, + taskGrid: newTaskGrid, + }); +}; +export default function TrimProject({ metadata, mapObj, updateMetadata }) { const token = useSelector((state) => state.auth.get('token')); const [clipStatus, setClipStatus] = useState(false); + const [tinyTasksNumber, setTinyTasksNumber] = useState(0); + + useEffect(() => { + mapObj.map + .getSource('grid') + .setData(featureCollection(metadata.taskGrid.features.filter((task) => area(task) >= 2000))); + const tinyTasks = metadata.taskGrid.features.filter((task) => area(task) < 2000); + mapObj.map.getSource('tiny-tasks').setData(featureCollection(tinyTasks)); + setTinyTasksNumber(tinyTasks.length); + }, [metadata, mapObj]); return ( <> @@ -42,21 +60,46 @@ export default function TrimProject({ metadata, mapObj, updateMetadata }) {

- setClipStatus(!clipStatus)} - label={} - /> -
- clipProject(clipStatus, metadata, mapObj.map, updateMetadata, token)} - className="bg-white blue-dark ba b--grey-light ph3 pv2" - > - - - -
+ {tinyTasksNumber === 0 ? ( + <> + setClipStatus(!clipStatus)} + label={} + /> +
+ clipProject(clipStatus, metadata, mapObj.map, updateMetadata, token)} + className="bg-white blue-dark ba b--grey-light ph3 pv2" + > + + + +
+ + ) : ( +
+
+
+ +
+
+ }} + /> +
+
+ removeTinyTasks(metadata, updateMetadata)} + className="bg-white blue-dark ba b--grey-light ph3 pv2" + > + + + +
+ )}
); diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index b563d34016..879f6fc800 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -215,6 +215,8 @@ "management.projects.create.trim_tasks.description.1": "Trim the task grid to the area of interest (optional).", "management.projects.create.trim_tasks.description.2": "You can keep the current tasks or trim the area for your project. This can take some time to execute.", "management.projects.create.trim_tasks.trim_to_aoi": "Trim the tasks to define the exact Area of Interest for mapping.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {There is # task smaller than {area}m². Would you like to discard them?} other {There are # tasks smaller than {area}m². Would you like to discard them?}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "Discard", "management.projects.create.task_sizes.description": "General task size", "management.projects.create.task_sizes.smaller": "Smaller", "management.projects.create.task_sizes.larger": "Larger", From 90a1362a0d13283e3589f1ffdf6fb52a858e32ef Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Thu, 25 Mar 2021 10:05:35 -0300 Subject: [PATCH 16/24] Update tasks number when going back from to step 1 with arbitrary tasks --- frontend/src/components/projectCreate/navButtons.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/projectCreate/navButtons.js b/frontend/src/components/projectCreate/navButtons.js index d29606fbf6..1830d29fcd 100644 --- a/frontend/src/components/projectCreate/navButtons.js +++ b/frontend/src/components/projectCreate/navButtons.js @@ -27,6 +27,7 @@ const clearParamsStep = (props) => { // If task is arbitrary. Jump to review. if (props.metadata.arbitraryTasks === true) { + props.updateMetadata({ ...props.metadata, tasksNumber: 0 }); prevStep = 1; } props.setStep(prevStep); From 5ae409686928845d01a3de6b3a95b411e570baec Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Thu, 25 Mar 2021 15:01:37 -0300 Subject: [PATCH 17/24] Count correctly the number of tasks when importing files --- frontend/src/components/projectCreate/index.js | 2 +- frontend/src/components/projectCreate/navButtons.js | 7 ++++++- frontend/src/components/projectCreate/setAOI.js | 7 ++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/projectCreate/index.js b/frontend/src/components/projectCreate/index.js index af07b6a415..f872d2cfa0 100644 --- a/frontend/src/components/projectCreate/index.js +++ b/frontend/src/components/projectCreate/index.js @@ -169,7 +169,7 @@ const ProjectCreate = (props) => { if (mapObj.map.getSource('aoi')) { mapObj.map.getSource('aoi').setData(featureCollection([])); } - updateMetadata({ ...metadata, area: 0, geom: null, arbitraryTasks: false }); + updateMetadata({ ...metadata, area: 0, geom: null, arbitraryTasks: false, tasksNumber: 0 }); }; const drawHandler = () => { diff --git a/frontend/src/components/projectCreate/navButtons.js b/frontend/src/components/projectCreate/navButtons.js index 1830d29fcd..fbdb1bdc4f 100644 --- a/frontend/src/components/projectCreate/navButtons.js +++ b/frontend/src/components/projectCreate/navButtons.js @@ -28,6 +28,9 @@ const clearParamsStep = (props) => { // If task is arbitrary. Jump to review. if (props.metadata.arbitraryTasks === true) { props.updateMetadata({ ...props.metadata, tasksNumber: 0 }); + if (props.metadata.geom.features) { + props.updateMetadata({ ...props.metadata, tasksNumber: props.metadata.geom.features.length }); + } prevStep = 1; } props.setStep(prevStep); @@ -51,7 +54,9 @@ const NavButtons = (props) => { props.mapObj.map.getSource('aoi').setData(props.metadata.geom); props.updateMetadata({ ...props.metadata, - tasksNumber: props.metadata.taskGrid.features.length, + tasksNumber: props.metadata.arbitraryTasks + ? props.metadata.geom.features.length + : props.metadata.taskGrid.features.length, }); } diff --git a/frontend/src/components/projectCreate/setAOI.js b/frontend/src/components/projectCreate/setAOI.js index 5b6c74098e..140824db35 100644 --- a/frontend/src/components/projectCreate/setAOI.js +++ b/frontend/src/components/projectCreate/setAOI.js @@ -59,7 +59,12 @@ export default function SetAOI({ labelPosition="right" isChecked={metadata.arbitraryTasks} onChange={() => - updateMetadata({ ...metadata, arbitraryTasks: !metadata.arbitraryTasks }) + updateMetadata({ + ...metadata, + arbitraryTasks: !metadata.arbitraryTasks, + tasksNumber: + metadata.geom && metadata.geom.features ? metadata.geom.features.length : 0, + }) } /> )} From b4d88d66fc643d316f623c913db38c3bda2fac85 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Mon, 29 Mar 2021 09:22:36 -0300 Subject: [PATCH 18/24] Show loading icon on buttons during mapping/validation API requests --- frontend/src/components/button.js | 20 ++++-- .../taskSelection/actionSidebars.js | 67 ++++++++++++++----- frontend/src/hooks/UseAsync.js | 40 +++++++++++ frontend/src/hooks/tests/UseAsync.test.js | 36 ++++++++++ 4 files changed, 142 insertions(+), 21 deletions(-) create mode 100644 frontend/src/hooks/UseAsync.js create mode 100644 frontend/src/hooks/tests/UseAsync.test.js diff --git a/frontend/src/components/button.js b/frontend/src/components/button.js index bbf2d7ac29..04aabdeff6 100644 --- a/frontend/src/components/button.js +++ b/frontend/src/components/button.js @@ -1,16 +1,21 @@ import React from 'react'; import { Link } from '@reach/router'; -export function Button({ onClick, children, className, disabled }: Object) { +import { LoadingIcon } from './svgIcons'; + +export function Button({ onClick, children, className, disabled, loading = false }: Object) { return ( ); @@ -33,15 +38,18 @@ export function FormSubmitButton({ children, className, disabledClassName, disab ); } -export function CustomButton({ onClick, children, className, disabled }: Object) { +export function CustomButton({ onClick, children, className, disabled, loading = false }: Object) { return ( ); diff --git a/frontend/src/components/taskSelection/actionSidebars.js b/frontend/src/components/taskSelection/actionSidebars.js index 30b96a0c63..22b7f5c88d 100644 --- a/frontend/src/components/taskSelection/actionSidebars.js +++ b/frontend/src/components/taskSelection/actionSidebars.js @@ -22,6 +22,7 @@ import { htmlFromMarkdown } from '../../utils/htmlFromMarkdown'; import { pushToLocalJSONAPI, fetchLocalJSONAPI } from '../../network/genericJSONRequest'; import { CommentInputField } from '../comments/commentInput'; import { useFetchLockedTasks, useClearLockedTasks } from '../../hooks/UseLockedTasks'; +import { useAsync } from '../../hooks/UseAsync'; export function CompletionTabForMapping({ project, @@ -46,7 +47,7 @@ export function CompletionTabForMapping({ const splitTask = () => { if (!disabled) { - fetchLocalJSONAPI( + return fetchLocalJSONAPI( `projects/${project.projectId}/tasks/actions/split/${tasksIds[0]}/`, token, 'POST', @@ -59,13 +60,18 @@ export function CompletionTabForMapping({ setSplitTaskError(true); }); } else { - setShowMapChangesModal('split'); + // we need to return a promise in order to be called by useAsync + return new Promise((resolve, reject) => { + setShowMapChangesModal('split'); + resolve(); + }); } }; + const splitTaskAsync = useAsync(splitTask); const stopMapping = () => { if (!disabled) { - pushToLocalJSONAPI( + return pushToLocalJSONAPI( `projects/${project.projectId}/tasks/actions/stop-mapping/${tasksIds[0]}/`, JSON.stringify({ comment: taskComment }), token, @@ -74,9 +80,13 @@ export function CompletionTabForMapping({ navigate(`/projects/${project.projectId}/tasks/`); }); } else { - setShowMapChangesModal('unlock'); + return new Promise((resolve, reject) => { + setShowMapChangesModal('unlock'); + resolve(); + }); } }; + const stopMappingAsync = useAsync(stopMapping); const submitTask = () => { if (!disabled && selectedStatus) { @@ -93,12 +103,13 @@ export function CompletionTabForMapping({ url = `projects/${project.projectId}/tasks/actions/unlock-after-mapping/${tasksIds[0]}/`; payload.status = 'BADIMAGERY'; } - pushToLocalJSONAPI(url, JSON.stringify(payload), token).then((r) => { + return pushToLocalJSONAPI(url, JSON.stringify(payload), token).then((r) => { fetchLockedTasks(); navigate(`/projects/${project.projectId}/tasks/`); }); } }; + const submitTaskAsync = useAsync(submitTask); return (
@@ -210,17 +221,32 @@ export function CompletionTabForMapping({
- -
@@ -247,7 +273,7 @@ export function CompletionTabForValidation({ const stopValidation = () => { if (!disabled) { - pushToLocalJSONAPI( + return pushToLocalJSONAPI( `projects/${project.projectId}/tasks/actions/stop-validation/`, JSON.stringify({ resetTasks: tasksIds.map((taskId) => ({ taskId: taskId, comment: taskComment })), @@ -258,9 +284,13 @@ export function CompletionTabForValidation({ navigate(`../tasks/`); }); } else { - setShowMapChangesModal('unlock'); + return new Promise((resolve, reject) => { + setShowMapChangesModal('unlock'); + resolve(); + }); } }; + const stopValidationAsync = useAsync(stopValidation); const submitTask = () => { if (!disabled && selectedStatus) { @@ -278,12 +308,13 @@ export function CompletionTabForValidation({ if (selectedStatus === 'INVALIDATED') { url = `projects/${project.projectId}/tasks/actions/unlock-after-validation/`; } - pushToLocalJSONAPI(url, JSON.stringify(payload), token).then((r) => { + return pushToLocalJSONAPI(url, JSON.stringify(payload), token).then((r) => { fetchLockedTasks(); navigate(`../tasks/?filter=readyToValidate`); }); } }; + const submitTaskAsync = useAsync(submitTask); return (
@@ -348,14 +379,20 @@ export function CompletionTabForValidation({
-
diff --git a/frontend/src/hooks/UseAsync.js b/frontend/src/hooks/UseAsync.js new file mode 100644 index 0000000000..2d3c0d7a0c --- /dev/null +++ b/frontend/src/hooks/UseAsync.js @@ -0,0 +1,40 @@ +import { useState, useCallback, useEffect } from 'react'; + +// source: https://usehooks.com/useAsync/ (with modifications) + +export const useAsync = (asyncFunction, immediate = false) => { + const [status, setStatus] = useState('idle'); + const [value, setValue] = useState(null); + const [error, setError] = useState(null); + + // The execute function wraps asyncFunction and + // handles setting state for pending, value, and error. + // useCallback ensures the below useEffect is not called + // on every render, but only if asyncFunction changes. + const execute = useCallback(() => { + setStatus('pending'); + setValue(null); + setError(null); + + return asyncFunction() + .then((response) => { + setValue(response); + setStatus('success'); + }) + .catch((error) => { + setError(error); + setStatus('error'); + }); + }, [asyncFunction]); + + // Call execute if we want to fire it right away. + // Otherwise execute can be called later, such as + // in an onClick handler. + useEffect(() => { + if (immediate) { + execute(); + } + }, [execute, immediate]); + + return { execute, status, value, error }; +}; diff --git a/frontend/src/hooks/tests/UseAsync.test.js b/frontend/src/hooks/tests/UseAsync.test.js new file mode 100644 index 0000000000..ee0a2164eb --- /dev/null +++ b/frontend/src/hooks/tests/UseAsync.test.js @@ -0,0 +1,36 @@ +import { renderHook } from '@testing-library/react-hooks'; + +import { useAsync } from '../UseAsync'; + +describe('useAsync', () => { + it('with successful result', async () => { + const mockFn = jest.fn(); + const testFn = () => + new Promise((resolve, reject) => { + mockFn(); + resolve(); + }); + const { result, waitForNextUpdate } = renderHook(() => useAsync(testFn)); + expect(result.current.status).toBe('idle'); + result.current.execute(); + expect(mockFn).toHaveBeenCalled(); + expect(result.current.status).toBe('pending'); + await waitForNextUpdate(); + expect(result.current.status).toBe('success'); + }); + it('with unsuccessful result', async () => { + const mockFn = jest.fn(); + const testFn = () => + new Promise((resolve, reject) => { + mockFn(); + reject(); + }); + const { result, waitForNextUpdate } = renderHook(() => useAsync(testFn)); + expect(result.current.status).toBe('idle'); + result.current.execute(); + expect(mockFn).toHaveBeenCalled(); + expect(result.current.status).toBe('pending'); + await waitForNextUpdate(); + expect(result.current.status).toBe('error'); + }); +}); From 965bc2a282e4d50e351126bdb0fadd7880832feb Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Tue, 30 Mar 2021 08:42:54 -0300 Subject: [PATCH 19/24] Improve Login page (#4451) * Improve Login page * adjust logo's size and position on login page * update login.test.js --- frontend/src/components/header/index.js | 10 ++-- frontend/src/components/header/messages.js | 10 ++-- .../header/tests/authButtons.test.js | 48 +++++++++++++++++++ frontend/src/locales/en.json | 5 +- frontend/src/views/login.js | 23 +++++++-- frontend/src/views/messages.js | 10 +++- frontend/src/views/tests/login.test.js | 26 ++++++++++ 7 files changed, 118 insertions(+), 14 deletions(-) create mode 100644 frontend/src/components/header/tests/authButtons.test.js create mode 100644 frontend/src/views/tests/login.test.js diff --git a/frontend/src/components/header/index.js b/frontend/src/components/header/index.js index 7bd0dbd35f..1a47e080e8 100644 --- a/frontend/src/components/header/index.js +++ b/frontend/src/components/header/index.js @@ -57,8 +57,7 @@ const UserDisplay = ({ username }) => { ); }; -const AuthButtons = (props) => { - const { logInStyle, signUpStyle, redirectTo } = props; +const AuthButtons = ({ logInStyle, signUpStyle, redirectTo, alternativeSignUpText = false }) => { const [debouncedCreateLoginWindow] = useDebouncedCallback( (redirectToPass) => createLoginWindow(redirectToPass), 3000, @@ -73,7 +72,11 @@ const AuthButtons = (props) => { - + {alternativeSignUpText ? ( + + ) : ( + + )} } modal @@ -207,7 +210,6 @@ class Header extends React.Component {
{ + it('without alternativeSignUpText', () => { + render( + + + , + ); + expect(screen.getByText('Log in').className).toContain('blue-dark bg-white'); + expect(screen.getByText('Sign up').className).toContain('bg-blue-dark white ml1 v-mid'); + expect(screen.queryByText('Create an account')).not.toBeInTheDocument(); + expect(screen.queryByText('Name')).not.toBeInTheDocument(); + fireEvent.click(screen.getByText('Sign up')); + expect(screen.getByText('Name')).toBeInTheDocument(); + expect(screen.getByText('Email')).toBeInTheDocument(); + expect(screen.getByText('Next')).toBeInTheDocument(); + }); + it('with alternativeSignUpText', () => { + render( + + + , + ); + expect(screen.getByText('Log in').className).toContain('white bg-red'); + expect(screen.getByText('Create an account').className).toContain('bg-orange black ml1 v-mid'); + expect(screen.queryByText('Sign up')).not.toBeInTheDocument(); + expect(screen.queryByText('Name')).not.toBeInTheDocument(); + fireEvent.click(screen.getByText('Create an account')); + expect(screen.getByText('Name')).toBeInTheDocument(); + expect(screen.getByText('Email')).toBeInTheDocument(); + expect(screen.getByText('Next')).toBeInTheDocument(); + }); +}); diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 879f6fc800..22849fb12c 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -59,6 +59,7 @@ "header.nav.manage": "Manage", "header.buttons.logIn": "Log in", "header.buttons.signUp": "Sign up", + "header.buttons.createAccount": "Create an account", "header.buttons.authorize": "Log in", "signUp.modal.authorize": "Have you finished the registration on OpenStreetMap?", "signUp.authorize.message": "Start mapping now! Just login to the Tasking Manager with your new OpenStreetMap account.", @@ -904,7 +905,9 @@ "management.forbiddenAccess.title": "You are not allowed to access the management area.", "teamsAndOrgs.management.project.forbidden": "You are not allowed to edit this project.", "teamsAndOrgs.management.team.forbidden": "You are not allowed to edit this team.", - "loginPage.title": "Login or register an account", + "loginPage.title": "Sign in to {org} Tasking Manager", + "loginPage.text.login": "You can log in with an OpenStreetMap account.", + "loginPage.text.create_account": "Or create a new one to start mapping.", "management.managers": "Managers", "management.users.title": "Manage users", "management.stats.users.title": "New users", diff --git a/frontend/src/views/login.js b/frontend/src/views/login.js index 81f0dec5d7..f907a0cdc6 100644 --- a/frontend/src/views/login.js +++ b/frontend/src/views/login.js @@ -6,22 +6,35 @@ import { FormattedMessage } from 'react-intl'; import { AuthButtons } from '../components/header'; import messages from './messages'; import { useSetTitleTag } from '../hooks/UseMetaTags'; +import { ORG_LOGO, ORG_NAME, ORG_CODE } from '../config'; +import logo from '../assets/img/main-logo.svg'; export function Login({ redirectTo }: Object) { useSetTitleTag('Login'); const userIsloggedIn = useSelector((state) => state.auth.get('token')); if (!userIsloggedIn) { return ( -
-

- +
+
+ {`${ORG_NAME} +
+

+

+
+

+ +

+

+ +

+
diff --git a/frontend/src/views/messages.js b/frontend/src/views/messages.js index eec1562a0f..afb9e908b4 100644 --- a/frontend/src/views/messages.js +++ b/frontend/src/views/messages.js @@ -46,7 +46,15 @@ export default defineMessages({ }, loginRequired: { id: 'loginPage.title', - defaultMessage: 'Login or register an account', + defaultMessage: 'Sign in to {org} Tasking Manager', + }, + loginWithOSM: { + id: 'loginPage.text.login', + defaultMessage: 'You can log in with an OpenStreetMap account.', + }, + createAccount: { + id: 'loginPage.text.create_account', + defaultMessage: 'Or create a new one to start mapping.', }, managers: { id: 'management.managers', diff --git a/frontend/src/views/tests/login.test.js b/frontend/src/views/tests/login.test.js new file mode 100644 index 0000000000..4f4bf296bb --- /dev/null +++ b/frontend/src/views/tests/login.test.js @@ -0,0 +1,26 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import '@testing-library/jest-dom'; + +import { ReduxIntlProviders } from '../../utils/testWithIntl'; +import { Login } from '../login'; + + +test('Login component renders the elements correctly formatted', () => { + render( + + + , + ); + expect(screen.getByText(/Tasking Manager/)).toBeInTheDocument(); + expect(screen.getByText('Log in').className).toContain('blue-dark bg-white'); + expect(screen.getByText('Create an account').className).toContain( + 'bg-blue-dark white ml1 v-mid', + ); + expect(screen.queryByText('Sign up')).not.toBeInTheDocument(); + expect(screen.queryByText('Name')).not.toBeInTheDocument(); + fireEvent.click(screen.getByText('Create an account')); + expect(screen.getByText('Name')).toBeInTheDocument(); + expect(screen.getByText('Email')).toBeInTheDocument(); + expect(screen.getByText('Next')).toBeInTheDocument(); +}); From 87f85160bd2e81be22b702cc63c5c2ed06c073f8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 29 Mar 2021 18:41:57 +0000 Subject: [PATCH 20/24] [Security] Bump y18n from 4.0.0 to 4.0.1 in /frontend Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1. **This update includes a security fix.** - [Release notes](https://github.com/yargs/y18n/releases) - [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md) - [Commits](https://github.com/yargs/y18n/commits) Signed-off-by: dependabot-preview[bot] --- frontend/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 5685f49987..be705220be 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -15463,9 +15463,9 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.0, xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== y18n@^5.0.5: version "5.0.5" From 855fd021edfea38d360f3c9d7b9ab5dc342a1508 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Tue, 30 Mar 2021 14:53:26 -0300 Subject: [PATCH 21/24] update frontend dependencies --- frontend/package.json | 14 +-- frontend/yarn.lock | 232 +++++++++++++++++++++++------------------- 2 files changed, 137 insertions(+), 109 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index bddc4b446d..9db48fa4dc 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,7 +4,7 @@ "license": "BSD-2-Clause", "private": false, "dependencies": { - "@formatjs/intl-locale": "^2.4.20", + "@formatjs/intl-locale": "^2.4.21", "@formatjs/intl-pluralrules": "^4.0.12", "@formatjs/intl-relativetimeformat": "^8.1.3", "@formatjs/macro": "^0.2.8", @@ -41,7 +41,7 @@ "mapbox-gl-draw-rectangle-mode": "^1.0.4", "marked": "^2.0.1", "osmtogeojson": "^3.0.0-beta.3", - "query-string": "^6.14.1", + "query-string": "^7.0.0", "react": "^17.0.2", "react-accessible-accordion": "^3.3.4", "react-calendar-heatmap": "^1.8.1", @@ -51,7 +51,7 @@ "react-dom": "^17.0.2", "react-dropzone": "^11.3.1", "react-final-form": "^6.5.3", - "react-intl": "^5.13.5", + "react-intl": "^5.15.5", "react-meta-elements": "^1.0.0", "react-placeholder": "^4.1.0", "react-redux": "^7.2.3", @@ -66,7 +66,7 @@ "shpjs": "^3.6.3", "slug": "^4.0.3", "tachyons": "^4.12.0", - "use-query-params": "^1.2.0", + "use-query-params": "^1.2.2", "webfontloader": "^1.6.28", "workbox-core": "^6.1.2", "workbox-expiration": "^6.1.2", @@ -104,13 +104,13 @@ ] }, "devDependencies": { - "@testing-library/jest-dom": "^5.11.9", + "@testing-library/jest-dom": "^5.11.10", "@testing-library/react": "^11.2.4", "@testing-library/react-hooks": "^5.1.0", - "@testing-library/user-event": "^13.0.7", + "@testing-library/user-event": "^13.1.1", "combine-react-intl-messages": "^4.0.0", "jest-canvas-mock": "^2.3.1", - "msw": "^0.27.1", + "msw": "^0.28.0", "prettier": "^2.2.1", "react-select-event": "^5.3.0", "react-test-renderer": "^17.0.2", diff --git a/frontend/yarn.lock b/frontend/yarn.lock index be705220be..f3c10eb4c8 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2215,37 +2215,61 @@ dependencies: tslib "^2.1.0" -"@formatjs/intl-displaynames@4.0.11": - version "4.0.11" - resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-4.0.11.tgz#7872625234c15f6e9ab91473a6de1ab26def1fda" - integrity sha512-e3917+HmXStxb2fNP3sOr3R1DMALdWrUteBb3nerA2AKa12mXwmL0lDavrdltwZWqF7/Egh8fF/esB0Z/fqOgQ== +"@formatjs/ecma402-abstract@1.6.4": + version "1.6.4" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.6.4.tgz#cff5ef03837fb6bae70b16d04940213c17e87884" + integrity sha512-ukFjGD9dLsxcD9D5AEshJqQElPQeUAlTALT/lzIV6OcYojyuU81gw/uXDUOrs6XW79jtOJwQDkLqHbCJBJMOTw== dependencies: - "@formatjs/ecma402-abstract" "1.6.3" tslib "^2.1.0" -"@formatjs/intl-getcanonicallocales@1.5.7": - version "1.5.7" - resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-1.5.7.tgz#ec59cf2bcf54ab56a133cc6c277612b1535adfdd" - integrity sha512-raPV3Dw7CBC9kPvKdgxkVGgwzYBsQDDG9qXGWblpj/zR+ZJ6Q2V+Co5jZhrviy6lq3qaM2T1Itc0ibvvil1tBw== +"@formatjs/icu-messageformat-parser@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-1.1.2.tgz#e0d41edcfd031c0627b0f40dfcce5883d765df5d" + integrity sha512-AgwoQ2XUL+bQ/v7t4TBJh9vsob8zXgfM3RNe3MvJBCVOEZ+9z8mszsqeae/DmJgLK6SDezJex5O9Vdiny58Pwg== + dependencies: + "@formatjs/ecma402-abstract" "1.6.4" + "@formatjs/icu-skeleton-parser" "1.1.1" + tslib "^2.1.0" + +"@formatjs/icu-skeleton-parser@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.1.1.tgz#b2c39a7817816d68d31272947dded970f6d1d1c7" + integrity sha512-hkRJhjr9G0IE730Kxwq65+rz/2fdCckSJTPrKmViMxLNtRmIt6Hx67tffElr9/QSlpzGlXw9XAMdFOa1ylRrJQ== + dependencies: + "@formatjs/ecma402-abstract" "1.6.4" + tslib "^2.1.0" + +"@formatjs/intl-displaynames@4.0.12": + version "4.0.12" + resolved "https://registry.yarnpkg.com/@formatjs/intl-displaynames/-/intl-displaynames-4.0.12.tgz#9af9992e544aa96b32c3a4994d6fef878e0376c9" + integrity sha512-2f3nf5IcPYk2SCS83rJoV5y47OTL+YtHDa5G42KDgSA8ZgmgkN5OaYs3WF6a2RweMG9jp4LCTUmqS42LcAhJSw== + dependencies: + "@formatjs/ecma402-abstract" "1.6.4" + tslib "^2.1.0" + +"@formatjs/intl-getcanonicallocales@1.5.8": + version "1.5.8" + resolved "https://registry.yarnpkg.com/@formatjs/intl-getcanonicallocales/-/intl-getcanonicallocales-1.5.8.tgz#3af767a065e733697594fdeb5ed3949451c1be35" + integrity sha512-6GEIfCsZ+wd/K8bixP5h0Ep5aOjMgHlM51TeznlcNoiOHPP4gOrkxggh2Y2G5lnk71Ocyi93/+d0oKJI3J0jzw== dependencies: cldr-core "38" tslib "^2.1.0" -"@formatjs/intl-listformat@5.0.12": - version "5.0.12" - resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-5.0.12.tgz#da0daa1988bc753be915e5361b7c237a3bca314e" - integrity sha512-xWAndG73lqJ1+ar6SljCpM9nUsi2YoZfKi45F2YZRSxtUx4JbWYkhpbroOwxjCQ8ppZFoPc2mlLZjhPZiTyG7g== +"@formatjs/intl-listformat@5.0.13": + version "5.0.13" + resolved "https://registry.yarnpkg.com/@formatjs/intl-listformat/-/intl-listformat-5.0.13.tgz#5b13057a12642089108ddf4316bab976319fd941" + integrity sha512-z4vZ5FX6dsL2fbO7NCmmJXKXH9p0gubzZVSsmCOUBIuy6rODLD8kE2LVnefd4wnXEJi5/fAnwGT2NMjirWa71g== dependencies: - "@formatjs/ecma402-abstract" "1.6.3" + "@formatjs/ecma402-abstract" "1.6.4" tslib "^2.1.0" -"@formatjs/intl-locale@^2.4.20": - version "2.4.20" - resolved "https://registry.yarnpkg.com/@formatjs/intl-locale/-/intl-locale-2.4.20.tgz#c86c4427b1b626ae622fbccbfc59bed67b026125" - integrity sha512-ZrVFxKab+W6jFP6WEYsNW0b7IlGYnCS20fdLN6u0LwPCPYRP5oqHBl0FFVD2+aNnQ1T/21Aol54fCr5LdN/49Q== +"@formatjs/intl-locale@^2.4.21": + version "2.4.21" + resolved "https://registry.yarnpkg.com/@formatjs/intl-locale/-/intl-locale-2.4.21.tgz#007a62db08ead1b8c0d85636f96af31275601125" + integrity sha512-AH7d6XaLq1pXZ/AQ4dRNveKmA0juCCN3hFdpBvVA3XT4EMXIVkERh8PSa7xKgZThgXJwSLCZgKAeaARDzmhFRA== dependencies: - "@formatjs/ecma402-abstract" "1.6.3" - "@formatjs/intl-getcanonicallocales" "1.5.7" + "@formatjs/ecma402-abstract" "1.6.4" + "@formatjs/intl-getcanonicallocales" "1.5.8" cldr-core "38" tslib "^2.1.0" @@ -2277,17 +2301,17 @@ resolved "https://registry.yarnpkg.com/@formatjs/intl-utils/-/intl-utils-2.2.1.tgz#0eeefe92d317acfcd179c14826e719b3b130d82a" integrity sha512-WF3oU6l2WqJjN4OWvnjF9AHyQjHpjcfpyuckM7euFeX6ZGRPpPj+ZCqzf41g81MSksf9aZI4fFCZXWTBusgcWA== -"@formatjs/intl@1.8.4": - version "1.8.4" - resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.8.4.tgz#66418092611777f050ab99ba5fe66b89dbcbd846" - integrity sha512-m0/5ZRQZZfzXmeDieoG8kxu3QRvJazv2VbXhROs5khJKfUKu1rz6xfuUrh3gkmydWYtHuwJDIoC9oGR0ik4+/g== +"@formatjs/intl@1.9.5": + version "1.9.5" + resolved "https://registry.yarnpkg.com/@formatjs/intl/-/intl-1.9.5.tgz#02bc32ab9e52b7f0201c964a696609b6d455cca2" + integrity sha512-PEvdDuppTHW23B4s1nzKCY1wku3HYEgmV2ip02RspSUKl8p3t/TCwb1/U3Qwhgj3EUsjYdiaF1uyMj61eChAow== dependencies: - "@formatjs/ecma402-abstract" "1.6.3" - "@formatjs/intl-displaynames" "4.0.11" - "@formatjs/intl-listformat" "5.0.12" + "@formatjs/ecma402-abstract" "1.6.4" + "@formatjs/icu-messageformat-parser" "1.1.2" + "@formatjs/intl-displaynames" "4.0.12" + "@formatjs/intl-listformat" "5.0.13" fast-memoize "^2.5.2" - intl-messageformat "9.5.3" - intl-messageformat-parser "6.4.3" + intl-messageformat "9.6.4" tslib "^2.1.0" "@formatjs/macro@^0.2.8": @@ -2791,6 +2815,24 @@ resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== +"@mswjs/cookies@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@mswjs/cookies/-/cookies-0.1.4.tgz#85ef872997eea2acd888f21af0b2067224dac244" + integrity sha512-gdtmSv21D4wHTnqF4rrZVX6ye7mQ4nRCTIHYnHBr4SkgoXaiqe3sMvUzXm43+H4PnL0EAKvUTxRVSSXz2xebeg== + dependencies: + "@types/set-cookie-parser" "^2.4.0" + set-cookie-parser "^2.4.6" + +"@mswjs/interceptors@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.8.1.tgz#8ef43a8b7b25c7b9a2bac67b3702167e25e5fc07" + integrity sha512-OI9FYmtURESZG3QDNz4Yt3osy3HY4T3FjlRw+AG4QS1UDdTSZ0tuPFAkp23nGR9ojmbSSj4gSMjf5+R8Oi/qtQ== + dependencies: + "@open-draft/until" "^1.0.3" + debug "^4.3.0" + headers-utils "^3.0.2" + strict-event-emitter "^0.2.0" + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" @@ -3099,10 +3141,10 @@ lz-string "^1.4.4" pretty-format "^26.6.2" -"@testing-library/jest-dom@^5.11.9": - version "5.11.9" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.11.9.tgz#e6b3cd687021f89f261bd53cbe367041fbd3e975" - integrity sha512-Mn2gnA9d1wStlAIT2NU8J15LNob0YFBVjs2aEQ3j8rsfRQo+lAs7/ui1i2TGaJjapLmuNPLTsrm+nPjmZDwpcQ== +"@testing-library/jest-dom@^5.11.10": + version "5.11.10" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.11.10.tgz#1cd90715023e1627f5ed26ab3b38e6f22d77046c" + integrity sha512-FuKiq5xuk44Fqm0000Z9w0hjOdwZRNzgx7xGGxQYepWFZy+OYUMOT/wPI4nLYXCaVltNVpU1W/qmD88wLWDsqQ== dependencies: "@babel/runtime" "^7.9.2" "@types/testing-library__jest-dom" "^5.9.1" @@ -3133,10 +3175,10 @@ "@babel/runtime" "^7.12.5" "@testing-library/dom" "^7.28.1" -"@testing-library/user-event@^13.0.7": - version "13.0.7" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.0.7.tgz#835634e4cd6db6d63eb9398bd62fb26120f85dfd" - integrity sha512-EJBruqe7mV9OwPrZBx9HhFXt84KLinNNiGB0gqVp6+gPJ1ZP99Nq5FieChb/54fzmddGLkMp5ndbZBaEADdxrQ== +"@testing-library/user-event@^13.1.1": + version "13.1.1" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.1.1.tgz#1e011de944cf4d2a917cef6c3046c26389943e24" + integrity sha512-B4roX+0mpXKGj8ndd38YoIo3IV9pmTTWxr/2cOke5apTtrNabEUE0KMBccpcAcYlfPcr7uMu+dxeeC3HdXd9qQ== dependencies: "@babel/runtime" "^7.12.5" @@ -6939,6 +6981,11 @@ events@^3.0.0: resolved "https://registry.yarnpkg.com/events/-/events-3.1.0.tgz#84279af1b34cb75aa88bf5ff291f6d0bd9b31a59" integrity sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg== +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + eventsource@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0" @@ -7871,10 +7918,10 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -headers-utils@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/headers-utils/-/headers-utils-1.2.0.tgz#5e10d1bc9d2bccf789547afca5b991a3167241e8" - integrity sha512-4/BMXcWrJErw7JpM87gF8MNEXcIMLzepYZjNRv/P9ctgupl2Ywa3u1PgHtNhSRq84bHH9Ndlkdy7bSi+bZ9I9A== +headers-utils@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/headers-utils/-/headers-utils-3.0.2.tgz#dfc65feae4b0e34357308aefbcafa99c895e59ef" + integrity sha512-xAxZkM1dRyGV2Ou5bzMxBPNLoRCjcX+ya7KSWybQD2KwLphxsapUVK6x/02o7f4VU6GPSXch9vNY2+gkU8tYWQ== hex-color-regex@^1.1.0: version "1.1.0" @@ -8298,14 +8345,6 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" -intl-messageformat-parser@6.4.3: - version "6.4.3" - resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-6.4.3.tgz#4326201256c52907f342c7bb058208113c3c7f95" - integrity sha512-gpB7OeKDSd9wqjIQ7wVQM9byrpMlokGoUfJND7DS9SjoBbOsZIHAHw+lrmAWYmq+MI3WQUeLouSFdYAZ6zSX9A== - dependencies: - "@formatjs/ecma402-abstract" "1.6.3" - tslib "^2.1.0" - intl-messageformat-parser@^3.6.4: version "3.6.4" resolved "https://registry.yarnpkg.com/intl-messageformat-parser/-/intl-messageformat-parser-3.6.4.tgz#5199d106d816c3dda26ee0694362a9cf823978fb" @@ -8313,13 +8352,13 @@ intl-messageformat-parser@^3.6.4: dependencies: "@formatjs/intl-unified-numberformat" "^3.2.0" -intl-messageformat@9.5.3: - version "9.5.3" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.5.3.tgz#cb89a91cc2da875c5c824d374ba8209fac63a3ca" - integrity sha512-Ei8vH41/icJsc16ZfWk1FzZ2SpaVn0gElXsQCKKPerxK/28m1gVdH0G26GuCqAyz5ETEJiSRn8sPMaSWJDuTjg== +intl-messageformat@9.6.4: + version "9.6.4" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-9.6.4.tgz#6ee964235c37b864359dc848b3dd5ea984cc8065" + integrity sha512-NCstnz4qiRYHRiFwAadptARV0XGv8dFtC6ZcDfjKlFePvyyQ9zkPXq28Tg7UPTfUZnOfGjnxgi0mMem/5/TbDw== dependencies: + "@formatjs/icu-messageformat-parser" "1.1.2" fast-memoize "^2.5.2" - intl-messageformat-parser "6.4.3" tslib "^2.1.0" into-stream@^3.1.0: @@ -10177,11 +10216,13 @@ ms@2.1.2, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -msw@^0.27.1: - version "0.27.1" - resolved "https://registry.yarnpkg.com/msw/-/msw-0.27.1.tgz#9dad215cd53b8b1b5e9446aa586e20cc8e2e086a" - integrity sha512-oAhqvOTEX16DjMFoYZaI10KeiYMMCnQR8EcXEFu2KzA6khmUe9tSM0rDRyO/wvuMLffODgVRdSkjCId90yFyVw== +msw@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/msw/-/msw-0.28.0.tgz#abed17416f59241a2100fe6c8740cc1c9a32339b" + integrity sha512-Hh+dPp613tethIFwNg90lvAzrW9T0U39D6AYzV8qIOAWskP49CErrqVWZnmPDQC87o69GzZ9Hl3RGz/65mms3A== dependencies: + "@mswjs/cookies" "^0.1.4" + "@mswjs/interceptors" "^0.8.0" "@open-draft/until" "^1.0.3" "@types/cookie" "^0.4.0" "@types/inquirer" "^7.3.1" @@ -10190,15 +10231,13 @@ msw@^0.27.1: chokidar "^3.4.2" cookie "^0.4.1" graphql "^15.4.0" - headers-utils "^1.2.0" + headers-utils "^3.0.2" inquirer "^7.3.3" js-levenshtein "^1.1.6" node-fetch "^2.6.1" node-match-path "^0.6.1" - node-request-interceptor "^0.6.3" statuses "^2.0.0" strict-event-emitter "^0.1.0" - virtual-cookies "^0.1.2" yargs "^16.2.0" multicast-dns-service-types@^1.1.0: @@ -10382,16 +10421,6 @@ node-releases@^1.1.69: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08" integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw== -node-request-interceptor@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/node-request-interceptor/-/node-request-interceptor-0.6.3.tgz#f2f0dbec2d421584419dd39ff6782ce1e02b42a7" - integrity sha512-8I2V7H2Ch0NvW7qWcjmS0/9Lhr0T6x7RD6PDirhvWEkUQvy83x8BA4haYMr09r/rig7hcgYSjYh6cd4U7G1vLA== - dependencies: - "@open-draft/until" "^1.0.3" - debug "^4.3.0" - headers-utils "^1.2.0" - strict-event-emitter "^0.1.0" - "nomnom@>= 1.5.x": version "1.8.1" resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" @@ -12054,10 +12083,10 @@ query-string@^5.0.1: object-assign "^4.1.0" strict-uri-encode "^1.0.0" -query-string@^6.14.1: - version "6.14.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.14.1.tgz#7ac2dca46da7f309449ba0f86b1fd28255b0c86a" - integrity sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw== +query-string@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.0.0.tgz#aaad2c8d5c6a6d0c6afada877fecbd56af79e609" + integrity sha512-Iy7moLybliR5ZgrK/1R3vjrXq03S13Vz4Rbm5Jg3EFq1LUmQppto0qtXz4vqZ386MSRjZgnTSZ9QC+NZOSd/XA== dependencies: decode-uri-component "^0.2.0" filter-obj "^1.1.0" @@ -12285,19 +12314,19 @@ react-input-autosize@^3.0.0: dependencies: prop-types "^15.5.8" -react-intl@^5.13.5: - version "5.13.5" - resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.13.5.tgz#32bb74120b67950fe63329db58aa83cfac73f6c8" - integrity sha512-Ym6knnC04k070vwe3UDcRHQUDE2rGn1PNfmYNhDHVPL6vbusuFbefjnt8ZC1GEjnfo29WUHn/tkGd9SMudzD+g== +react-intl@^5.15.5: + version "5.15.5" + resolved "https://registry.yarnpkg.com/react-intl/-/react-intl-5.15.5.tgz#a475445f7e9d9085040d622528ed18a082b03b5d" + integrity sha512-TdjMVU0xkH5hKonv/g5x2sD94iojErqlDMbLADsTmz1dgRDc6iLRP5b7mtp0//pkK/psrb283B8HL1wp1vhpiQ== dependencies: - "@formatjs/ecma402-abstract" "1.6.3" - "@formatjs/intl" "1.8.4" - "@formatjs/intl-displaynames" "4.0.11" - "@formatjs/intl-listformat" "5.0.12" + "@formatjs/ecma402-abstract" "1.6.4" + "@formatjs/icu-messageformat-parser" "1.1.2" + "@formatjs/intl" "1.9.5" + "@formatjs/intl-displaynames" "4.0.12" + "@formatjs/intl-listformat" "5.0.13" "@types/hoist-non-react-statics" "^3.3.1" hoist-non-react-statics "^3.3.2" - intl-messageformat "9.5.3" - intl-messageformat-parser "6.4.3" + intl-messageformat "9.6.4" tslib "^2.1.0" react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.1: @@ -13279,10 +13308,10 @@ serialize-javascript@^5.0.1: dependencies: randombytes "^2.1.0" -serialize-query-params@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/serialize-query-params/-/serialize-query-params-1.3.1.tgz#f9353fbf397e27b12ff6a3232670972559e62172" - integrity sha512-oDMjBDqoutgbZIX+4xZxa+DD4gQ/q8C66ukPZbe27msutU21yML9UYsBz+jDKklQh6atdnGlTMHa6YBvjKZwhQ== +serialize-query-params@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/serialize-query-params/-/serialize-query-params-1.3.3.tgz#a4bf0fc0ab9e80c92b93cdf9d84ec521d769ecbe" + integrity sha512-rJIIETRuGUVbLekC73IiXV3738ylEHbHK1kxaXAbhxbxfio0yvVXaRMF+OyLZOBMwdgDHYLaj6EMBAEiSf8C/g== serve-index@^1.9.1: version "1.9.1" @@ -13800,6 +13829,13 @@ strict-event-emitter@^0.1.0: resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.1.0.tgz#fd742c1fb7e3852f0b964ecdae2d7666a6fb7ef8" integrity sha512-8hSYfU+WKLdNcHVXJ0VxRXiPESalzRe7w1l8dg9+/22Ry+iZQUoQuoJ27R30GMD1TiyYINWsIEGY05WrskhSKw== +strict-event-emitter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.2.0.tgz#78e2f75dc6ea502e5d8a877661065a1e2deedecd" + integrity sha512-zv7K2egoKwkQkZGEaH8m+i2D0XiKzx5jNsiSul6ja2IYFvil10A59Z9Y7PPAAe5OW53dQUf9CfsHKzjZzKkm1w== + dependencies: + events "^3.3.0" + strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" @@ -14720,12 +14756,12 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" -use-query-params@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-query-params/-/use-query-params-1.2.0.tgz#91dda012a9f3767120515a0de5078919444d3aa8" - integrity sha512-XsLVW/Pt2zC9rDoUW3z+HlW3azv6JaSrWRIGkVCksSLLeXKjNA93P2TLTvpM+sjBUOLoFCMtGUIdTL3ad9OYuw== +use-query-params@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/use-query-params/-/use-query-params-1.2.2.tgz#4c4b274133d699605301510b5aa01047f92b5ce0" + integrity sha512-Uyfe+/TECsNNzCSkgUM1MM24OEGxGE4aeWvZEf0a14iQFp/m43wiqI1HZ9oTlrRSZwD5yABeLc9rN+wtiB5B3Q== dependencies: - serialize-query-params "^1.3.1" + serialize-query-params "^1.3.3" use@^3.1.0: version "3.1.1" @@ -14876,14 +14912,6 @@ vfile@^4.0.0: unist-util-stringify-position "^2.0.0" vfile-message "^2.0.0" -virtual-cookies@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/virtual-cookies/-/virtual-cookies-0.1.2.tgz#67683d2bba98b9351d9446274ccbfb9c105671cd" - integrity sha512-mcjWP9Jp1Qzsm06aXKVUJaTaSdnPuRFz/KOLkx7joAJEcWjdQVJwfyKjlvUS6kpKDhZGWi0qSCZelMc6uij9BQ== - dependencies: - "@types/set-cookie-parser" "^2.4.0" - set-cookie-parser "^2.4.6" - vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" From 004d6db6afe6e4becba9e3180d014741ee46e44f Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Tue, 30 Mar 2021 15:18:41 -0300 Subject: [PATCH 22/24] Update translations --- .../src/components/projectCreate/messages.js | 2 +- frontend/src/locales/ar.json | 7 ++++++ frontend/src/locales/cs.json | 13 +++++++--- frontend/src/locales/de.json | 17 +++++++++---- frontend/src/locales/el.json | 11 ++++++-- frontend/src/locales/en.json | 2 +- frontend/src/locales/es.json | 11 ++++++-- frontend/src/locales/fa_IR.json | 11 ++++++-- frontend/src/locales/fr.json | 11 ++++++-- frontend/src/locales/he.json | 11 ++++++-- frontend/src/locales/hu.json | 11 ++++++-- frontend/src/locales/id.json | 11 ++++++-- frontend/src/locales/it.json | 11 ++++++-- frontend/src/locales/ja.json | 11 ++++++-- frontend/src/locales/ko.json | 11 ++++++-- frontend/src/locales/mg.json | 9 ++++++- frontend/src/locales/ml.json | 7 ++++++ frontend/src/locales/nl_NL.json | 17 +++++++++---- frontend/src/locales/pt.json | 25 ++++++++++++------- frontend/src/locales/pt_BR.json | 11 ++++++-- frontend/src/locales/sv.json | 11 ++++++-- frontend/src/locales/sw.json | 11 ++++++-- frontend/src/locales/tl.json | 7 ++++++ frontend/src/locales/tr.json | 11 ++++++-- frontend/src/locales/uk.json | 13 +++++++--- frontend/src/locales/zh_TW.json | 9 ++++++- 26 files changed, 225 insertions(+), 57 deletions(-) diff --git a/frontend/src/components/projectCreate/messages.js b/frontend/src/components/projectCreate/messages.js index efe25545c4..a090b81824 100644 --- a/frontend/src/components/projectCreate/messages.js +++ b/frontend/src/components/projectCreate/messages.js @@ -88,7 +88,7 @@ export default defineMessages({ tinyTasks: { id: 'management.projects.create.trim_tasks.tiny_tasks', defaultMessage: - '{number, plural, one {There is # task smaller than {area}m². Would you like to discard them?} other {There are # tasks smaller than {area}m². Would you like to discard them?}}', + '{number, plural, one {There is # task smaller than {area}m². Would you like to discard it?} other {There are # tasks smaller than {area}m². Would you like to discard them?}}', }, discard: { id: 'management.projects.create.trim_tasks.tiny_tasks.discard', diff --git a/frontend/src/locales/ar.json b/frontend/src/locales/ar.json index cfc4c12009..0c6f72fe93 100644 --- a/frontend/src/locales/ar.json +++ b/frontend/src/locales/ar.json @@ -59,6 +59,7 @@ "header.nav.manage": "", "header.buttons.logIn": "", "header.buttons.signUp": "", + "header.buttons.createAccount": "", "header.buttons.authorize": "", "signUp.modal.authorize": "", "signUp.authorize.message": "", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "", "management.projects.create.trim_tasks.description.2": "", "management.projects.create.trim_tasks.trim_to_aoi": "", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, zero {} one {} two {} few {} many {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "", "management.projects.create.task_sizes.smaller": "", "management.projects.create.task_sizes.larger": "", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "", "projects.formInputs.categories.title": "", "projects.formInputs.organisation.description": "", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "", "projects.formInputs.campaign.select": "", @@ -556,6 +560,7 @@ "project.imagery.wmts": "", "project.imagery.customLayer": "", "project.imagery.noDefined": "", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "", "project.selectTask.footer.button.mapSelectedTask": "", "project.selectTask.footer.button.mapAnotherTask": "", @@ -901,6 +906,8 @@ "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "", "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "", "management.users.title": "", "management.stats.users.title": "", diff --git a/frontend/src/locales/cs.json b/frontend/src/locales/cs.json index 3b0ebc8632..dd23e5abc1 100644 --- a/frontend/src/locales/cs.json +++ b/frontend/src/locales/cs.json @@ -59,6 +59,7 @@ "header.nav.manage": "Spravovat", "header.buttons.logIn": "Přihlásit se", "header.buttons.signUp": "Registrovat se", + "header.buttons.createAccount": "", "header.buttons.authorize": "Přihlásit se", "signUp.modal.authorize": "Dokončili jste registraci na OpenStreetMap?", "signUp.authorize.message": "Začněte mapovat hned teď! Stačí se přihlásit do Tasking Manageru pomocí nového účtu OpenStreetMap.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Oříznout hranice úlohy na oblast zájmu (volitelné).", "management.projects.create.trim_tasks.description.2": "Můžete ponechat aktuální úlohy, nebo můžete zúžit pohled na váš projekt. Provedení může chvíli trvat.", "management.projects.create.trim_tasks.trim_to_aoi": "Oblast zájmu mapování definujte oříznutím oblasti úlohy.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} few {} many {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Obecná velikost úlohy", "management.projects.create.task_sizes.smaller": "Menší", "management.projects.create.task_sizes.larger": "Větší", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Kampaň", "projects.formInputs.categories.title": "Kategorie", "projects.formInputs.organisation.description": "Organizace, která koordinuje projekt, pokud byl nějaký vytvořen. Správci této organizace, budou mít administrátorská práva k tomuto projektu.", + "projects.formInputs.imagery.select": "Výběr snímků", "projects.formInputs.license.select": "Vybrat licence", "projects.formInputs.organisation.select": "Zvolte organizaci", "projects.formInputs.campaign.select": "Vybrat kampaně", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Vynutit náhodný výběr úlohy", "projects.formInputs.random_task_selection.mapping": "Vynutit náhodný výběr úlohy při mapování", "projects.formInputs.random_task_selection.description": "Pokud je zaškrtnuto, uživatelé musí editovat úkoly náhodně v počáteční fázi editace (pro správce a administrátory to neplatí).", - "projects.formInputs.imagery": "URL mapového podkladu", + "projects.formInputs.imagery": "Mapový podklad", "projects.formInputs.imagery.note": "Používejte tento formát adres TMS URL: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Nakreslit polygon", "projects.formInputs.priority_areas.options.rectangle": "Nakreslit obdélník", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Vlastní vrstva WMTS", "project.imagery.customLayer": "Vlastní vrstva", "project.imagery.noDefined": "Jakýkoliv dostupný zdroj", + "project.imagery.copy": "Kopírovat URL snímků", "project.selectTask.footer.button.mapRandomTask": "Mapovat úlohu", "project.selectTask.footer.button.mapSelectedTask": "Mapovat vybranou úlohu", "project.selectTask.footer.button.mapAnotherTask": "Mapovat další úlohu", @@ -734,7 +739,7 @@ "management.organisations.stats.tier.estimation": "Odhadovaná úroveň do konce {year}", "management.organisations.stats.cost.estimation": "Odhadované náklady do konce {year}", "management.organisations.stats.next_level.actions": "Akce k dosažení stupně {n}", - "management.organisations.stats.tier.actions_remaining": "", + "management.organisations.stats.tier.actions_remaining": "Akce zbývající na úrovni {name}", "management.organisations.tier.free": "Zdarma", "management.organisations.tier.low": "Nízká", "management.organisations.tier.medium": "Střední", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Nemáte práva pro přístup do správcovské sekce ", "teamsAndOrgs.management.project.forbidden": "Nemáte oprávnění upravovat tento projekt.", "teamsAndOrgs.management.team.forbidden": "Nemáte oprávnění upravovat tento tým.", - "loginPage.title": "Přihlaste se nebo registrujte účet", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Správci", "management.users.title": "Spravovat uživatele", "management.stats.users.title": "Noví uživatelé", diff --git a/frontend/src/locales/de.json b/frontend/src/locales/de.json index bcbce9944b..8a097260d1 100644 --- a/frontend/src/locales/de.json +++ b/frontend/src/locales/de.json @@ -59,6 +59,7 @@ "header.nav.manage": "Verwalten", "header.buttons.logIn": "Anmelden", "header.buttons.signUp": "Registrieren", + "header.buttons.createAccount": "", "header.buttons.authorize": "Anmelden", "signUp.modal.authorize": "Haben Sie Ihre Registrierung bei OpenStreetMap abgeschlossen?", "signUp.authorize.message": "Beginne Sie mit der Kartierung! Dazu melden Sie sich am Tasking Manager mit Ihrem neuen OpenStreetMap-Benutzerkonto an.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Das Aufgabenraster auf den Projektbereich zuschneiden (optional).", "management.projects.create.trim_tasks.description.2": "Sie können die Einteilung der Aufgaben so belassen oder auf den Projektbereich zuschneiden. Dies kann einige Zeit in Anspruch nehmen.", "management.projects.create.trim_tasks.trim_to_aoi": "Schneiden Sie die Aufgaben so zurecht, dass sie genau das Arbeitsgebiet abdecken.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Allgemeine Größe der Aufgaben", "management.projects.create.task_sizes.smaller": "Kleiner", "management.projects.create.task_sizes.larger": "Größer", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Kampagne", "projects.formInputs.categories.title": "Themen", "projects.formInputs.organisation.description": "Die Organisation, welche das Projekt koordiniert (falls vorhanden). Die Manager dieser Organisation haben Administratorrechte für das Projekt.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "Wählen Sie eine Lizenz", "projects.formInputs.organisation.select": "Organisation auswählen", "projects.formInputs.campaign.select": "Kampagnen auswählen", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Zufällige Aufgabenauswahl erzwingen", "projects.formInputs.random_task_selection.mapping": "Zufällige Aufgabenauswahl für die Kartierung erzwingen", "projects.formInputs.random_task_selection.description": "Wenn diese Option aktiviert ist, müssen Benutzer zufällig ausgewählte Aufgaben kartieren (Projektmanager und Administratoren sind ausgenommen).\n", - "projects.formInputs.imagery": "Bilddaten-URL", + "projects.formInputs.imagery": "Bildmaterial", "projects.formInputs.imagery.note": "Benutzen Sie dieses Format für TMS-URLs: {exampleURL}", "projects.formInputs.priority_areas.options.polygon": "Polygon zeichnen", "projects.formInputs.priority_areas.options.rectangle": "Rechteck zeichnen", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Benutzerdefinierte WMTS-Ebene", "project.imagery.customLayer": "Benutzerdefinierte Bildebene", "project.imagery.noDefined": "Alle verfügbaren Quellen", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Kartieren Sie eine Aufgabe", "project.selectTask.footer.button.mapSelectedTask": "Ausgewählte Aufgabe kartieren", "project.selectTask.footer.button.mapAnotherTask": "Eine andere Aufgabe kartieren", @@ -869,9 +874,9 @@ "users.detail.roadMapped": "km Straßen kartiert", "users.detail.poiMapped": "\"Points of Interest\" kartiert", "users.detail.waterwaysMapped": "", - "users.detail.tasksMapped": "{user} kartiert", - "users.detail.you": "Sie", - "users.detail.tasksValidated": "{user} validiert", + "users.detail.tasksMapped": "Von {user} kartiert", + "users.detail.you": "Ihnen", + "users.detail.tasksValidated": "Von {user} validiert", "users.detail.invalidated": "Benötigt mehr Kartierung", "users.detail.validated": "Validiert", "users.detail.finished": "Fertig", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Sie haben nicht die Erlaubnis den Verwaltungsbereich zu öffnen.", "teamsAndOrgs.management.project.forbidden": "Sie dürfen dieses Projekt nicht bearbeiten.", "teamsAndOrgs.management.team.forbidden": "Sie dürfen dieses Team nicht bearbeiten.", - "loginPage.title": "Anmeldung oder Kontoregistrierung", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Manager", "management.users.title": "Benutzerverwaltung", "management.stats.users.title": "Neue Benutzer", diff --git a/frontend/src/locales/el.json b/frontend/src/locales/el.json index 8e1731b30b..b3f67f0907 100644 --- a/frontend/src/locales/el.json +++ b/frontend/src/locales/el.json @@ -59,6 +59,7 @@ "header.nav.manage": "Διαχειριστείτε", "header.buttons.logIn": "Συνδεθείτε", "header.buttons.signUp": "Εγγραφείτε", + "header.buttons.createAccount": "", "header.buttons.authorize": "Συνδεθείτε", "signUp.modal.authorize": "Έχετε ολοκληρώσει την εγγραφή στο OpenStreetMap;", "signUp.authorize.message": "Ξεκινήστε τη χαρτογράφηση τώρα! Απλά συνδεθείτε στο Διαχειριστή Εργασιών με το νέο σας λογαριασμό OpenStreetMap.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Περικόψτε το πλέγμα εργασίας στην περιοχή ενδιαφέροντος (προαιρετικό).", "management.projects.create.trim_tasks.description.2": "Μπορείτε να διατηρήσετε τις τρέχουσες εργασίες ή να περικόψετε την περιοχή για το έργο σας. Ενδέχεται αυτό να χρειαστεί κάποιο χρόνο για να εκτελεστεί.", "management.projects.create.trim_tasks.trim_to_aoi": "Περικόψτε τις εργασίες για να ορίσετε την ακριβή Περιοχή Ενδιαφέροντος προς χαρτογράφηση.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Γενικό μέγεθος εργασίας", "management.projects.create.task_sizes.smaller": "Μικρότερο", "management.projects.create.task_sizes.larger": "Μεγαλύτερο", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Καμπάνια", "projects.formInputs.categories.title": "Κατηγορίες", "projects.formInputs.organisation.description": "Οργανισμός συντονισμού του έργου, εφόσον υπάρχει. Οι διευθυντές αυτού του οργανισμού θα έχουν δικαιώματα διαχείρισης επί του έργου.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "Επιλέξτε άδεια", "projects.formInputs.organisation.select": "Επιλέξτε Οργανισμό", "projects.formInputs.campaign.select": "Επιλέξτε καμπάνιες", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Επιβάλετε τυχαία επιλογή εργασίας", "projects.formInputs.random_task_selection.mapping": "Επιβάλετε την τυχαία επιλογή εργασιών κατά την χαρτογράφηση", "projects.formInputs.random_task_selection.description": "Εάν ενεργοποιηθεί, οι χρήστες πρέπει να επεξεργαστούν τυχαία εργασίες για το αρχικό στάδιο επεξεργασίας (εξαιρούνται οι διευθυντές και οι διαχειριστές).", - "projects.formInputs.imagery": "URL εικόνων", + "projects.formInputs.imagery": "Εικόνες", "projects.formInputs.imagery.note": "Ακολουθήστε αυτό τον μορφότυπο για τα TMS URLs: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Σχεδιάστε πολύγωνο", "projects.formInputs.priority_areas.options.rectangle": "Σχεδιάστε ορθογώνιο", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Προσαρμοσμένο Υπόβαθρο WMTS", "project.imagery.customLayer": "Προσαρμοσμένο Υπόβαθρο", "project.imagery.noDefined": "Κάθε διαθέσιμη πηγή", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Χαρτογραφήστε μία εργασία", "project.selectTask.footer.button.mapSelectedTask": "Χαρτογραφήστε την επιλεγμένη εργασία", "project.selectTask.footer.button.mapAnotherTask": "Χαρτογραφήστε άλλη εργασία", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Δεν σας επιτρέπεται η πρόσβαση στην περιοχή διεύθυνσης.", "teamsAndOrgs.management.project.forbidden": "Δεν σας επιτρέπεται να επεξεργαστείτε αυτό το έργο.", "teamsAndOrgs.management.team.forbidden": "Δεν σας επιτρέπεται να επεξεργαστείτε αυτή την ομάδα.", - "loginPage.title": "Συνδεθείτε ή κάντε εγγραφή λογαριασμού", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Διευθυντές", "management.users.title": "Διαχείριση χρηστών", "management.stats.users.title": "Νέοι χρήστες", diff --git a/frontend/src/locales/en.json b/frontend/src/locales/en.json index 22849fb12c..274b798569 100644 --- a/frontend/src/locales/en.json +++ b/frontend/src/locales/en.json @@ -216,7 +216,7 @@ "management.projects.create.trim_tasks.description.1": "Trim the task grid to the area of interest (optional).", "management.projects.create.trim_tasks.description.2": "You can keep the current tasks or trim the area for your project. This can take some time to execute.", "management.projects.create.trim_tasks.trim_to_aoi": "Trim the tasks to define the exact Area of Interest for mapping.", - "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {There is # task smaller than {area}m². Would you like to discard them?} other {There are # tasks smaller than {area}m². Would you like to discard them?}}", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {There is # task smaller than {area}m². Would you like to discard it?} other {There are # tasks smaller than {area}m². Would you like to discard them?}}", "management.projects.create.trim_tasks.tiny_tasks.discard": "Discard", "management.projects.create.task_sizes.description": "General task size", "management.projects.create.task_sizes.smaller": "Smaller", diff --git a/frontend/src/locales/es.json b/frontend/src/locales/es.json index 5d135b57aa..3c0015cb40 100644 --- a/frontend/src/locales/es.json +++ b/frontend/src/locales/es.json @@ -59,6 +59,7 @@ "header.nav.manage": "Gestionar", "header.buttons.logIn": "Iniciar sesión", "header.buttons.signUp": "Regístrese", + "header.buttons.createAccount": "Crear una cuenta", "header.buttons.authorize": "Iniciar sesión", "signUp.modal.authorize": "¿Ha terminado el registro en OpenStreetMap?", "signUp.authorize.message": "¡Empieza a hacer un mapa ahora! Sólo tienes que iniciar sesión en el Tasking Manager con tu nueva cuenta de OpenStreetMap.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Recorte la cuadrícula de tareas al área de interés (opcional).", "management.projects.create.trim_tasks.description.2": "Puede mantener las tareas actuales o recortar el área para su proyecto. Esto puede tardar un tiempo en ejecutarse.", "management.projects.create.trim_tasks.trim_to_aoi": "Recorte las tareas para definir el área de interés exacta para el mapeo.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {Hay # tarea menor que {area} m². ¿Te gustaría descartarla?} other {Hay # tareas menores que {area} m². ¿Te gustaría descartarlas?}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "Descartar", "management.projects.create.task_sizes.description": "Tamaño de tarea general", "management.projects.create.task_sizes.smaller": "Más pequeño", "management.projects.create.task_sizes.larger": "Más grande", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Campaña", "projects.formInputs.categories.title": "Categorías", "projects.formInputs.organisation.description": "Organización que está coordinando el proyecto, si lo hay. Los gerentes de la organización tendrán derechos de administración sobre el proyecto.", + "projects.formInputs.imagery.select": "Seleccionar imágenes", "projects.formInputs.license.select": "Seleccionar licencia", "projects.formInputs.organisation.select": "Seleccione organizacion", "projects.formInputs.campaign.select": "Seleccionar campañas", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Obligar la selección de tareas al azar", "projects.formInputs.random_task_selection.mapping": "Obliga la selección de tareas al azar en el mapeo", "projects.formInputs.random_task_selection.description": "Si se marca, los usuarios deben editar las tareas de forma aleatoria para la etapa inicial de edición (los gerentes y administradores están exentos).", - "projects.formInputs.imagery": "URL de imágenes", + "projects.formInputs.imagery": "Imágenes", "projects.formInputs.imagery.note": "Siga este formato para las URL de TMS: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Dibujar polígono", "projects.formInputs.priority_areas.options.rectangle": "Dibujar rectángulo", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Capa WMTS personalizada", "project.imagery.customLayer": "Cubierta personalizada", "project.imagery.noDefined": "Cualquier fuente disponible", + "project.imagery.copy": "Copiar URL de las imágenes", "project.selectTask.footer.button.mapRandomTask": "Mapear una tarea", "project.selectTask.footer.button.mapSelectedTask": "Mapear tarea seleccionada", "project.selectTask.footer.button.mapAnotherTask": "Mapear otra tarea", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "No tiene permiso para acceder al área de administración", "teamsAndOrgs.management.project.forbidden": "No tiene permiso para editar este proyecto.", "teamsAndOrgs.management.team.forbidden": "No tienes permiso para editar este equipo.", - "loginPage.title": "Iniciar sesión o registrar una cuenta", + "loginPage.title": "Inicie sesión en {org} Tasking Manager", + "loginPage.text.login": "Puede iniciar sesión con una cuenta de OpenStreetMap.", + "loginPage.text.create_account": "O cree una nueva para comenzar a mapear.", "management.managers": "Gerentes", "management.users.title": "Gestionar usuarios", "management.stats.users.title": "Nuevos usuarios", diff --git a/frontend/src/locales/fa_IR.json b/frontend/src/locales/fa_IR.json index fd4eeaff54..8137c7d2da 100644 --- a/frontend/src/locales/fa_IR.json +++ b/frontend/src/locales/fa_IR.json @@ -59,6 +59,7 @@ "header.nav.manage": "مدیریت کنید", "header.buttons.logIn": "وارد شدن", "header.buttons.signUp": "ثبت نام", + "header.buttons.createAccount": "", "header.buttons.authorize": "وارد شدن", "signUp.modal.authorize": "", "signUp.authorize.message": "", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "", "management.projects.create.trim_tasks.description.2": "", "management.projects.create.trim_tasks.trim_to_aoi": "", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "", "management.projects.create.task_sizes.smaller": "کوچک تر", "management.projects.create.task_sizes.larger": "بزرگ تر", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "کمپین", "projects.formInputs.categories.title": "دسته بندی ها", "projects.formInputs.organisation.description": "", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "", "projects.formInputs.campaign.select": "", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "", "projects.formInputs.random_task_selection.mapping": "", "projects.formInputs.random_task_selection.description": "", - "projects.formInputs.imagery": "URL تصویر سازی", + "projects.formInputs.imagery": "تصویر", "projects.formInputs.imagery.note": "", "projects.formInputs.priority_areas.options.polygon": "رسم محدوده", "projects.formInputs.priority_areas.options.rectangle": "رسم مستطیل", @@ -556,6 +560,7 @@ "project.imagery.wmts": "", "project.imagery.customLayer": "", "project.imagery.noDefined": "هر منبع در دسترس", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "", "project.selectTask.footer.button.mapSelectedTask": "", "project.selectTask.footer.button.mapAnotherTask": "", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "", "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "", - "loginPage.title": "وارد شوید یا یک اکانت جدید بسازید", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "مدیران", "management.users.title": "مدیریت کاربران", "management.stats.users.title": "", diff --git a/frontend/src/locales/fr.json b/frontend/src/locales/fr.json index 0ae0cc3ccf..f2a31e0239 100644 --- a/frontend/src/locales/fr.json +++ b/frontend/src/locales/fr.json @@ -59,6 +59,7 @@ "header.nav.manage": "Gérer", "header.buttons.logIn": "Se connecter", "header.buttons.signUp": "Créer un compte", + "header.buttons.createAccount": "", "header.buttons.authorize": "Se connecter", "signUp.modal.authorize": "Avez-vous finalisé l'inscription sur OpenStreetMap?", "signUp.authorize.message": "Commencez à cartographier dès maintenant : connectez-vous sur le Tasking Manager avec votre nouveau compte OpenStreetMap.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Ajuster la grille des tâches à la zone d'intérêt (facultatif).", "management.projects.create.trim_tasks.description.2": "Vous pouvez conserver les tâches en cours ou ajuster la zone de votre projet. L'exécution peut prendre un certain temps.", "management.projects.create.trim_tasks.trim_to_aoi": "Ajuster la tâche pour définir la zone d'intérêt exacte pour la contribution.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Taille générale de la tâche", "management.projects.create.task_sizes.smaller": "Plus petit", "management.projects.create.task_sizes.larger": "Plus grand", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Campagne", "projects.formInputs.categories.title": "Catégories", "projects.formInputs.organisation.description": "Organisation qui coordonne le projet, le cas échéant. Les gestionnaires de cette organisation auront des droits d'administration sur le projet.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "Choisissez la license", "projects.formInputs.organisation.select": "Choisir une organisation", "projects.formInputs.campaign.select": "Sélectionner les campagnes", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Appliquer la sélection aléatoire des tâches", "projects.formInputs.random_task_selection.mapping": "Appliquer la sélection aléatoire des tâches sur la cartographie.", "projects.formInputs.random_task_selection.description": "Si coché, les utilisateurs doivent éditer au hasard des tâches pour l'étape initiale d'édition (les responsables et les administrateurs en sont exemptés).", - "projects.formInputs.imagery": "URL d'imagerie", + "projects.formInputs.imagery": "Imagerie", "projects.formInputs.imagery.note": "Suivez ce format pour les URLs TMS: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Dessiner un polygone", "projects.formInputs.priority_areas.options.rectangle": "Dessiner un rectangle", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Couche WMTS personnalisée", "project.imagery.customLayer": "Couche personnalisée", "project.imagery.noDefined": "Toute source disponible", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Cartographier une tâche", "project.selectTask.footer.button.mapSelectedTask": "Cartographier la tâche sélectionnée", "project.selectTask.footer.button.mapAnotherTask": "Cartographier une autre tâche", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Vous n'êtes pas autorisé à accéder à l'espace de gestion", "teamsAndOrgs.management.project.forbidden": "Vous n'êtes pas autorisé à modifier ce projet.", "teamsAndOrgs.management.team.forbidden": "Vous n'êtes pas autorisé à modifier cette équipe.", - "loginPage.title": "Connectez-vous ou créez un compte", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Chefs de projet", "management.users.title": "Gérer des utilisateurs", "management.stats.users.title": "Nouveaux utilisateurs", diff --git a/frontend/src/locales/he.json b/frontend/src/locales/he.json index 1ee2d1544c..590f53061e 100644 --- a/frontend/src/locales/he.json +++ b/frontend/src/locales/he.json @@ -59,6 +59,7 @@ "header.nav.manage": "ניהול", "header.buttons.logIn": "כניסה", "header.buttons.signUp": "הרשמה", + "header.buttons.createAccount": "", "header.buttons.authorize": "כניסה", "signUp.modal.authorize": "סיימת את הרישום ל־OpenStreetMap?", "signUp.authorize.message": "המיפוי מתחיל כעת! כל שעליך לעשות הוא להיכנס למערכת Tasking Manager עם חשבון ה־OpenStreetMap החדש שיצרת.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "קיצוץ רשת המשימה לאזור העניין (רשות).", "management.projects.create.trim_tasks.description.2": "ניתן להשאיר את המשימות הנוכחיות או לקצץ את שטח המיזם שלך. ביצוע הפעולה הזו עלול לארוך זמן מה.", "management.projects.create.trim_tasks.trim_to_aoi": "קיצוץ המשימות כדי להגדיר את שטח העניין המדויק למיפוי.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} two {} many {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "גודל המשימה הכללי", "management.projects.create.task_sizes.smaller": "קטנה יותר", "management.projects.create.task_sizes.larger": "גדולה יותר", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "מסע פרסום", "projects.formInputs.categories.title": "קטגוריות", "projects.formInputs.organisation.description": "ארגון שמתאם את המיזם, אם בכלל יש כזה. למנהלי הארגון תהיינה הרשאות ניהול למיזם הזה.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "בחירת רישיון", "projects.formInputs.organisation.select": "בחירת ארגון", "projects.formInputs.campaign.select": "בחירת מסעות פרסום", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "אכיפת בחירת משימות אקראית", "projects.formInputs.random_task_selection.mapping": "אכיפת בחירת משימות מיפוי אקראיות", "projects.formInputs.random_task_selection.description": "אם האפשרות מסומנת, על המשתמשים יהיה לערוך משימות באופן אקראי עבור שלב העריכה הראשוני (מנהלי מיזמים ומנהלים כלליים חריגים מהבחינה הזאת).", - "projects.formInputs.imagery": "כתובת צילום האוויר", + "projects.formInputs.imagery": "צילום אוויר", "projects.formInputs.imagery.note": "יש להיצמד לתבנית הזו לכתובות TMS:‏ {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "ציור מצולע", "projects.formInputs.priority_areas.options.rectangle": "ציור ריבוע", @@ -556,6 +560,7 @@ "project.imagery.wmts": "שכבת WMTS מותאמת אישית", "project.imagery.customLayer": "שכבה בהתאמה אישית", "project.imagery.noDefined": "כל מקור זמין", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "מיפוי משימה", "project.selectTask.footer.button.mapSelectedTask": "מיפוי משימה נבחרת", "project.selectTask.footer.button.mapAnotherTask": "מיפוי משימה נוספת", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "אסור לך לגשת לאזור הניהול.", "teamsAndOrgs.management.project.forbidden": "אין לך הרשאה לערוך את המיזם הזה.", "teamsAndOrgs.management.team.forbidden": "אין לך הרשאה לערוך את הקבוצה הזה.", - "loginPage.title": "יש להיכנס או לפתוח חשבון", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "מנהלים", "management.users.title": "ניהול משתמשים", "management.stats.users.title": "משתמשים חדשים", diff --git a/frontend/src/locales/hu.json b/frontend/src/locales/hu.json index fe5fe51162..c0e402a64e 100644 --- a/frontend/src/locales/hu.json +++ b/frontend/src/locales/hu.json @@ -59,6 +59,7 @@ "header.nav.manage": "Kezelés", "header.buttons.logIn": "Bejelentkezés", "header.buttons.signUp": "Feliratkozás", + "header.buttons.createAccount": "", "header.buttons.authorize": "Bejelentkezés", "signUp.modal.authorize": "Befejezte regisztrációját az OpenStreetMapen?", "signUp.authorize.message": "Kezdje meg a térképezést most! Csak jelentkezzék be a Tasking Managerbe az új OpenStreetMap fiókjával.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Igazítsa hozzá a feladatrácsot az érintett területehez (nem kötelező).", "management.projects.create.trim_tasks.description.2": "Megtarthatja a jelenlegi feladatokat vagy hozzáigazíthatja a területet a projekthez. Ez beletelhet némi időbe.", "management.projects.create.trim_tasks.trim_to_aoi": "A térképezéssel érintett terület pontos meghatározásához igazítsa ki a feladatokat.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Általános feladatméret", "management.projects.create.task_sizes.smaller": "Kisebb", "management.projects.create.task_sizes.larger": "Nagyobb", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Kampány", "projects.formInputs.categories.title": "Kategóriák", "projects.formInputs.organisation.description": "A projektet koordináló szervezet, ha van. A szervezet kezelőinek rendszergazdai jogosultságai lesznek a projektben.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "Licenc kijelölése", "projects.formInputs.organisation.select": "Szervezet kijelölése", "projects.formInputs.campaign.select": "Kampányok kijelölése", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Véletlenszerű feladatkijelölés kényszerítése", "projects.formInputs.random_task_selection.mapping": "Véletlenszerű feladatkijelölés kényszerítése térképezésnél", "projects.formInputs.random_task_selection.description": "Ha be van jelölve, a felhasználóknak a kezdeti szerkesztési szakaszban véletlenszerűen kell feladatokat szerkeszteniük (a kezelők és a rendszergazdák mentesülnek ez alól).", - "projects.formInputs.imagery": "Légi felvételek URL-je", + "projects.formInputs.imagery": "Légi felvételek", "projects.formInputs.imagery.note": "TMS URL-je esetében ezt a formátumot kövesse: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Sokszög rajzolása", "projects.formInputs.priority_areas.options.rectangle": "Téglalap rajzolása", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Egyedi WTMS-réteg", "project.imagery.customLayer": "Egyedi réteg", "project.imagery.noDefined": "Bármelyik elérhető forrás", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Feladat térképezése", "project.selectTask.footer.button.mapSelectedTask": "Kijelölt feladat térképezése", "project.selectTask.footer.button.mapAnotherTask": "Másik feladat térképezése", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Nem férhet hozzá a kezelési felülethez.", "teamsAndOrgs.management.project.forbidden": "Nem szerkesztheti ezt a projektet.", "teamsAndOrgs.management.team.forbidden": "Nincs jogosultsága a csoport szerkesztéséhez.", - "loginPage.title": "Bejelentkezés vagy fiók regisztrálása", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Kezelők", "management.users.title": "Felhasználók kezelése", "management.stats.users.title": "Új felhasználók", diff --git a/frontend/src/locales/id.json b/frontend/src/locales/id.json index 4208ca8df0..8a5afed21e 100644 --- a/frontend/src/locales/id.json +++ b/frontend/src/locales/id.json @@ -59,6 +59,7 @@ "header.nav.manage": "Kelola", "header.buttons.logIn": "Masuk", "header.buttons.signUp": "Daftar", + "header.buttons.createAccount": "", "header.buttons.authorize": "Masuk", "signUp.modal.authorize": "Sudahkah Anda menyelesaikan pendaftaran di OpenStreetMap?", "signUp.authorize.message": "Mulailah memetakan sekarang! Cukup login ke Tasking Manager dengan akun OpenStreetMap baru Anda.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Potong grid task sesuai dengan area pilihan Anda (opsional).", "management.projects.create.trim_tasks.description.2": "Anda dapat menyimpan tasks saat ini atau memotong area untuk proyek Anda. Untuk mengeksekusinya, diperlukan waktu beberapa lama.", "management.projects.create.trim_tasks.trim_to_aoi": "Potong task untuk menetapkan area pemetaan sesuai dengan area pilihan Anda.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Ukuran task secara umum", "management.projects.create.task_sizes.smaller": "Lebih kecil", "management.projects.create.task_sizes.larger": "Lebih besar", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Campaign", "projects.formInputs.categories.title": "Kategori", "projects.formInputs.organisation.description": "Organisasi yang mengkoordinir proyek, jika ada. Manager dari organisasi tersebut akan memiliki hak administrasi terhadap proyek.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "Pilih lisensi", "projects.formInputs.organisation.select": "Pilih organisasi", "projects.formInputs.campaign.select": "Pilih campaign", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Terapkan pemilihan task/kotak secara acak", "projects.formInputs.random_task_selection.mapping": "Terapkan pemilihan task/kotak secara acak untuk pemetaan", "projects.formInputs.random_task_selection.description": "Jika dicentang, pengguna harus mengedit tugas secara acak untuk tahap pengeditan awal (pengecualian manajer dan admin).", - "projects.formInputs.imagery": "URL citra satelit", + "projects.formInputs.imagery": "Citra satelit", "projects.formInputs.imagery.note": "Ikuti format berikut ini untuk URL TMS: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Gambar poligon", "projects.formInputs.priority_areas.options.rectangle": "Gambar segi empat", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Layer WMTS kustom", "project.imagery.customLayer": "Layer kustom", "project.imagery.noDefined": "Sumber yang tersedia", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Petakan task", "project.selectTask.footer.button.mapSelectedTask": "Petakan task terpilih", "project.selectTask.footer.button.mapAnotherTask": "Petakan task lain", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Anda tidak diizinkan untuk mengakses area manajemen.", "teamsAndOrgs.management.project.forbidden": "Anda tidak diizinkan untuk mengubah proyek ini.", "teamsAndOrgs.management.team.forbidden": "Anda tidak diizinkan untuk mengubah tim ini.", - "loginPage.title": "Masuk atau daftarkan sebuah akun.", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Manager", "management.users.title": "Kelola pengguna", "management.stats.users.title": "Pengguna baru", diff --git a/frontend/src/locales/it.json b/frontend/src/locales/it.json index 16ae5b0396..ed79652220 100644 --- a/frontend/src/locales/it.json +++ b/frontend/src/locales/it.json @@ -59,6 +59,7 @@ "header.nav.manage": "Gestisci", "header.buttons.logIn": "Accesso", "header.buttons.signUp": "Registrazione", + "header.buttons.createAccount": "", "header.buttons.authorize": "Accesso", "signUp.modal.authorize": "Hai completato la registrazione su OpenStreetMap?", "signUp.authorize.message": "Inizia a mappare ora! Fai il login nel Tasking Manager con il tuo nuovo OpenStreetMap account.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Ritaglia l'area del compito all'area di interesse (opzionale).", "management.projects.create.trim_tasks.description.2": "Puoi mantenere il compito attuale o ritagliare l'area del tuo progetto. Potrebbe essere necessario del tempo per l'esecuzione.", "management.projects.create.trim_tasks.trim_to_aoi": "Ritaglia il compito per definire l'esatta area di interesse per la mappatura.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Dimensione generale del compito", "management.projects.create.task_sizes.smaller": "Più piccolo", "management.projects.create.task_sizes.larger": "Più grande", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Campagna", "projects.formInputs.categories.title": "Categorie", "projects.formInputs.organisation.description": "Organizzazione che coordina il progetto, se esistente. I gestori dell'organizzazione avranno poteri di amministrazione sul progetto.", + "projects.formInputs.imagery.select": "Seleziona immagine aerea", "projects.formInputs.license.select": "Seleziona licenza", "projects.formInputs.organisation.select": "Scegli un'organizzazione", "projects.formInputs.campaign.select": "Seleziona campagne", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Applica selezione casuale di un compito", "projects.formInputs.random_task_selection.mapping": "Obbliga selezione dei task casuale in mappatura", "projects.formInputs.random_task_selection.description": "Se selezionato, gli utenti devono modificare i compiti in modo casuale per la fase iniziale di modifica (manager e amministratori sono esenti).", - "projects.formInputs.imagery": "URL immagine", + "projects.formInputs.imagery": "Foto aeree/satellitari", "projects.formInputs.imagery.note": "Segui questo formato per gli URL TMS: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Disegna poligono", "projects.formInputs.priority_areas.options.rectangle": "Disegna rettangolo", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Livello WMTS personalizzato", "project.imagery.customLayer": "Livello personalizzato", "project.imagery.noDefined": "Qualsiasi fonte disponibile", + "project.imagery.copy": "Copia URL immagine aerea", "project.selectTask.footer.button.mapRandomTask": "Mappa un compito", "project.selectTask.footer.button.mapSelectedTask": "Mappa il compito selezionato", "project.selectTask.footer.button.mapAnotherTask": "Mappa un altro compito", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Non sei autorizzato ad accedere all'area di gestione.", "teamsAndOrgs.management.project.forbidden": "Non sei autorizzato a modificare questo progetto.", "teamsAndOrgs.management.team.forbidden": "Non sei autorizzato a modificare questo gruppo.", - "loginPage.title": "Accedi o registra un account", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Gestori", "management.users.title": "Gestire gli utenti", "management.stats.users.title": "Nuovi utenti", diff --git a/frontend/src/locales/ja.json b/frontend/src/locales/ja.json index 5e78f6a348..26cb3b9a74 100644 --- a/frontend/src/locales/ja.json +++ b/frontend/src/locales/ja.json @@ -59,6 +59,7 @@ "header.nav.manage": "管理", "header.buttons.logIn": "ログイン", "header.buttons.signUp": "登録", + "header.buttons.createAccount": "", "header.buttons.authorize": "ログイン", "signUp.modal.authorize": "OpenStreetMapへの登録は済んでいますか?", "signUp.authorize.message": "マッピングをはじめましょう! あなたのOpenStreetMapアカウントでTasking Managerにログインしてください。", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "タスクグリッドをトリムして Area of interestを作成 (オプション)", "management.projects.create.trim_tasks.description.2": "現在のタスクを続行するか、プロジェクト対象地域の切り取りを行うことができます。切り取り処理には少し時間がかかります。", "management.projects.create.trim_tasks.trim_to_aoi": "タスクを切り取って、マッピング対象のArea of Interestを指定します。", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "通常のタスクのサイズ", "management.projects.create.task_sizes.smaller": "縮小", "management.projects.create.task_sizes.larger": "拡大", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "キャンペーン", "projects.formInputs.categories.title": "カテゴリ", "projects.formInputs.organisation.description": "このプロジェクトの調整役になっている組織名。必ず設定されているわけではありません。組織の管理者は対象となるプロジェクトの管理権限を有しています。", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "ライセンス選択", "projects.formInputs.organisation.select": "組織を選択", "projects.formInputs.campaign.select": "キャンペーン選択", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "ランダムにタスクを選択する", "projects.formInputs.random_task_selection.mapping": "マッピングのタスクをランダムに選択する", "projects.formInputs.random_task_selection.description": "チェックを入れると、ユーザーは最初の編集タスクをランダムで行う必要があります(マネージャと管理者は例外)。", - "projects.formInputs.imagery": "画像のURL", + "projects.formInputs.imagery": "画像", "projects.formInputs.imagery.note": "TMS URLs: {exampleUrl} の書式に従ってください。", "projects.formInputs.priority_areas.options.polygon": "ポリゴンを描く", "projects.formInputs.priority_areas.options.rectangle": "四角形を描く", @@ -556,6 +560,7 @@ "project.imagery.wmts": "カスタム WMTS レイヤー", "project.imagery.customLayer": "カスタムレイヤー", "project.imagery.noDefined": "利用可能なソース", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "タスクのマッピング", "project.selectTask.footer.button.mapSelectedTask": "選択したタスクをマッピング", "project.selectTask.footer.button.mapAnotherTask": "他のタスクをマッピング", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "管理エリアへのアクセスはできません。", "teamsAndOrgs.management.project.forbidden": "プロジェクトへの参加権限がありません。", "teamsAndOrgs.management.team.forbidden": "あなたはこのチームを編集することが許可されていません", - "loginPage.title": "ログインまたはアカウント登録", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "管理者", "management.users.title": "ユーザーの管理", "management.stats.users.title": "新規ユーザ", diff --git a/frontend/src/locales/ko.json b/frontend/src/locales/ko.json index f8c6c46724..e1cb7cbb6a 100644 --- a/frontend/src/locales/ko.json +++ b/frontend/src/locales/ko.json @@ -59,6 +59,7 @@ "header.nav.manage": "관리", "header.buttons.logIn": "로그인", "header.buttons.signUp": "회원가입", + "header.buttons.createAccount": "", "header.buttons.authorize": "로그인", "signUp.modal.authorize": "OpenStreetMap에 가입하셨습니까?", "signUp.authorize.message": "이제 지도를 만들어 봅시다! 여러분의 OpenStreetMap 계정으로 Tasking Manager에 로그인하세요.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "불필요한 영역을 설정합니다(옵션).", "management.projects.create.trim_tasks.description.2": "현재 영역을 그대로 유지할 수도 있고, 불필요한 부분을 잘라낼 수도 있습니다. 이 작업을 수행하는 데는 시간이 걸립니다.", "management.projects.create.trim_tasks.trim_to_aoi": "정확히 필요한 영역을 제외한 나머지 부분을 잘라냅니다.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "단위 작업의 크기 통일", "management.projects.create.task_sizes.smaller": "축소", "management.projects.create.task_sizes.larger": "확대", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "캠페인", "projects.formInputs.categories.title": "카테고리", "projects.formInputs.organisation.description": "프로젝트를 총괄하는 단체입니다. 반드시 존재할 필요는 없습니다. 단체의 관리자는 해당 프로젝트의 관리 권한을 가집니다.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "라이선스 선택", "projects.formInputs.organisation.select": "단체 선택", "projects.formInputs.campaign.select": "캠페인 선택", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "랜덤으로 작업 사각형을 선택하도록 강제", "projects.formInputs.random_task_selection.mapping": "지도 제작 시 랜덤으로 작업 사각형을 선택하도록 강제", "projects.formInputs.random_task_selection.description": "이 옵션을 활성화하면 기여자들은 무작위 작업 사각형을 할당받습니다(관리자와 총책임자는 제외).", - "projects.formInputs.imagery": "이미지 URL", + "projects.formInputs.imagery": "이미지", "projects.formInputs.imagery.note": "TMS URL의 양식은 다음과 같습니다: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "다각형 그리기", "projects.formInputs.priority_areas.options.rectangle": "직사각형 그리기", @@ -556,6 +560,7 @@ "project.imagery.wmts": "사용자 지정 WMTS 레이어", "project.imagery.customLayer": "사용자 지정 레이어", "project.imagery.noDefined": "이용 가능한 모든 자료", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "지도 만들기", "project.selectTask.footer.button.mapSelectedTask": "선택한 구역의 지도 만들기", "project.selectTask.footer.button.mapAnotherTask": "다른 구역의 지도 만들기", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "관리 영역에 접근할 권한이 없습니다.", "teamsAndOrgs.management.project.forbidden": "이 프로젝트를 수정할 권한이 없습니다.", "teamsAndOrgs.management.team.forbidden": "이 팀을 수정할 권한이 없습니다.", - "loginPage.title": "로그인 또는 회원가입", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "관리자", "management.users.title": "사용자 관리", "management.stats.users.title": "신규 사용자", diff --git a/frontend/src/locales/mg.json b/frontend/src/locales/mg.json index bb420d25e6..ce2cf49cfe 100644 --- a/frontend/src/locales/mg.json +++ b/frontend/src/locales/mg.json @@ -59,6 +59,7 @@ "header.nav.manage": "", "header.buttons.logIn": "", "header.buttons.signUp": "", + "header.buttons.createAccount": "", "header.buttons.authorize": "", "signUp.modal.authorize": "", "signUp.authorize.message": "", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "", "management.projects.create.trim_tasks.description.2": "", "management.projects.create.trim_tasks.trim_to_aoi": "", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "", "management.projects.create.task_sizes.smaller": "Kelikely", "management.projects.create.task_sizes.larger": "", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "", "projects.formInputs.categories.title": "", "projects.formInputs.organisation.description": "", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "", "projects.formInputs.campaign.select": "", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "", "projects.formInputs.random_task_selection.mapping": "", "projects.formInputs.random_task_selection.description": "", - "projects.formInputs.imagery": "", + "projects.formInputs.imagery": "Imagerie", "projects.formInputs.imagery.note": "", "projects.formInputs.priority_areas.options.polygon": "Hanao sary faritra", "projects.formInputs.priority_areas.options.rectangle": "Hanao sary efajoro", @@ -556,6 +560,7 @@ "project.imagery.wmts": "", "project.imagery.customLayer": "", "project.imagery.noDefined": "", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "", "project.selectTask.footer.button.mapSelectedTask": "", "project.selectTask.footer.button.mapAnotherTask": "", @@ -901,6 +906,8 @@ "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "", "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "", "management.users.title": "", "management.stats.users.title": "", diff --git a/frontend/src/locales/ml.json b/frontend/src/locales/ml.json index bc5680f8e1..55906f4dba 100644 --- a/frontend/src/locales/ml.json +++ b/frontend/src/locales/ml.json @@ -59,6 +59,7 @@ "header.nav.manage": "", "header.buttons.logIn": "", "header.buttons.signUp": "", + "header.buttons.createAccount": "", "header.buttons.authorize": "", "signUp.modal.authorize": "", "signUp.authorize.message": "", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "", "management.projects.create.trim_tasks.description.2": "", "management.projects.create.trim_tasks.trim_to_aoi": "", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "", "management.projects.create.task_sizes.smaller": "", "management.projects.create.task_sizes.larger": "", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "", "projects.formInputs.categories.title": "", "projects.formInputs.organisation.description": "", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "", "projects.formInputs.campaign.select": "", @@ -556,6 +560,7 @@ "project.imagery.wmts": "", "project.imagery.customLayer": "", "project.imagery.noDefined": "", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "", "project.selectTask.footer.button.mapSelectedTask": "", "project.selectTask.footer.button.mapAnotherTask": "", @@ -901,6 +906,8 @@ "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "", "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "", "management.users.title": "", "management.stats.users.title": "", diff --git a/frontend/src/locales/nl_NL.json b/frontend/src/locales/nl_NL.json index a16af4627f..c59a101e59 100644 --- a/frontend/src/locales/nl_NL.json +++ b/frontend/src/locales/nl_NL.json @@ -59,6 +59,7 @@ "header.nav.manage": "Beheren", "header.buttons.logIn": "Inloggen", "header.buttons.signUp": "Aanmelden", + "header.buttons.createAccount": "", "header.buttons.authorize": "Inloggen", "signUp.modal.authorize": "Bent u klaar met de registratie op OpenStreetMap?", "signUp.authorize.message": "Begin nu met in kaart brengen! Log in de Tasking Manager in met uw nieuwe OpenStreetMap account.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Verklein het raster voor de taak tot het gebied van interesse (optioneel).", "management.projects.create.trim_tasks.description.2": "U kunt de huidige taken behouden of het gebied voor uw project verkleinen. Uitvoeren hiervan kan enige tijd vergen.", "management.projects.create.trim_tasks.trim_to_aoi": "Verklein de taken om het exacte gebied van interesse te definiëren voor in kaart brengen. (optioneel).", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Grootte algemene taak:", "management.projects.create.task_sizes.smaller": "Kleiner", "management.projects.create.task_sizes.larger": "Groter", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Campagne", "projects.formInputs.categories.title": "Categorieën", "projects.formInputs.organisation.description": "Organisatie die het project coördineert, als er een is. De beheerders van die organisatie zullen beheersrechten voor het project hebben.", + "projects.formInputs.imagery.select": "Luchtfoto's selecteren", "projects.formInputs.license.select": "Licentie selecteren", "projects.formInputs.organisation.select": "Organisatie selecteren ", "projects.formInputs.campaign.select": "Campagne selecteren", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Willekeurige taak selecteren forceren", "projects.formInputs.random_task_selection.mapping": "Taak willekeurig selecteren forceren bij in kaart brengen", "projects.formInputs.random_task_selection.description": "Indien geselecteerd moeten gebruikers willekeurig taken bewerken in het initiële stadium van bewerken (beheerders en admins zijn uitgezonderd).", - "projects.formInputs.imagery": "URL afbeeldingen", + "projects.formInputs.imagery": "Luchtfoto's en remote sensing beelden", "projects.formInputs.imagery.note": "Volg deze indeling voor URL's van TMS: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Polygoon tekenen", "projects.formInputs.priority_areas.options.rectangle": "Rechthoek tekenen", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Aangepaste WMTS-laag", "project.imagery.customLayer": "Aangepaste laag", "project.imagery.noDefined": "Elke beschikbare bron", + "project.imagery.copy": "URL afbeeldingen kopiëren", "project.selectTask.footer.button.mapRandomTask": "Een taak in kaart brengen", "project.selectTask.footer.button.mapSelectedTask": "Geselecteerde taak in kaart brengen", "project.selectTask.footer.button.mapAnotherTask": "Een andere taak in kaart brengen", @@ -709,7 +714,7 @@ "management.organisations.type": "Type", "management.organisations.publicUrl": "Publieke URL", "management.organisations.publicUrl.copy": "Publieke URL kopiëren", - "management.organisations.tier.select": "Niveau selecteren", + "management.organisations.tier.select": "Fase selecteren", "management.organisations.type.select": "Type selecteren ", "management.organisations.type.free": "Vrij", "management.organisations.type.discounted": "Niet geteld", @@ -726,7 +731,7 @@ "management.organisations.stats.actions_needed": "Benodigde acties", "management.organisations.stats.completed_actions": "Voltooide acties", "management.organisations.stats.actions_needed.help": "Actie betekent een bewerking voor in kaart brengen of valideren. Omdat elke taak in kaart gebracht en gevalideerd moet worden, is dat het aantal benodigde acties om alle gepubliceerde projecten van die organisatie te voltooien.", - "management.organisations.stats.tier.subscribed": "Geabonneerd niveau", + "management.organisations.stats.tier.subscribed": "Geabonneerde fase", "management.organisations.stats.level.tooltip": "{n} van {total} ({percent}%) voltooid om te verplaatsen naar niveau {nextLevel}", "management.organisations.stats.tier.tooltip": "{n} van {total} ({percent}%) voltooid om te verplaatsen naar fase {nextTier}", "management.organisations.stats.level.description": "{org} is een organisatie niveau {level}.", @@ -734,7 +739,7 @@ "management.organisations.stats.tier.estimation": "Geschatte fase aan het einde van {year}", "management.organisations.stats.cost.estimation": "Geschatte kosten aan het einde van {year}", "management.organisations.stats.next_level.actions": "Acties om het niveau {n} te bereiken", - "management.organisations.stats.tier.actions_remaining": "", + "management.organisations.stats.tier.actions_remaining": "Resterende acties voor de fase {name}", "management.organisations.tier.free": "Vrij", "management.organisations.tier.low": "Laag", "management.organisations.tier.medium": "Normaal", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "U heeft geen rechten voor het beheersgebied.", "teamsAndOrgs.management.project.forbidden": "U heeft geen rechten om dit project te bewerken.", "teamsAndOrgs.management.team.forbidden": "U heeft geen rechten om dit team te bewerken.", - "loginPage.title": "Inloggen of een account registreren", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Beheerders", "management.users.title": "Gebruikers beheren", "management.stats.users.title": "Nieuwe gebruikers", diff --git a/frontend/src/locales/pt.json b/frontend/src/locales/pt.json index 5ca74ac7ff..a85b4a76b4 100644 --- a/frontend/src/locales/pt.json +++ b/frontend/src/locales/pt.json @@ -33,7 +33,7 @@ "mytasks.unlock": "desbloquear {time}", "mytasks.tasks.title": "Tarefa #{task} · Projeto #{project}", "mytasks.tasks.button.retry": "Tentar novamente", - "mytasks.tasks.comments.number": "{number, plural, one {} other {}}", + "mytasks.tasks.comments.number": "{number, plural, one {# comentário} other {# comentários}}", "deleteModal.status.processing": "A processar", "deleteModal.status.success": "{type} eliminado com sucesso.", "deleteModal.status.failure.projects": "Ocorreu um erro ao tentar eliminar este projeto.", @@ -59,6 +59,7 @@ "header.nav.manage": "Gerir", "header.buttons.logIn": "Iniciar sessão", "header.buttons.signUp": "Registar", + "header.buttons.createAccount": "Criar uma conta", "header.buttons.authorize": "Entrar", "signUp.modal.authorize": "Concluíste o registo no OpenStreetMap?", "signUp.authorize.message": "Começa a mapear agora! Basta iniciares sessão no Gestor de Tarefas com a tua nova conta OpenStreetMap.", @@ -195,7 +196,7 @@ "project.card.edit_project.button": "Editar", "project.card.project_page.button": "Página do Projeto", "project.card.project_tasks.button": "Tarefas", - "management.projects.create.title": "", + "management.projects.create.title": "Criar novo projeto", "management.projects.clone.message": "O novo projeto será um clone do projeto #{id} ({name}).", "management.projects.create.clone": "Clonar", "management.projects.create.area_size": "Tamanho da área: {area} km{sq}", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Ajustar a grelha de tarefas à área de interesse (opcional).", "management.projects.create.trim_tasks.description.2": "Podes manter as tarefas atuais ou ajustar a área para o teu projeto. Isto pode levar algum tempo a ser executado.", "management.projects.create.trim_tasks.trim_to_aoi": "Ajusta as tarefas para definir a Área de Interesse exata para mapeamento.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "Descartar", "management.projects.create.task_sizes.description": "Tamanho geral da tarefa", "management.projects.create.task_sizes.smaller": "Menor", "management.projects.create.task_sizes.larger": "Maior", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Campanha", "projects.formInputs.categories.title": "Categorias", "projects.formInputs.organisation.description": "Organização que está a coordenar o projeto, se houver algum. Os gestores da organização terão direitos administrativos sobre o projeto.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "Selecionar licença", "projects.formInputs.organisation.select": "Selecionar organização", "projects.formInputs.campaign.select": "Selecionar campanhas", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Impor seleção aleatória de tarefa", "projects.formInputs.random_task_selection.mapping": "Impor seleção aleatória de tarefas no mapeamento", "projects.formInputs.random_task_selection.description": "Se marcada, os utilizadores devem editar tarefas aleatoriamente na fase inicial de edição (os gestores e os administradores estão isentos).", - "projects.formInputs.imagery": "URL de imagens aéreas", + "projects.formInputs.imagery": "Imagem aérea", "projects.formInputs.imagery.note": "Usar este formato para URL TMS: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Desenhar polígono", "projects.formInputs.priority_areas.options.rectangle": "Desenhar retângulo", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Camada WMTS personalizada", "project.imagery.customLayer": "Camada personalizada", "project.imagery.noDefined": "Qualquer fonte disponível", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Mapear uma tarefa", "project.selectTask.footer.button.mapSelectedTask": "Mapear tarefa selecionada", "project.selectTask.footer.button.mapAnotherTask": "Mapear outra tarefa", @@ -699,14 +704,14 @@ "management.filter.buttons.myOrganisations": "As Minhas Organizações", "management.filter.buttons.all": "Todas", "management.myTeams": "As minhas equipas", - "management.buttons.new": "", + "management.buttons.new": "Novo", "management.buttons.delete": "Eliminar", "management.buttons.accept": "Aceitar", "management.buttons.reject": "Rejeitar", "management.links.viewAll": "Ver tudo", "management.organisation": "Organização", "management.organisations": "Organizações", - "management.organisations.type": "", + "management.organisations.type": "Tipo", "management.organisations.publicUrl": "", "management.organisations.publicUrl.copy": "", "management.organisations.tier.select": "", @@ -715,7 +720,7 @@ "management.organisations.type.discounted": "", "management.organisations.type.defaultFee": "", "management.organisations.list.empty": "", - "management.organisations.stats.retry": "", + "management.organisations.stats.retry": "Tente novamente", "management.organisations.stats.error": "", "management.organisations.stats.error.start_date": "", "management.organisations.stats.error.date_range": "", @@ -735,11 +740,11 @@ "management.organisations.stats.cost.estimation": "", "management.organisations.stats.next_level.actions": "", "management.organisations.stats.tier.actions_remaining": "", - "management.organisations.tier.free": "", + "management.organisations.tier.free": "Grátis", "management.organisations.tier.low": "Baixa", "management.organisations.tier.medium": "Média", "management.organisations.tier.high": "Alta", - "management.organisations.tier.very_high": "", + "management.organisations.tier.very_high": "Muito alta", "management.organisations.stats.level.next": "", "management.organisations.stats.level.top": "", "management.titles.organisation_information": "Informações da organização", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Não tens permissão para aceder à área de gestão.", "teamsAndOrgs.management.project.forbidden": "Não tens permissão para editar este projeto.", "teamsAndOrgs.management.team.forbidden": "Não tens permissão para editar esta equipa.", - "loginPage.title": "Iniciar sessão ou registar uma conta", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Gestores", "management.users.title": "Gerir utilizadores", "management.stats.users.title": "Novos utilizadores", diff --git a/frontend/src/locales/pt_BR.json b/frontend/src/locales/pt_BR.json index 015a5577bf..b08853dbdb 100644 --- a/frontend/src/locales/pt_BR.json +++ b/frontend/src/locales/pt_BR.json @@ -59,6 +59,7 @@ "header.nav.manage": "Administração", "header.buttons.logIn": "Entrar", "header.buttons.signUp": "Cadastrar", + "header.buttons.createAccount": "Criar uma conta", "header.buttons.authorize": "Entrar", "signUp.modal.authorize": "Você finalizou o seu cadastro no OpenStreetMap?", "signUp.authorize.message": " Comece a mapear agora! Basta fazer login no Tasking Manager com sua nova conta OpenStreetMap.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Reduza a grade de tarefas para a área de interesse (opcional).", "management.projects.create.trim_tasks.description.2": "Você pode manter as tarefas atuais ou cortar a área para o seu projeto. Isso pode levar algum tempo para ser executado.", "management.projects.create.trim_tasks.trim_to_aoi": "Corte as tarefas para definir a Área de Interesse exata para mapeamento.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {Há uma tarefa menor que {area} m². Gostaria de descartá-la?} other {Existem # tarefas menores que {area} m². Gostaria de descartá-las?}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "Descartar", "management.projects.create.task_sizes.description": "Tamanho geral da tarefa", "management.projects.create.task_sizes.smaller": "Menor", "management.projects.create.task_sizes.larger": "Maior", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Campanha", "projects.formInputs.categories.title": "Categorias", "projects.formInputs.organisation.description": "Organização que está coordenando o projeto, se houver algum. Os gerentes dessa organização terão direitos administrativos sobre o projeto.", + "projects.formInputs.imagery.select": "Selecionar imagem", "projects.formInputs.license.select": "Selecionar licença", "projects.formInputs.organisation.select": "Selecionar organização", "projects.formInputs.campaign.select": "Selecionar campanhas", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Impor seleção aleatória de tarefa", "projects.formInputs.random_task_selection.mapping": "Impor seleção aleatória de tarefas no mapeamento", "projects.formInputs.random_task_selection.description": "Se conferidos, os usuários devem editar tarefas aleatoriamente para o estágio inicial de edição (gerentes e administradores estão isentos).", - "projects.formInputs.imagery": "URL das imagens", + "projects.formInputs.imagery": "Imagens aéreas", "projects.formInputs.imagery.note": "Siga este formato para URLs TMS: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Desenhar polígono", "projects.formInputs.priority_areas.options.rectangle": "Desenhar retângulo", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Camada WMTS personalizada", "project.imagery.customLayer": "Camada personalizada", "project.imagery.noDefined": "Qualquer fonte disponível", + "project.imagery.copy": "Copiar URL das imagens", "project.selectTask.footer.button.mapRandomTask": "Mapear uma tarefa", "project.selectTask.footer.button.mapSelectedTask": "Mapear a tarefa selecionada", "project.selectTask.footer.button.mapAnotherTask": "Mapear outra tarefa", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Você não tem permissão para acessar a área de gerenciamento.", "teamsAndOrgs.management.project.forbidden": "Você não tem permissão para editar este projeto.", "teamsAndOrgs.management.team.forbidden": "Você não tem permissão para editar esta equipe.", - "loginPage.title": "Entrar ou registrar uma conta", + "loginPage.title": "Faça login no {org} Tasking Manager", + "loginPage.text.login": "Você pode fazer login com uma conta do OpenStreetMap.", + "loginPage.text.create_account": "Ou crie uma nova para começar a mapear.", "management.managers": "Gerentes", "management.users.title": "Gerenciar usuários", "management.stats.users.title": "Novos usuários", diff --git a/frontend/src/locales/sv.json b/frontend/src/locales/sv.json index 8412283582..ac1de72ae5 100644 --- a/frontend/src/locales/sv.json +++ b/frontend/src/locales/sv.json @@ -59,6 +59,7 @@ "header.nav.manage": "Hantera", "header.buttons.logIn": "Logga in", "header.buttons.signUp": "Registrera dig", + "header.buttons.createAccount": "", "header.buttons.authorize": "Logga in", "signUp.modal.authorize": "Har du avslutat registreringen på OpenStreetMap?", "signUp.authorize.message": "Börja kartlägga nu! Logga bara in på Tasking Manager med ditt nya OpenStreetMap-konto.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Trimma uppgifternas rutnät till området (valfritt).", "management.projects.create.trim_tasks.description.2": "Du kan behålla aktuella uppgifter eller trimma området för ditt projekt. Det kan ta lite tid att utföra.", "management.projects.create.trim_tasks.trim_to_aoi": "Trimma uppgifterna för att definiera det exakta området för kartläggning.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Allmän uppgift storlek", "management.projects.create.task_sizes.smaller": "Mindre", "management.projects.create.task_sizes.larger": "Större", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Kampanj", "projects.formInputs.categories.title": "Kategorier", "projects.formInputs.organisation.description": "Organisation som samordnar projektet, om det finns någon. Organisationens chefer kommer att ha administrationsrättigheter över projektet.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "Välj organisation", "projects.formInputs.campaign.select": "", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "", "projects.formInputs.random_task_selection.mapping": "", "projects.formInputs.random_task_selection.description": "", - "projects.formInputs.imagery": "Bilduppsättning URL", + "projects.formInputs.imagery": "Bilduppsättning", "projects.formInputs.imagery.note": "", "projects.formInputs.priority_areas.options.polygon": "Rita polygon", "projects.formInputs.priority_areas.options.rectangle": "Rita rektangel", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Anpassat WMTS-lager", "project.imagery.customLayer": "Anpassat lager", "project.imagery.noDefined": "Eventuell tillgänglig källa", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Kartera en uppgift", "project.selectTask.footer.button.mapSelectedTask": "Kartera vald uppgift", "project.selectTask.footer.button.mapAnotherTask": "Kartera en annan uppgift", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "", "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "Du har inte behörighet att redigera detta team.", - "loginPage.title": "Logga in eller registrera ett konto", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Hanterare", "management.users.title": "Hantera användare", "management.stats.users.title": "", diff --git a/frontend/src/locales/sw.json b/frontend/src/locales/sw.json index 43a5c7c78c..0e4be94638 100644 --- a/frontend/src/locales/sw.json +++ b/frontend/src/locales/sw.json @@ -59,6 +59,7 @@ "header.nav.manage": "Simamia", "header.buttons.logIn": "Ingia", "header.buttons.signUp": "Jisajili", + "header.buttons.createAccount": "", "header.buttons.authorize": "Ingia", "signUp.modal.authorize": "", "signUp.authorize.message": "", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Punguza kazi hadi kwenye eneo unalotaka (si lazima)", "management.projects.create.trim_tasks.description.2": "Unaweza kuzihifadhi hizi kazi au kupunguza eneo la mradi wako. Hii yaweza kuchukua muda kufanikisha.", "management.projects.create.trim_tasks.trim_to_aoi": "Punguza kidogo kuonesha eneo husika la kufanyia kazi", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Ukubwa wa kazi kiujumla", "management.projects.create.task_sizes.smaller": "Ndogo", "management.projects.create.task_sizes.larger": "Kubwa", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Kampeni", "projects.formInputs.categories.title": "Jamii", "projects.formInputs.organisation.description": "Shirika ambalo linaratibu mradi, ikiwa kuna lolote. Wasimamizi wa shirika hilo watakuwa na haki za usimamizi juu ya mradi huo.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "Chagua shirika", "projects.formInputs.campaign.select": "", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Fanya iwe ya kuchagua bila mpangilio", "projects.formInputs.random_task_selection.mapping": "Fanya iwe ya kuchagua bila mpangilio wakati wa kuchora", "projects.formInputs.random_task_selection.description": "", - "projects.formInputs.imagery": "Picha URL", + "projects.formInputs.imagery": "Picha", "projects.formInputs.imagery.note": "Fuata huu muundo kwa ajili ya TMS URLs: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Chora umbo", "projects.formInputs.priority_areas.options.rectangle": "Chora umbo la mstatili", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Safu ya WMTS ya Kawaida", "project.imagery.customLayer": "Safu ya Kawaida", "project.imagery.noDefined": "Chanzo chochote kilichopo", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": " Chora ramani ya kazi", "project.selectTask.footer.button.mapSelectedTask": "Chora kazi iliyochaguliwa", "project.selectTask.footer.button.mapAnotherTask": "Chora kazi nyingine", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Hauruhusiwi kuingia eneo la usimamizi.", "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "", - "loginPage.title": "Ingia au sajili akaunti", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Mameneja", "management.users.title": "Simamia watumiaji", "management.stats.users.title": "", diff --git a/frontend/src/locales/tl.json b/frontend/src/locales/tl.json index bc5680f8e1..55906f4dba 100644 --- a/frontend/src/locales/tl.json +++ b/frontend/src/locales/tl.json @@ -59,6 +59,7 @@ "header.nav.manage": "", "header.buttons.logIn": "", "header.buttons.signUp": "", + "header.buttons.createAccount": "", "header.buttons.authorize": "", "signUp.modal.authorize": "", "signUp.authorize.message": "", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "", "management.projects.create.trim_tasks.description.2": "", "management.projects.create.trim_tasks.trim_to_aoi": "", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "", "management.projects.create.task_sizes.smaller": "", "management.projects.create.task_sizes.larger": "", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "", "projects.formInputs.categories.title": "", "projects.formInputs.organisation.description": "", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "", "projects.formInputs.campaign.select": "", @@ -556,6 +560,7 @@ "project.imagery.wmts": "", "project.imagery.customLayer": "", "project.imagery.noDefined": "", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "", "project.selectTask.footer.button.mapSelectedTask": "", "project.selectTask.footer.button.mapAnotherTask": "", @@ -901,6 +906,8 @@ "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "", "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "", "management.users.title": "", "management.stats.users.title": "", diff --git a/frontend/src/locales/tr.json b/frontend/src/locales/tr.json index 56235ba1e4..7286d738c2 100644 --- a/frontend/src/locales/tr.json +++ b/frontend/src/locales/tr.json @@ -59,6 +59,7 @@ "header.nav.manage": "Yönet", "header.buttons.logIn": "Oturum aç", "header.buttons.signUp": "Kaydol", + "header.buttons.createAccount": "", "header.buttons.authorize": "Oturum aç", "signUp.modal.authorize": "OpenStreetMap kaydınızı bitirdiniz mi?", "signUp.authorize.message": "Haritalamaya şimdi başlayın! Yeni OpenStreetMap hesabınızla Görev Yöneticisi'nde oturum açmanız yeterli.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Görevleri proje alanına göre kırp (isteğe bağlı).", "management.projects.create.trim_tasks.description.2": "Geçerli görevleri koruyabilir veya projeniz alanı dışında kalanları kırpabilirsiniz. Bunun gerçekleştirilmesi biraz zaman alabilir.", "management.projects.create.trim_tasks.trim_to_aoi": "İlgi alanının dışında kalan görevleri kırpın.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Genel görev boyutu", "management.projects.create.task_sizes.smaller": "Daha küçük", "management.projects.create.task_sizes.larger": "Daha büyük", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Kampanya", "projects.formInputs.categories.title": "Kategoriler", "projects.formInputs.organisation.description": "Projeyi koordine eden bir kuruluş varsa, bu kuruluşun yöneticilerinin proje üzerinde yönetim hakları olacaktır.", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "Lisans seç", "projects.formInputs.organisation.select": "Kuruluş seçiniz", "projects.formInputs.campaign.select": "Kampanyaları seç", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Rastgele görev seçimini zorunlu kıl", "projects.formInputs.random_task_selection.mapping": "Haritalama için rastgele görev seçimini zorunlu kıl", "projects.formInputs.random_task_selection.description": "Seçilmişse, kullanıcılar ilk düzenleme aşaması için görevleri rastgele almalıdırlar (proje yöneticileri ve yöneticiler hariç).", - "projects.formInputs.imagery": "Uydu görüntüsü URL", + "projects.formInputs.imagery": "Görüntü", "projects.formInputs.imagery.note": "TMS URL'leri için şu biçimi uygulayın: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Alan çiz", "projects.formInputs.priority_areas.options.rectangle": "Dikdörtgen çiz", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Özel WMTS Katmanı", "project.imagery.customLayer": "Özel Katman", "project.imagery.noDefined": "Erişime açık herhangi bir kaynak", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "Bir görev haritala", "project.selectTask.footer.button.mapSelectedTask": "Seçili görevi haritala", "project.selectTask.footer.button.mapAnotherTask": "Başka görev haritala", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "Yönetici alanına erişim izniniz yok.", "teamsAndOrgs.management.project.forbidden": "Bu projeyi düzenleme yetkiniz bulunmamaktadır.", "teamsAndOrgs.management.team.forbidden": "", - "loginPage.title": "Giriş yapın ya da kayıt olun", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Yöneticiler", "management.users.title": "Kullanıcıları yönet", "management.stats.users.title": "", diff --git a/frontend/src/locales/uk.json b/frontend/src/locales/uk.json index a39f147d3a..620ad60cc5 100644 --- a/frontend/src/locales/uk.json +++ b/frontend/src/locales/uk.json @@ -59,6 +59,7 @@ "header.nav.manage": "Керувати", "header.buttons.logIn": "Увійти", "header.buttons.signUp": "Зареєструватись", + "header.buttons.createAccount": "", "header.buttons.authorize": "Увійти", "signUp.modal.authorize": "Чи ви закінчили процес реєстрації в OpenStreetMap?", "signUp.authorize.message": "Розпочніть мапити зараз! Увійдіть в Менеджер завдань використовуючи ваш новостворений обліковий запис OpenStreetMap.", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "Обрізка сітки завдань по контуру території (необов’язково).", "management.projects.create.trim_tasks.description.2": "Ви можете залишити поточну сітку або обрізати її по контуру проєкту. Це триватиме певний час.", "management.projects.create.trim_tasks.trim_to_aoi": "Обрізка завдань допомагає визначити точну територію для мапінгу.", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, one {} few {} many {} other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "Загальні розміри завдання", "management.projects.create.task_sizes.smaller": "Менше", "management.projects.create.task_sizes.larger": "Більше", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "Кампанія", "projects.formInputs.categories.title": "Категорії", "projects.formInputs.organisation.description": "Організація, що координує виконання проєкту, за наявності. Менеджери організації матимуть права адміністраторів цього проєкту.", + "projects.formInputs.imagery.select": "Оберіть знімки", "projects.formInputs.license.select": "Оберіть ліцензію", "projects.formInputs.organisation.select": "Оберіть організацію", "projects.formInputs.campaign.select": "Оберіть кампанії", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "Тільки випадкове розподілення завдань", "projects.formInputs.random_task_selection.mapping": "Тільки випадкове розподілення завдань для мапінгу", "projects.formInputs.random_task_selection.description": "У разі використання цієї функції, учасникам на початковому етапі будуть назначатись завдання у випадковому порядку (окрім менеджерів та адміністраторів).", - "projects.formInputs.imagery": "URL фону", + "projects.formInputs.imagery": "Фонове зображення", "projects.formInputs.imagery.note": "Використовуйте цей формат для TMS URL: {exampleUrl}", "projects.formInputs.priority_areas.options.polygon": "Накреслити полігон", "projects.formInputs.priority_areas.options.rectangle": "Накреслити прямокутник", @@ -556,6 +560,7 @@ "project.imagery.wmts": "Власний шар WMTS", "project.imagery.customLayer": "Власний шар", "project.imagery.noDefined": "Будь-які наявні джерела", + "project.imagery.copy": "Скопіювати посилання", "project.selectTask.footer.button.mapRandomTask": "Мапити", "project.selectTask.footer.button.mapSelectedTask": "Мапити виділене завдання", "project.selectTask.footer.button.mapAnotherTask": "Мапити інше завдання", @@ -734,7 +739,7 @@ "management.organisations.stats.tier.estimation": "Прогнозований рівень до кінця {year} року", "management.organisations.stats.cost.estimation": "Орієнтовна вартість до кінця {year} року", "management.organisations.stats.next_level.actions": "Дій залишилось до рівня {n}", - "management.organisations.stats.tier.actions_remaining": "", + "management.organisations.stats.tier.actions_remaining": "Дій залишилось на рівні {name} ", "management.organisations.tier.free": "Вільно", "management.organisations.tier.low": "Неважливий", "management.organisations.tier.medium": "Середній", @@ -900,7 +905,9 @@ "management.forbiddenAccess.title": "У вас немає дозволу на керування.", "teamsAndOrgs.management.project.forbidden": "У вас немає дозволу на редагування цього проєкту.", "teamsAndOrgs.management.team.forbidden": "У вас немає дозволу на редагування цієї команди.", - "loginPage.title": "Увійдіть або зареєструйте обліковий запис", + "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "Менеджери", "management.users.title": "Керування учасниками", "management.stats.users.title": "Нові учасники", diff --git a/frontend/src/locales/zh_TW.json b/frontend/src/locales/zh_TW.json index 5f8e5e3cc5..02580b4827 100644 --- a/frontend/src/locales/zh_TW.json +++ b/frontend/src/locales/zh_TW.json @@ -59,6 +59,7 @@ "header.nav.manage": "管理", "header.buttons.logIn": "登入", "header.buttons.signUp": "註冊", + "header.buttons.createAccount": "", "header.buttons.authorize": "登入", "signUp.modal.authorize": "你完成註冊開放街圖程序了嗎?", "signUp.authorize.message": "現在就開始畫地圖吧!只要用新的開放街圖帳號登入任務分配管理器就可以了。", @@ -215,6 +216,8 @@ "management.projects.create.trim_tasks.description.1": "", "management.projects.create.trim_tasks.description.2": "", "management.projects.create.trim_tasks.trim_to_aoi": "", + "management.projects.create.trim_tasks.tiny_tasks": "{number, plural, other {}}", + "management.projects.create.trim_tasks.tiny_tasks.discard": "", "management.projects.create.task_sizes.description": "", "management.projects.create.task_sizes.smaller": "", "management.projects.create.task_sizes.larger": "", @@ -317,6 +320,7 @@ "projects.formInputs.campaign.title": "活動", "projects.formInputs.categories.title": "", "projects.formInputs.organisation.description": "", + "projects.formInputs.imagery.select": "", "projects.formInputs.license.select": "", "projects.formInputs.organisation.select": "選擇組織", "projects.formInputs.campaign.select": "", @@ -388,7 +392,7 @@ "projects.formInputs.random_task_selection": "", "projects.formInputs.random_task_selection.mapping": "", "projects.formInputs.random_task_selection.description": "", - "projects.formInputs.imagery": "", + "projects.formInputs.imagery": "影像", "projects.formInputs.imagery.note": "", "projects.formInputs.priority_areas.options.polygon": "", "projects.formInputs.priority_areas.options.rectangle": "", @@ -556,6 +560,7 @@ "project.imagery.wmts": "", "project.imagery.customLayer": "", "project.imagery.noDefined": "", + "project.imagery.copy": "", "project.selectTask.footer.button.mapRandomTask": "", "project.selectTask.footer.button.mapSelectedTask": "", "project.selectTask.footer.button.mapAnotherTask": "", @@ -901,6 +906,8 @@ "teamsAndOrgs.management.project.forbidden": "", "teamsAndOrgs.management.team.forbidden": "", "loginPage.title": "", + "loginPage.text.login": "", + "loginPage.text.create_account": "", "management.managers": "", "management.users.title": "", "management.stats.users.title": "新使用者", From 16e7cd3f08f8922a2d634d1bab26084cbb7d03fa Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Tue, 30 Mar 2021 17:35:42 -0300 Subject: [PATCH 23/24] fix error message on useAsync tests --- frontend/src/hooks/tests/UseAsync.test.js | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/frontend/src/hooks/tests/UseAsync.test.js b/frontend/src/hooks/tests/UseAsync.test.js index ee0a2164eb..a212c9bfa3 100644 --- a/frontend/src/hooks/tests/UseAsync.test.js +++ b/frontend/src/hooks/tests/UseAsync.test.js @@ -1,4 +1,4 @@ -import { renderHook } from '@testing-library/react-hooks'; +import { renderHook, act } from '@testing-library/react-hooks'; import { useAsync } from '../UseAsync'; @@ -10,13 +10,12 @@ describe('useAsync', () => { mockFn(); resolve(); }); - const { result, waitForNextUpdate } = renderHook(() => useAsync(testFn)); + const { result } = renderHook(() => useAsync(testFn)); expect(result.current.status).toBe('idle'); - result.current.execute(); + await act(async () => await result.current.execute()); expect(mockFn).toHaveBeenCalled(); - expect(result.current.status).toBe('pending'); - await waitForNextUpdate(); expect(result.current.status).toBe('success'); + expect(result.current.error).toBeNull(); }); it('with unsuccessful result', async () => { const mockFn = jest.fn(); @@ -25,12 +24,11 @@ describe('useAsync', () => { mockFn(); reject(); }); - const { result, waitForNextUpdate } = renderHook(() => useAsync(testFn)); + const { result } = renderHook(() => useAsync(testFn)); expect(result.current.status).toBe('idle'); - result.current.execute(); + await act(async () => await result.current.execute()); expect(mockFn).toHaveBeenCalled(); - expect(result.current.status).toBe('pending'); - await waitForNextUpdate(); expect(result.current.status).toBe('error'); + expect(result.current.error).not.toBeNull(); }); }); From f13c709bd43ee22e70e6a701723cefe4a6c9c1b4 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Thu, 25 Mar 2021 15:54:31 -0300 Subject: [PATCH 24/24] Load imagery on JOSM using its id instead of url --- frontend/src/utils/openEditor.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/frontend/src/utils/openEditor.js b/frontend/src/utils/openEditor.js index d9b2d3194e..5c8aa7a599 100644 --- a/frontend/src/utils/openEditor.js +++ b/frontend/src/utils/openEditor.js @@ -149,17 +149,21 @@ export function getImageryInfo(url) { } function loadImageryonJosm(project) { - if (project.imagery && project.imagery.includes('http')) { - const [type, minZoom, maxZoom] = getImageryInfo(project.imagery); - const imageryParams = { - title: project.imagery, - type: type, - }; - if (minZoom) imageryParams.min_zoom = minZoom; - if (maxZoom) imageryParams.max_zoom = maxZoom; - imageryParams.url = project.imagery.substr(project.imagery.indexOf('http')); - - return callJosmRemoteControl(formatJosmUrl('imagery', imageryParams)); + if (project.imagery) { + if (project.imagery.includes('http')) { + const [type, minZoom, maxZoom] = getImageryInfo(project.imagery); + const imageryParams = { + title: project.imagery, + type: type, + }; + if (minZoom) imageryParams.min_zoom = minZoom; + if (maxZoom) imageryParams.max_zoom = maxZoom; + imageryParams.url = project.imagery.substr(project.imagery.indexOf('http')); + + return callJosmRemoteControl(formatJosmUrl('imagery', imageryParams)); + } else { + return callJosmRemoteControl(formatJosmUrl('imagery', { id: project.imagery })); + } } }