From 237828e4edc4ceac29061449d235081d497554af Mon Sep 17 00:00:00 2001 From: zomars Date: Wed, 19 Oct 2022 13:28:54 -0600 Subject: [PATCH 1/9] Upgrades zod --- apps/web/package.json | 2 +- packages/app-store/slackmessaging/package.json | 2 +- packages/app-store/stripepayment/package.json | 2 +- packages/features/ee/package.json | 2 +- packages/prisma/package.json | 2 +- packages/trpc/package.json | 2 +- yarn.lock | 7 +------ 7 files changed, 7 insertions(+), 12 deletions(-) diff --git a/apps/web/package.json b/apps/web/package.json index 0e2c39a1e7..529b356adf 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -120,7 +120,7 @@ "tailwindcss-radix": "^2.6.0", "uuid": "^8.3.2", "web3": "^1.7.5", - "zod": "^3.18.0" + "zod": "^3.19.1" }, "devDependencies": { "@babel/core": "^7.18.10", diff --git a/packages/app-store/slackmessaging/package.json b/packages/app-store/slackmessaging/package.json index de148aca60..cca9c9bf77 100644 --- a/packages/app-store/slackmessaging/package.json +++ b/packages/app-store/slackmessaging/package.json @@ -9,7 +9,7 @@ "@calcom/prisma": "*", "@slack/web-api": "^6.7.2", "slack-block-builder": "^2.6.0", - "zod": "^3.18.0" + "zod": "^3.19.1" }, "devDependencies": { "@calcom/types": "*" diff --git a/packages/app-store/stripepayment/package.json b/packages/app-store/stripepayment/package.json index a4c074bb40..0c790cc606 100644 --- a/packages/app-store/stripepayment/package.json +++ b/packages/app-store/stripepayment/package.json @@ -21,7 +21,7 @@ "@stripe/stripe-js": "^1.35.0", "stripe": "^9.16.0", "uuid": "^8.3.2", - "zod": "^3.18.0" + "zod": "^3.19.1" }, "devDependencies": { "@calcom/types": "*", diff --git a/packages/features/ee/package.json b/packages/features/ee/package.json index a0522b5be8..e45b358686 100644 --- a/packages/features/ee/package.json +++ b/packages/features/ee/package.json @@ -13,7 +13,7 @@ "@sendgrid/client": "^7.7.0", "@sendgrid/mail": "^7.6.2", "twilio": "^3.80.1", - "zod": "^3.18.0" + "zod": "^3.19.1" }, "devDependencies": { "@calcom/tsconfig": "*" diff --git a/packages/prisma/package.json b/packages/prisma/package.json index 2b2d21be14..2b459baf73 100644 --- a/packages/prisma/package.json +++ b/packages/prisma/package.json @@ -27,7 +27,7 @@ "@prisma/client": "^4.2.1", "prisma": "^4.2.1", "ts-node": "^10.9.1", - "zod": "^3.18.0", + "zod": "^3.19.1", "zod-prisma": "^0.5.4" }, "main": "index.ts", diff --git a/packages/trpc/package.json b/packages/trpc/package.json index fc1fbae75a..617ce0ea91 100644 --- a/packages/trpc/package.json +++ b/packages/trpc/package.json @@ -12,6 +12,6 @@ "@trpc/react": "^10.0.0-proxy-beta.5", "@trpc/server": "^10.0.0-proxy-beta.5", "superjson": "1.9.1", - "zod": "^3.18.0" + "zod": "^3.19.1" } } diff --git a/yarn.lock b/yarn.lock index 2567b9f7bc..1fcaf0272e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -25845,16 +25845,11 @@ zod-prisma@^0.5.4: parenthesis "^3.1.8" ts-morph "^13.0.2" -zod@^3.17.3: +zod@^3.17.3, zod@^3.19.1: version "3.19.1" resolved "https://registry.yarnpkg.com/zod/-/zod-3.19.1.tgz#112f074a97b50bfc4772d4ad1576814bd8ac4473" integrity sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA== -zod@^3.18.0: - version "3.18.0" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.18.0.tgz#2eed58b3cafb8d9a67aa2fee69279702f584f3bc" - integrity sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA== - zustand@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.1.1.tgz#5a61cc755a002df5f041840a414ae6e9a99ee22b" From 477941545e83c7a445f6fc3cd6e97a74cf350912 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 19 Oct 2022 21:59:13 +0100 Subject: [PATCH 2/9] New Crowdin translations by Github Action (#5115) Co-authored-by: Crowdin Bot --- apps/web/public/static/locales/ro/common.json | 160 +++++++++--------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/apps/web/public/static/locales/ro/common.json b/apps/web/public/static/locales/ro/common.json index 283cd6c843..bcae4e34a8 100644 --- a/apps/web/public/static/locales/ro/common.json +++ b/apps/web/public/static/locales/ro/common.json @@ -230,7 +230,7 @@ "current_time": "Ora curentă", "details": "Detalii", "welcome": "Bun venit", - "welcome_back": "Bine ai revenit", + "welcome_back": "Bine ați revenit", "welcome_to_calcom": "Bine ați venit la Cal.com", "welcome_instructions": "Spune-ne ce să te sune și spune-ne în ce fus orar. Vei putea edita mai târziu.", "connect_caldav": "Conectează-te la serverul CalDav", @@ -243,7 +243,7 @@ "when": "Când", "where": "Unde", "add_to_calendar": "Adaugă în calendar", - "add_another_calendar": "Adaugă alt calendar", + "add_another_calendar": "Adăugați alt calendar", "other": "Altele", "emailed_you_and_attendees": "V-am trimis un e-mail dumneavoastră şi celuilalt participant la o invitaţie în calendar cu toate detaliile.", "emailed_you_and_attendees_recurring": "V-am trimis un e-mail dvs. și celorlalți participanți cu o invitație în calendar pentru primul dintre aceste evenimente recurente.", @@ -312,7 +312,7 @@ "recurring_bookings": "De îndată ce o persoană rezervă o întâlnire recurentă cu dvs., întâlnirea va apărea aici.", "past_bookings": "Rezervările anterioare vor apărea aici.", "cancelled_bookings": "Rezervările tale anulate vor apărea aici.", - "unconfirmed_bookings": "Rezervările tale neconfirmate vor apărea aici.", + "unconfirmed_bookings": "Rezervările dvs. neconfirmate vor apărea aici.", "on": "pe", "and": "şi", "calendar_shows_busy_between": "Calendarul vă arată ca ocupat între", @@ -496,9 +496,9 @@ "lets_create_first_administrator_user": "Haideți să creăm primul utilizator administrator.", "new_member": "Membru Nou", "invite": "Invită", - "add_team_members": "Adaugă membri în echipă", + "add_team_members": "Adăugați membri în echipă", "add_team_members_description": "Invită alte persoane să se alăture echipei tale", - "add_team_member": "Adaugă membru al echipei", + "add_team_member": "Adăugați membru al echipei", "invite_new_member": "Invită un membru nou", "invite_new_team_member": "Invită pe cineva în echipa ta.", "change_member_role": "Schimbați rolul de membru al echipei", @@ -665,7 +665,7 @@ "disable_guests_description": "Dezactivează adăugarea de vizitatori suplimentari în timpul rezervării.", "private_link": "Generare URL privat", "private_link_label": "Link privat", - "private_link_hint": "Linkul tău privat se va regenera după fiecare utilizare", + "private_link_hint": "Linkul dvs. privat se va regenera după fiecare utilizare", "copy_private_link": "Copiere link privat", "private_link_description": "Generați un URL privat pentru distribuire fără expunerea numelui de utilizator Cal", "invitees_can_schedule": "Invitații pot programa", @@ -715,7 +715,7 @@ "next_step_text": "Următorul pas", "next_step": "Sari peste", "prev_step": "Pas anterior", - "install": "Instalează", + "install": "Instalați", "installed": "Instalat", "active_install_one": "{{count}} instalare activă", "active_install_other": "{{count}} (de) instalări active", @@ -763,13 +763,13 @@ "explore_apps": "Aplicații {{category}}", "installed_apps": "Aplicații instalate", "no_category_apps": "Nicio aplicație {{category}}", - "no_category_apps_description_calendar": "Adaugă o aplicație calendar pentru a verifica dacă există conflicte și a preveni rezervări suprapuse", + "no_category_apps_description_calendar": "Adăugați o aplicație calendar pentru a verifica dacă există conflicte și a preveni rezervări suprapuse", "no_category_apps_description_conferencing": "Încercați să adăugați o aplicație de conferință pentru a integra apelul video cu clienții dvs.", - "no_category_apps_description_payment": "Adaugă o aplicație de plată pentru a facilita tranzacția între tine și clienții tăi", - "no_category_apps_description_other": "Adaugă orice alt tip de aplicație pentru a face tot felul de lucruri", - "installed_app_calendar_description": "Setează calendarele să verifice dacă există conflicte, pentru a preveni rezervările suprapuse.", - "installed_app_conferencing_description": "Adaugă aplicațiile tale preferate de conferințe video pentru ședințele tale", - "installed_app_payment_description": "Configurează serviciile de procesare a plăților care vor fi utilizate la taxarea clienților.", + "no_category_apps_description_payment": "Adăugați o aplicație de plată pentru a facilita tranzacția între dvs. și clienții dvs.", + "no_category_apps_description_other": "Adăugați orice alt tip de aplicație pentru a face tot felul de lucruri", + "installed_app_calendar_description": "Setați calendarele să verifice dacă există conflicte, pentru a preveni rezervările suprapuse.", + "installed_app_conferencing_description": "Adăugați aplicațiile dvs. preferate de conferințe video pentru ședințele dvs.", + "installed_app_payment_description": "Configurați serviciile de procesare a plăților care vor fi utilizate la taxarea clienților.", "installed_app_other_description": "Toate aplicațiile instalate din alte categorii.", "empty_installed_apps_headline": "Nicio aplicație instalată", "empty_installed_apps_description": "Aplicațiile vă permit să vă îmbunătățiți în mod semnificativ fluxul de lucru și activitățile legate de programări.", @@ -809,7 +809,7 @@ "set_to_default": "Setare ca implicit", "new_schedule_btn": "Program nou", "add_new_schedule": "Adăugați un program nou", - "add_new_calendar": "Adaugă un calendar nou", + "add_new_calendar": "Adăugați un calendar nou", "set_calendar": "Setați unde să adăugați evenimente noi când sunteți rezervat.", "delete_schedule": "Ștergeți programul", "schedule_created_successfully": "Programul {{scheduleName}} a fost creat cu succes", @@ -1077,61 +1077,61 @@ "notification_sent": "Notificare trimisă", "no_input": "Nu s-a introdus nimic", "test_workflow_action": "Acțiune flux de lucru de testare", - "send_sms": "Trimite SMS", - "send_sms_to_number": "Sigur vrei să trimiți un SMS către {{number}}?", + "send_sms": "Trimiteți SMS", + "send_sms_to_number": "Sigur vreți să trimiteți un SMS către {{number}}?", "missing_connected_calendar": "Nu este conectat niciun calendar implicit", - "connect_your_calendar_and_link": "Îți poți conecta calendarul de <1>aici.", + "connect_your_calendar_and_link": "Vă puteți conecta calendarul de <1>aici.", "default_calendar_selected": "Calendar implicit", - "hide_from_profile": "Ascunde din profil", + "hide_from_profile": "Ascundeți din profil", "event_setup_tab_title": "Configurare eveniment", "event_limit_tab_title": "Limite", - "event_limit_tab_description": "Cât de des poți fi rezervat", + "event_limit_tab_description": "Cât de des puteți fi rezervat", "event_advanced_tab_description": "Setări calendar și mai multe...", "event_advanced_tab_title": "Avansat", - "select_which_cal": "Alege la ce calendar se adaugă rezervările", + "select_which_cal": "Alegeți la ce calendar se adaugă rezervările", "custom_event_name": "Nume eveniment personalizat", - "custom_event_name_description": "Creează nume de evenimente personalizate pentru a fi afișate pe evenimentul calendarului", + "custom_event_name_description": "Creați nume de evenimente personalizate pentru a fi afișate pe evenimentul calendarului", "2fa_required": "Autentificare cu doi factori necesară", "incorrect_2fa": "Cod incorect de autentificare cu doi factori", "which_event_type_apply": "La ce tip de eveniment se va aplica aceasta?", - "no_workflows_description": "Fluxurile de lucru permit automatizarea simplă pentru a trimite notificări și mementouri, care îți permit să construiești procese în jurul evenimentelor tale.", - "create_workflow": "Creează un flux de lucru", - "do_this": "Fă acest lucru", - "turn_off": "Dezactivează", + "no_workflows_description": "Fluxurile de lucru permit automatizarea simplă pentru a trimite notificări și mementouri, care vă permit să construiți procese în jurul evenimentelor dvs.", + "create_workflow": "Creați un flux de lucru", + "do_this": "Faceți acest lucru", + "turn_off": "Dezactivați", "settings_updated_successfully": "Setări actualizate cu succes", "error_updating_settings": "Eroare la actualizarea setărilor", "personal_cal_url": "URL-ul meu personal Cal", "bio_hint": "Câteva propoziții despre dvs. Acestea vor apărea pe pagina URL-ului dvs. personal.", - "delete_account_modal_title": "Șterge contul", - "confirm_delete_account_modal": "Sigur dorești să îți ștergi contul Cal.com?", - "delete_my_account": "Șterge contul meu", + "delete_account_modal_title": "Ștergeți contul", + "confirm_delete_account_modal": "Sigur doriți să vă ștergeți contul Cal.com?", + "delete_my_account": "Ștergeți contul meu", "start_of_week": "Începutul săptămânii", - "select_calendars": "Selectează pe ce calendare vrei să verifici dacă există conflicte pentru a preveni rezervările suprapuse.", + "select_calendars": "Selectați pe ce calendare vreți să verificați dacă există conflicte pentru a preveni rezervările suprapuse.", "check_for_conflicts": "Verifică dacă există conflicte", "adding_events_to": "Adăugarea de evenimente la", - "follow_system_preferences": "Urmărește preferințele sistemului", + "follow_system_preferences": "Urmăriți preferințele sistemului", "custom_brand_colors": "Culori personalizate ale mărcii", "customize_your_brand_colors": "Personalizați-vă pagina de rezervare folosind culoarea mărcii dvs.", "pro": "Pro", - "removes_cal_branding": "Elimină orice mărci de tip Cal, și anume „Powered by Cal”.", + "removes_cal_branding": "Eliminați orice mărci de tip Cal, și anume „Powered by Cal”.", "profile_picture": "Poză de profil", - "upload": "Încarcă", + "upload": "Încărcați", "web3": "Web3", "rainbow_token_gated": "Accesul la acest tip de eveniment se face pe baza tokenului.", "rainbow_connect_wallet_gate": "Conectați-vă portofelul dacă dețineți <1>{{name}} (<3>{{symbol}}).", - "rainbow_insufficient_balance": "Portofelul tău conectat nu conține suficient <1>{{symbol}}.", + "rainbow_insufficient_balance": "Portofelul dvs. conectat nu conține suficient <1>{{symbol}}.", "rainbow_sign_message_request": "Semnați solicitarea de mesaj în portofel.", "rainbow_signature_error": "Eroare la solicitarea semnăturii din portofel.", "token_address": "Adresă token", "blockchain": "Blockchain", "old_password": "Parola veche", - "secure_password": "Noua ta parolă super sigură", + "secure_password": "Noua dvs. parolă super sigură", "error_updating_password": "Eroare la actualizarea parolei", "two_factor_auth": "Autentificare cu doi factori", - "recurring_event_tab_description": "Configurează un program de repetare", + "recurring_event_tab_description": "Configurați un program de repetare", "today": "astăzi", "appearance": "Aspect", - "appearance_subtitle": "Gestionează setările pentru aspectul rezervărilor", + "appearance_subtitle": "Gestionați setările pentru aspectul rezervărilor", "my_account": "Contul meu", "general": "Generalități", "calendars": "Calendare", @@ -1141,28 +1141,28 @@ "impersonation": "Reprezentare", "users": "Utilizatori", "profile_description": "Gestionați setările profilului dvs. Cal", - "general_description": "Gestionează setările pentru limba și fusul orar", - "calendars_description": "Configurează cum interacționează tipurile de evenimente cu calendarele tale", - "appearance_description": "Gestionează setările pentru aspectul rezervărilor tale", + "general_description": "Gestionați setările pentru limba și fusul orar", + "calendars_description": "Configurați cum interacționează tipurile de evenimente cu calendarele dvs.", + "appearance_description": "Gestionați setările pentru aspectul rezervărilor dvs.", "conferencing_description": "Gestionează aplicațiile de conferințe video pentru ședințele tale", - "password_description": "Gestionează setările pentru parolele contului tău", - "2fa_description": "Gestionează setările pentru parolele contului tău", - "we_just_need_basic_info": "Avem nevoie doar de câteva informații de bază pentru configurarea profilului tău.", - "skip": "Omite", + "password_description": "Gestionați setările pentru parolele contului dvs.", + "2fa_description": "Gestionați setările pentru parolele contului dvs.", + "we_just_need_basic_info": "Avem nevoie doar de câteva informații de bază pentru configurarea profilului dvs.", + "skip": "Omiteți", "do_this_later": "Mai târziu", "set_availability_getting_started_subtitle_1": "Definiți intervalele de timp pentru disponibilitatea dvs.", "set_availability_getting_started_subtitle_2": "Puteți personaliza toate acestea mai târziu în pagina de disponibilitate.", "connect_calendars_from_app_store": "Puteți adăuga mai multe calendare din magazinul de aplicații", - "connect_conference_apps": "Conectează aplicațiile de conferință", - "connect_calendar_apps": "Conectează aplicații calendar", - "connect_payment_apps": "Conectează aplicații de plată", - "connect_other_apps": "Conectează alte aplicații", + "connect_conference_apps": "Conectați aplicațiile de conferință", + "connect_calendar_apps": "Conectați aplicații calendar", + "connect_payment_apps": "Conectați aplicații de plată", + "connect_other_apps": "Conectați alte aplicații", "current_step_of_total": "Pasul {{currentStep}} din {{maxSteps}}", - "add_variable": "Adaugă variabilă", + "add_variable": "Adăugați variabilă", "custom_phone_number": "Număr de telefon personalizat", "message_template": "Șablon mesaj", "email_subject": "Subiect e-mail", - "add_dynamic_variables": "Adaugă variabile text dinamice", + "add_dynamic_variables": "Adăugați variabile text dinamice", "event_name_info": "Numele tipului de eveniment", "event_date_info": "Data evenimentului", "event_time_info": "Ora începerii evenimentului", @@ -1175,83 +1175,83 @@ "download_responses": "Răspunsuri la descărcare", "create_your_first_form": "Creați primul dvs. formular", "create_your_first_form_description": "Cu ajutorul formularelor de direcționare puteți adresa întrebări de calificare şi direcționa către persoana sau tipul de eveniment corect.", - "create_your_first_webhook": "Creează primul tău Webhook", - "create_your_first_webhook_description": "Cu Webhook-urile, poți primi date despre ședințe în timp real atunci când se întâmplă ceva pe Cal.com.", + "create_your_first_webhook": "Creați primul dvs. Webhook", + "create_your_first_webhook_description": "Cu Webhook-urile, puteți primi date despre ședințe în timp real atunci când se întâmplă ceva pe Cal.com.", "for_a_maximum_of": "Pentru maximum", "event_one": "eveniment", "event_other": "evenimente", - "profile_team_description": "Gestionează setările profilului echipei tale", + "profile_team_description": "Gestionați setările profilului echipei dvs.", "members_team_description": "Utilizatori care sunt în grup", "team_url": "URL-ul echipei", - "delete_team": "Șterge echipa", + "delete_team": "Ștergeți echipa", "team_members": "Membrii echipei", "more": "Mai mult", - "more_page_footer": "Considerăm că aplicația mobilă este o extensie a aplicației web. Dacă efectuezi orice acțiuni complicate, te rugăm să consulți aplicația web.", - "workflow_example_1": "Trimite participantului un memento prin SMS cu 24 de ore înainte de începerea evenimentului", - "workflow_example_2": "Trimite participantului un SMS personalizat atunci când evenimentul este reprogramat", + "more_page_footer": "Considerăm că aplicația mobilă este o extensie a aplicației web. Dacă efectuați orice acțiuni complicate, vă rugăm să consultați aplicația web.", + "workflow_example_1": "Trimiteți participantului un memento prin SMS cu 24 de ore înainte de începerea evenimentului", + "workflow_example_2": "Trimiteți participantului un SMS personalizat atunci când evenimentul este reprogramat", "workflow_example_3": "Trimiteți gazdei un e-mail personalizat atunci când evenimentul nou este rezervat", - "workflow_example_4": "Trimite participantului un memento prin e-mail cu 1 oră înainte de începerea evenimentului", + "workflow_example_4": "Trimiteți participantului un memento prin e-mail cu 1 oră înainte de începerea evenimentului", "workflow_example_5": "Trimiteți gazdei un e-mail personalizat atunci când evenimentul nou este reprogramat", "workflow_example_6": "Trimiteți gazdei un SMS personalizat atunci când evenimentul nou este rezervat", "welcome_to_cal_header": "Bun venit la Cal.com!", - "edit_form_later_subtitle": "Vei putea să editezi mai târziu.", + "edit_form_later_subtitle": "Veți putea să editați mai târziu.", "connect_calendar_later": "Îmi voi conecta calendarul mai târziu", "set_my_availability_later": "Îmi voi seta disponibilitatea mai târziu", - "problem_saving_user_profile": "A apărut o problemă la salvarea datelor tale. Încearcă din nou sau contactează serviciul de asistență pentru clienți.", + "problem_saving_user_profile": "A apărut o problemă la salvarea datelor dvs. Încercați din nou sau contactați serviciul de asistență pentru clienți.", "purchase_missing_seats": "Cumpărați locuri lipsă", "slot_length": "Lungime interval", "booking_appearance": "Aspectul rezervării", - "appearance_team_description": "Gestionează setările pentru aspectul rezervărilor echipei tale", + "appearance_team_description": "Gestionați setările pentru aspectul rezervărilor echipei dvs.", "only_owner_change": "Doar proprietarul acestei echipe poate schimba rezervarea echipei ", "team_disable_cal_branding_description": "Eliminați orice mărci de tip Cal, și anume „Powered by Cal”", - "invited_by_team": "{{teamName}} te-a invitat să te alături echipei sale ca {{role}}", + "invited_by_team": "{{teamName}} v-a invitat să vă alăturați echipei sale ca {{role}}", "token_invalid_expired": "Tokenul este nevalid sau expirat.", - "exchange_add": "Conectează-te la Microsoft Exchange", + "exchange_add": "Conectați-vă la Microsoft Exchange", "exchange_authentication": "Metodă de autentificare", "exchange_authentication_standard": "Autentificare de bază", "exchange_authentication_ntlm": "Autentificare NTLM", "exchange_compression": "Compresie GZip", - "routing_forms_description": "Aici poți vedea toate formularele și direcțioările pe care le-ai creat.", - "add_new_form": "Adaugă formular nou", - "form_description": "Creează formularul pentru direcționarea unei persoane care face rezervare", + "routing_forms_description": "Aici puteți vedea toate formularele și direcțioările pe care le-ati creat.", + "add_new_form": "Adăugați formular nou", + "form_description": "Creați formularul pentru direcționarea unei persoane care face rezervare", "copy_link_to_form": "Copiați linkul la formular", "theme": "Temă", - "theme_applies_note": "Acest lucru se aplică numai paginilor tale de rezervare publice", + "theme_applies_note": "Acest lucru se aplică numai paginilor dvs. de rezervare publice", "theme_light": "Lumină", "theme_dark": "Întunecat", "theme_system": "Implicit sistem", - "add_a_team": "Adaugă o echipă", - "add_webhook_description": "Primește datele ședințelor în timp real atunci când se întâmplă ceva pe Cal.com", + "add_a_team": "Adăugați o echipă", + "add_webhook_description": "Primiți datele ședințelor în timp real atunci când se întâmplă ceva pe Cal.com", "triggers_when": "Se declanșează când", "test_webhook": "Testați ping-ul înainte de creare.", - "enable_webhook": "Activează Webhook", - "add_webhook": "Adaugă Webhook", + "enable_webhook": "Activați Webhook", + "add_webhook": "Adăugați Webhook", "webhook_edited_successfully": "Webhook salvat", - "webhooks_description": "Primește datele ședințelor în timp real atunci când se întâmplă ceva pe Cal.com", - "api_keys_description": "Generează chei API pentru accesarea propriului tău cont", + "webhooks_description": "Primiți datele ședințelor în timp real atunci când se întâmplă ceva pe Cal.com", + "api_keys_description": "Generați chei API pentru accesarea propriului dvs. cont", "new_api_key": "Cheie API nouă", "active": "Activ", "api_key_updated": "Nume cheie API actualizat", "api_key_update_failed": "Eroare la actualizarea numelui cheii API", "embeds_title": "Încorporare HTML iframe", "embeds_description": "Încorporați toate tipurile de evenimente pe site-ul dvs.", - "create_first_api_key": "Creează prima ta cheie API", + "create_first_api_key": "Creați prima dvs. cheie API", "create_first_api_key_description": "Cheile API permit altor aplicații să comunice cu Cal.com", "back_to_signin": "Înapoi la autentificare", "reset_link_sent": "Link de resetare trimis", - "password_reset_email": "Vei primi în curând un e-mail la {{email}} cu instrucțiuni de resetare a parolei.", + "password_reset_email": "Veți primi în curând un e-mail la {{email}} cu instrucțiuni de resetare a parolei.", "password_updated": "Parolă actualizată!", "pending_payment": "Plată în așteptare", "confirmation_page_rainbow": "Restricționați accesul la evenimentul dvs. cu tokeni sau NFT-uri pe Ethereum, Polygon și altele.", "not_on_cal": "Nu pe Cal.com", "no_calendar_installed": "Niciun calendar instalat", - "no_calendar_installed_description": "Încă nu ai conectat niciunul dintre calendarele tale", - "add_a_calendar": "Adaugă un calendar", - "change_email_hint": "S-ar putea să fie nevoie să te deconectezi și să te reconectezi pentru aplicarea oricăror modificări", - "confirm_password_change_email": "Te rugăm să confirmi parola înainte de a-ți schimba adresa de e-mail", + "no_calendar_installed_description": "Încă nu ați conectat niciunul dintre calendarele dvs.", + "add_a_calendar": "Adăugați un calendar", + "change_email_hint": "S-ar putea să fie nevoie să vă deconectați și să vă reconectați pentru aplicarea oricăror modificări", + "confirm_password_change_email": "Vă rugăm să confirmați parola înainte de a vă schimba adresa de e-mail", "seats": "locuri", - "every_app_published": "Fiecare aplicație publicată pe Cal.com App Store este open source și testată temeinic prin evaluări inter pares. Cu toate acestea, Cal.com, Inc. nu susține sau certifică aceste aplicații decât dacă sunt publicate de Cal.com. Dacă întâmpini un conținut sau un comportament necorespunzător, te rugăm să îl raportezi.", - "report_app": "Raportează aplicația", + "every_app_published": "Fiecare aplicație publicată pe Cal.com App Store este open source și testată temeinic prin evaluări inter pares. Cu toate acestea, Cal.com, Inc. nu susține sau certifică aceste aplicații decât dacă sunt publicate de Cal.com. Dacă întâmpinați un conținut sau un comportament necorespunzător, vă rugăm să îl raportați.", + "report_app": "Raportați aplicația", "billing_manage_details_title": "Vizualizați și gestionați detaliile de facturare", "billing_manage_details_description": "Vizualizați și editați detaliile de facturare, precum și anulați abonarea.", "billing_help_title": "Aveți nevoie de altceva?", From 7756b9c3a19aeb608d7291798930443aa14e6090 Mon Sep 17 00:00:00 2001 From: Hariom Balhara Date: Thu, 20 Oct 2022 02:55:03 +0530 Subject: [PATCH 3/9] The links that can be directly given to embed should pre-render(Either SSG/SSR) (#4975) * Embed SSG and consistently pass embedType query param across pages * Embed fixes * Code cleanup * Add main class which tells embed which helps in identifying which area is outside the main content * remove any special optimization handling for routing forms * Add comments * Small fixes * Fix broken team booking page in embed * Fix Fallback message dark theme * TS Fixes * Fixes * Fix tests * Remove not required code Co-authored-by: Peer Richelsen --- .../web/components/booking/AvailableTimes.tsx | 2 +- apps/web/components/booking/CancelBooking.tsx | 2 +- .../booking/pages/AvailabilityPage.tsx | 4 +- .../components/booking/pages/BookingPage.tsx | 4 +- apps/web/lib/withEmbedSsr.tsx | 21 +++++++++ apps/web/middleware.ts | 7 +++ apps/web/next.config.js | 4 +- apps/web/pages/[user].tsx | 7 ++- apps/web/pages/[user]/[type].tsx | 3 +- apps/web/pages/[user]/[type]/embed.tsx | 21 +++++++++ apps/web/pages/[user]/book.tsx | 1 + apps/web/pages/[user]/embed.tsx | 7 +++ apps/web/pages/_document.tsx | 47 +++++++++---------- apps/web/pages/d/[link]/[slug].tsx | 9 +++- apps/web/pages/d/[link]/[slug]/embed.tsx | 7 +++ apps/web/pages/d/[link]/book.tsx | 2 +- apps/web/pages/success.tsx | 2 +- apps/web/pages/team/[slug].tsx | 9 ++-- apps/web/pages/team/[slug]/[type].tsx | 5 +- apps/web/pages/team/[slug]/[type]/embed.tsx | 7 +++ apps/web/pages/team/[slug]/book.tsx | 4 +- apps/web/pages/team/[slug]/embed.tsx | 7 +++ apps/web/playwright/fixtures/embeds.ts | 2 +- .../pages/routing-link/[...appPages].tsx | 26 ++++++---- packages/embeds/embed-core/index.html | 4 +- .../playwright/config/playwright.config.ts | 19 ++++---- .../playwright/fixtures/fixtures.ts | 2 +- .../embed-core/playwright/lib/testUtils.ts | 2 +- .../embed-core/src/Inline/inlineHtml.ts | 6 +-- .../embeds/embed-core/src/embed-iframe.ts | 17 ++----- packages/embeds/embed-core/src/embed.ts | 4 ++ 31 files changed, 175 insertions(+), 89 deletions(-) create mode 100644 apps/web/lib/withEmbedSsr.tsx create mode 100644 apps/web/pages/[user]/[type]/embed.tsx create mode 100644 apps/web/pages/[user]/embed.tsx create mode 100644 apps/web/pages/d/[link]/[slug]/embed.tsx create mode 100644 apps/web/pages/team/[slug]/[type]/embed.tsx create mode 100644 apps/web/pages/team/[slug]/embed.tsx diff --git a/apps/web/components/booking/AvailableTimes.tsx b/apps/web/components/booking/AvailableTimes.tsx index 7d55b70292..43db34e51b 100644 --- a/apps/web/components/booking/AvailableTimes.tsx +++ b/apps/web/components/booking/AvailableTimes.tsx @@ -65,7 +65,7 @@ const AvailableTimes: FC = ({ query: Record; }; const bookingUrl: BookingURL = { - pathname: "book", + pathname: router.pathname.endsWith("/embed") ? "../book" : "book", query: { ...router.query, date: dayjs(slot.time).format(), diff --git a/apps/web/components/booking/CancelBooking.tsx b/apps/web/components/booking/CancelBooking.tsx index 39c0cefbb5..1e1a2ab510 100644 --- a/apps/web/components/booking/CancelBooking.tsx +++ b/apps/web/components/booking/CancelBooking.tsx @@ -63,7 +63,7 @@ export default function CancelBooking(props: Props) { diff --git a/apps/web/components/booking/pages/AvailabilityPage.tsx b/apps/web/components/booking/pages/AvailabilityPage.tsx index c125fc5277..7543c2ba1f 100644 --- a/apps/web/components/booking/pages/AvailabilityPage.tsx +++ b/apps/web/components/booking/pages/AvailabilityPage.tsx @@ -304,11 +304,11 @@ const timeFormatTotimeFormatString = (timeFormat?: number | null) => { return timeFormat === 24 ? "HH:mm" : "h:mma"; }; -const AvailabilityPage = ({ profile, eventType }: Props) => { +const AvailabilityPage = ({ profile, eventType, ...restProps }: Props) => { const { data: user } = trpc.useQuery(["viewer.me"]); const timeFormatFromProfile = timeFormatTotimeFormatString(user?.timeFormat); const router = useRouter(); - const isEmbed = useIsEmbed(); + const isEmbed = useIsEmbed(restProps.isEmbed); const query = dateQuerySchema.parse(router.query); const { rescheduleUid } = query; useTheme(profile.theme); diff --git a/apps/web/components/booking/pages/BookingPage.tsx b/apps/web/components/booking/pages/BookingPage.tsx index c2b1894322..0d5f5d059b 100644 --- a/apps/web/components/booking/pages/BookingPage.tsx +++ b/apps/web/components/booking/pages/BookingPage.tsx @@ -1,6 +1,5 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { EventTypeCustomInputType, WorkflowActions } from "@prisma/client"; -import { SchedulingType } from "@prisma/client"; import { useMutation } from "@tanstack/react-query"; import { isValidPhoneNumber } from "libphonenumber-js"; import { useSession } from "next-auth/react"; @@ -84,9 +83,10 @@ const BookingPage = ({ recurringEventCount, hasHashedBookingLink, hashedLink, + ...restProps }: BookingPageProps) => { const { t, i18n } = useLocale(); - const isEmbed = useIsEmbed(); + const isEmbed = useIsEmbed(restProps.isEmbed); const shouldAlignCentrallyInEmbed = useEmbedNonStylesConfig("align") !== "left"; const shouldAlignCentrally = !isEmbed || shouldAlignCentrallyInEmbed; const router = useRouter(); diff --git a/apps/web/lib/withEmbedSsr.tsx b/apps/web/lib/withEmbedSsr.tsx new file mode 100644 index 0000000000..f524068bf5 --- /dev/null +++ b/apps/web/lib/withEmbedSsr.tsx @@ -0,0 +1,21 @@ +import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult } from "next"; + +export type EmbedProps = { + isEmbed?: boolean; +}; + +export default function withEmbedSsr(getServerSideProps: GetServerSideProps) { + return async (context: GetServerSidePropsContext): Promise> => { + const ssrResponse = await getServerSideProps(context); + if (!("props" in ssrResponse)) { + return ssrResponse; + } + return { + ...ssrResponse, + props: { + ...ssrResponse.props, + isEmbed: true, + }, + }; + }; +} diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts index fb0d5b68a1..dddd96ec1f 100644 --- a/apps/web/middleware.ts +++ b/apps/web/middleware.ts @@ -23,6 +23,13 @@ const middleware: NextMiddleware = async (req) => { } } + // Ensure that embed query param is there in when /embed is added. + // query param is the way in which client side code knows that it is in embed mode. + if (url.pathname.endsWith("/embed") && typeof url.searchParams.get("embed") !== "string") { + url.searchParams.set("embed", ""); + return NextResponse.redirect(url); + } + // Don't 404 old routing_forms links if (url.pathname.startsWith("/apps/routing_forms")) { url.pathname = url.pathname.replace("/apps/routing_forms", "/apps/routing-forms"); diff --git a/apps/web/next.config.js b/apps/web/next.config.js index 0c6542cfaf..4108d8e01d 100644 --- a/apps/web/next.config.js +++ b/apps/web/next.config.js @@ -134,8 +134,8 @@ const nextConfig = { destination: "/api/user/avatar?teamname=:teamname", }, { - source: "/forms/:formId", - destination: "/apps/routing-forms/routing-link/:formId", + source: "/forms/:formQuery*", + destination: "/apps/routing-forms/routing-link/:formQuery*", }, { source: "/router", diff --git a/apps/web/pages/[user].tsx b/apps/web/pages/[user].tsx index b44efaa16b..ed5375f41b 100644 --- a/apps/web/pages/[user].tsx +++ b/apps/web/pages/[user].tsx @@ -30,6 +30,7 @@ import { BadgeCheckIcon, Icon } from "@calcom/ui/Icon"; import { useExposePlanGlobally } from "@lib/hooks/useExposePlanGlobally"; import { inferSSRProps } from "@lib/types/inferSSRProps"; +import { EmbedProps } from "@lib/withEmbedSsr"; import AvatarGroup from "@components/ui/AvatarGroup"; import { AvatarSSR } from "@components/ui/AvatarSSR"; @@ -38,7 +39,7 @@ import { ssrInit } from "@server/lib/ssr"; const EventTypeDescription = dynamic(() => import("@calcom/ui/v2/modules/event-types/EventTypeDescription")); const HeadSeo = dynamic(() => import("@components/seo/head-seo")); -export default function User(props: inferSSRProps) { +export default function User(props: inferSSRProps & EmbedProps) { const { users, profile, eventTypes, isDynamicGroup, dynamicNames, dynamicUsernames, isSingleUser } = props; const [user] = users; //To be used when we only have a single user, not dynamic group useTheme(user.theme); @@ -86,7 +87,7 @@ export default function User(props: inferSSRProps) { ); - const isEmbed = useIsEmbed(); + const isEmbed = useIsEmbed(props.isEmbed); const eventTypeListItemEmbedStyles = useEmbedStyles("eventTypeListItem"); const shouldAlignCentrallyInEmbed = useEmbedNonStylesConfig("align") !== "left"; const shouldAlignCentrally = !isEmbed || shouldAlignCentrallyInEmbed; @@ -287,6 +288,8 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => if (!users.length) { return { notFound: true, + } as { + notFound: true; }; } const isDynamicGroup = users.length > 1; diff --git a/apps/web/pages/[user]/[type].tsx b/apps/web/pages/[user]/[type].tsx index 07241b0c70..cf78274543 100644 --- a/apps/web/pages/[user]/[type].tsx +++ b/apps/web/pages/[user]/[type].tsx @@ -11,10 +11,11 @@ import prisma from "@calcom/prisma"; import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import { inferSSRProps } from "@lib/types/inferSSRProps"; +import { EmbedProps } from "@lib/withEmbedSsr"; import AvailabilityPage from "@components/booking/pages/AvailabilityPage"; -export type AvailabilityPageProps = inferSSRProps; +export type AvailabilityPageProps = inferSSRProps & EmbedProps; export default function Type(props: AvailabilityPageProps) { const { t } = useLocale(); diff --git a/apps/web/pages/[user]/[type]/embed.tsx b/apps/web/pages/[user]/[type]/embed.tsx new file mode 100644 index 0000000000..4b701ce151 --- /dev/null +++ b/apps/web/pages/[user]/[type]/embed.tsx @@ -0,0 +1,21 @@ +import { GetStaticPropsContext } from "next"; + +import { getStaticProps as _getStaticProps } from "../[type]"; + +export { getStaticPaths } from "../[type]"; + +export { default } from "../[type]"; + +export const getStaticProps = async (context: GetStaticPropsContext) => { + const staticResponse = await _getStaticProps(context); + if (staticResponse.notFound) { + return staticResponse; + } + return { + ...staticResponse, + props: { + ...staticResponse.props, + isEmbed: true, + }, + }; +}; diff --git a/apps/web/pages/[user]/book.tsx b/apps/web/pages/[user]/book.tsx index 0aae61782f..36b353fb23 100644 --- a/apps/web/pages/[user]/book.tsx +++ b/apps/web/pages/[user]/book.tsx @@ -197,6 +197,7 @@ export async function getServerSideProps(context: GetServerSidePropsContext) { isDynamicGroupBooking, hasHashedBookingLink: false, hashedLink: null, + isEmbed: typeof context.query.embed === "string", }, }; } diff --git a/apps/web/pages/[user]/embed.tsx b/apps/web/pages/[user]/embed.tsx new file mode 100644 index 0000000000..5c62c6117e --- /dev/null +++ b/apps/web/pages/[user]/embed.tsx @@ -0,0 +1,7 @@ +import withEmbedSsr from "@lib/withEmbedSsr"; + +import { getServerSideProps as _getServerSideProps } from "../[user]"; + +export { default } from "../[user]"; + +export const getServerSideProps = withEmbedSsr(_getServerSideProps); diff --git a/apps/web/pages/_document.tsx b/apps/web/pages/_document.tsx index 56def4c1c8..cb1654466d 100644 --- a/apps/web/pages/_document.tsx +++ b/apps/web/pages/_document.tsx @@ -3,18 +3,13 @@ import Document, { DocumentContext, Head, Html, Main, NextScript, DocumentProps type Props = Record & DocumentProps; function toRunBeforeReactOnClient() { - const calEmbedMode = location.search.includes("embed="); - try { - // eslint-disable-next-line @calcom/eslint/avoid-web-storage - window.sessionStorage.setItem("calEmbedMode", String(calEmbedMode)); - } catch (e) {} + const calEmbedMode = + location.search.includes("embed=") || + /* Iframe Name */ + window.name.includes("cal-embed"); window.isEmbed = () => { - try { - // eslint-disable-next-line @calcom/eslint/avoid-web-storage - return window.sessionStorage.getItem("calEmbedMode") === "true"; - } catch (e) {} - // If we can't use sessionStorage to retrieve embed mode, just use the variable. It would fail to detect embed if page in iframe reloads without embed query param in it. + // Once an embed mode always an embed mode return calEmbedMode; }; @@ -45,14 +40,14 @@ function toRunBeforeReactOnClient() { class MyDocument extends Document { static async getInitialProps(ctx: DocumentContext) { + const isEmbed = ctx.asPath?.includes("/embed") || ctx.asPath?.includes("embedType="); const initialProps = await Document.getInitialProps(ctx); - return { ...initialProps }; + return { isEmbed, ...initialProps }; } render() { const { locale } = this.props.__NEXT_DATA__; const dir = locale === "ar" || locale === "he" ? "rtl" : "ltr"; - return ( @@ -82,22 +77,22 @@ class MyDocument extends Document { /> - +
- {/* In case of Embed we want background to be transparent so that it merges into the website seamlessly. Also, we keep the body hidden here and embed logic would take care of showing the body when it's ready */} - {/* We are doing it on browser and not on server because there are some pages which are not SSRd */} -