From a697e3c5435ddaa3612ef0c948330e357f4930bc Mon Sep 17 00:00:00 2001 From: Jenkins Date: Sun, 12 Feb 2023 20:35:16 +0000 Subject: [PATCH 01/63] chore(i18n): update translations --- src/i18n/messages/ar.json | 7 +++++++ src/i18n/messages/de.json | 7 +++++++ src/i18n/messages/es_419.json | 7 +++++++ src/i18n/messages/fr.json | 7 +++++++ src/i18n/messages/fr_CA.json | 7 +++++++ src/i18n/messages/hi.json | 7 +++++++ src/i18n/messages/it.json | 7 +++++++ src/i18n/messages/pt.json | 7 +++++++ src/i18n/messages/ru.json | 7 +++++++ src/i18n/messages/uk.json | 7 +++++++ src/i18n/messages/zh_CN.json | 7 +++++++ 11 files changed, 77 insertions(+) diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index 4a4c01e..43296ce 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "تم الحفظ", "profile.visibility.who.just.me": "أنا فقط", "profile.visibility.who.everyone": "جميع من على {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "الاسم الكامل", "profile.name.details": "هذا هو الاسم الذي يظهر في حسابك وفي شهاداتك", "profile.name.empty": "إضافة الاسم", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "عرض سجلّاتي", "profile.loading": "يتم تحميل الملف الشخصي...", "profile.username.description": "معلومات ملفك الشخصي تظهر لك فقط. وحده اسم المستخدم الخاص بك يظهر للآخرين على {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index c39191f..86e3525 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Saved", "profile.visibility.who.just.me": "Just me", "profile.visibility.who.everyone": "Everyone on {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Full Name", "profile.name.details": "This is the name that appears in your account and on your certificates.", "profile.name.empty": "Add name", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "View My Records", "profile.loading": "Profile loading...", "profile.username.description": "Your profile information is only visible to you. Only your username is visible to others on {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/es_419.json b/src/i18n/messages/es_419.json index 4742e43..b8d7baf 100644 --- a/src/i18n/messages/es_419.json +++ b/src/i18n/messages/es_419.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Guardado", "profile.visibility.who.just.me": "Solo yo", "profile.visibility.who.everyone": "Todos en {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Nombre completo", "profile.name.details": "Este es el nombre que aparecerá en tu cuenta y en tus certificados.", "profile.name.empty": "Añade nombre", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "Ver mis registros", "profile.loading": "Cargando perfil...", "profile.username.description": "La información del perfil solo la visualiza usted. Solo el nombre de usuario es visible para los demás en {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Volver Atrás", "next.step.button": "Próximo paso" } \ No newline at end of file diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index 0977bcd..1230b86 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Enregistré", "profile.visibility.who.just.me": "Juste moi", "profile.visibility.who.everyone": "Tout le monde sur {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Nom complet", "profile.name.details": "C'est le nom qui apparaît dans votre compte et sur vos certificats.", "profile.name.empty": "Ajouter un nom", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "Voir mes succès", "profile.loading": "Chargement du profil....", "profile.username.description": "Les informations de votre profil ne sont visibles que par vous. Seul votre nom d'utilisateur est visible par les autres sur {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/fr_CA.json b/src/i18n/messages/fr_CA.json index ec690fd..e065bdb 100644 --- a/src/i18n/messages/fr_CA.json +++ b/src/i18n/messages/fr_CA.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Sauvegardé", "profile.visibility.who.just.me": "Juste moi", "profile.visibility.who.everyone": "Tout le monde sur {siteName}", + "profile.learningGoal.learningGoal": "Objectif d'apprentissage", + "profile.learningGoal.options.start_career": "Je veux commencer ma carrière", + "profile.learningGoal.options.advance_career": "Je veux faire progresser ma carrière", + "profile.learningGoal.options.learn_something_new": "Je veux apprendre quelque chose de nouveau", + "profile.learningGoal.options.something_else": "Autre chose", "profile.name.full.name": "Nom complet", "profile.name.details": "C'est le nom qui apparaît dans votre compte et sur vos attestations.", "profile.name.empty": "Ajouter un nom", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "Afficher mes dossiers", "profile.loading": "Chargement du profil...", "profile.username.description": "Les informations de votre profil ne sont visibles que par vous. Seul votre nom d'utilisateur est visible par les autres sur {siteName}.", + "skills.builder.header.title": "Constructeur de compétences", + "skills.builder.header.subheading": "Laissez EDUlib être votre guide", "go.back.button": "Retour", "next.step.button": "Prochaine étape" } \ No newline at end of file diff --git a/src/i18n/messages/hi.json b/src/i18n/messages/hi.json index c39191f..86e3525 100644 --- a/src/i18n/messages/hi.json +++ b/src/i18n/messages/hi.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Saved", "profile.visibility.who.just.me": "Just me", "profile.visibility.who.everyone": "Everyone on {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Full Name", "profile.name.details": "This is the name that appears in your account and on your certificates.", "profile.name.empty": "Add name", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "View My Records", "profile.loading": "Profile loading...", "profile.username.description": "Your profile information is only visible to you. Only your username is visible to others on {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/it.json b/src/i18n/messages/it.json index c39191f..86e3525 100644 --- a/src/i18n/messages/it.json +++ b/src/i18n/messages/it.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Saved", "profile.visibility.who.just.me": "Just me", "profile.visibility.who.everyone": "Everyone on {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Full Name", "profile.name.details": "This is the name that appears in your account and on your certificates.", "profile.name.empty": "Add name", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "View My Records", "profile.loading": "Profile loading...", "profile.username.description": "Your profile information is only visible to you. Only your username is visible to others on {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index c39191f..86e3525 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Saved", "profile.visibility.who.just.me": "Just me", "profile.visibility.who.everyone": "Everyone on {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Full Name", "profile.name.details": "This is the name that appears in your account and on your certificates.", "profile.name.empty": "Add name", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "View My Records", "profile.loading": "Profile loading...", "profile.username.description": "Your profile information is only visible to you. Only your username is visible to others on {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index c39191f..86e3525 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Saved", "profile.visibility.who.just.me": "Just me", "profile.visibility.who.everyone": "Everyone on {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Full Name", "profile.name.details": "This is the name that appears in your account and on your certificates.", "profile.name.empty": "Add name", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "View My Records", "profile.loading": "Profile loading...", "profile.username.description": "Your profile information is only visible to you. Only your username is visible to others on {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/uk.json b/src/i18n/messages/uk.json index c39191f..86e3525 100644 --- a/src/i18n/messages/uk.json +++ b/src/i18n/messages/uk.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Saved", "profile.visibility.who.just.me": "Just me", "profile.visibility.who.everyone": "Everyone on {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Full Name", "profile.name.details": "This is the name that appears in your account and on your certificates.", "profile.name.empty": "Add name", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "View My Records", "profile.loading": "Profile loading...", "profile.username.description": "Your profile information is only visible to you. Only your username is visible to others on {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file diff --git a/src/i18n/messages/zh_CN.json b/src/i18n/messages/zh_CN.json index c39191f..86e3525 100644 --- a/src/i18n/messages/zh_CN.json +++ b/src/i18n/messages/zh_CN.json @@ -34,6 +34,11 @@ "profile.formcontrols.button.saved": "Saved", "profile.visibility.who.just.me": "Just me", "profile.visibility.who.everyone": "Everyone on {siteName}", + "profile.learningGoal.learningGoal": "Learning Goal", + "profile.learningGoal.options.start_career": "I want to start my career", + "profile.learningGoal.options.advance_career": "I want to advance my career", + "profile.learningGoal.options.learn_something_new": "I want to learn something new", + "profile.learningGoal.options.something_else": "Something else", "profile.name.full.name": "Full Name", "profile.name.details": "This is the name that appears in your account and on your certificates.", "profile.name.empty": "Add name", @@ -49,6 +54,8 @@ "profile.viewMyRecords": "View My Records", "profile.loading": "Profile loading...", "profile.username.description": "Your profile information is only visible to you. Only your username is visible to others on {siteName}.", + "skills.builder.header.title": "Skills Builder", + "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step" } \ No newline at end of file From e75864b8606fdab56fa5df89f72d196885b299dd Mon Sep 17 00:00:00 2001 From: Justin Hynes Date: Mon, 13 Feb 2023 09:07:02 -0500 Subject: [PATCH 02/63] feat: Add Algolia support to Profile MFE [APER-2261] This PR adds Algolia support to the Profile MFE and the upcoming Skills Builder feature. * Adds new dependency for the `algoliasearch` package * Add new config to support Algolia * Update MFE configuration so we can access the new configuration variables * Add hook to initialize Algolia client and return job and product Algolia indexes (based on settings) * Update SkillsBuilderModal to add test code that displays the results of querying Algolia --- .env | 4 + .env.development | 4 + .env.test | 4 + package-lock.json | 273 ++++++++++++++++++ package.json | 1 + src/index.jsx | 4 + .../SkillsBuilderModal.jsx | 11 +- src/skills-builder/utils/hooks.jsx | 28 ++ 8 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 src/skills-builder/utils/hooks.jsx diff --git a/.env b/.env index bddadec..09763a6 100644 --- a/.env +++ b/.env @@ -27,3 +27,7 @@ APP_ID='' MFE_CONFIG_API_URL='' ENABLE_SKILLS_BUILDER='' ENABLE_SKILLS_BUILDER_PROFILE='' +ALGOLIA_APP_ID='' +ALGOLIA_JOBS_INDEX_NAME='' +ALGOLIA_PRODUCT_INDEX_NAME='' +ALGOLIA_SEARCH_API_KEY='' diff --git a/.env.development b/.env.development index d249e3e..b87bcde 100644 --- a/.env.development +++ b/.env.development @@ -28,3 +28,7 @@ APP_ID='' MFE_CONFIG_API_URL='' ENABLE_SKILLS_BUILDER='true' ENABLE_SKILLS_BUILDER_PROFILE='' +ALGOLIA_APP_ID='' +ALGOLIA_JOBS_INDEX_NAME='' +ALGOLIA_PRODUCT_INDEX_NAME='' +ALGOLIA_SEARCH_API_KEY='' diff --git a/.env.test b/.env.test index b79d85c..6f8232c 100644 --- a/.env.test +++ b/.env.test @@ -23,3 +23,7 @@ LEARNER_RECORD_MFE_BASE_URL='http://localhost:1990' COLLECT_YEAR_OF_BIRTH=true APP_ID='' MFE_CONFIG_API_URL='' +ALGOLIA_APP_ID='' +ALGOLIA_JOBS_INDEX_NAME='' +ALGOLIA_PRODUCT_INDEX_NAME='' +ALGOLIA_SEARCH_API_KEY='' diff --git a/package-lock.json b/package-lock.json index 4af1986..6e503ae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@fortawesome/free-regular-svg-icons": "5.15.4", "@fortawesome/free-solid-svg-icons": "5.15.4", "@fortawesome/react-fontawesome": "0.2.0", + "algoliasearch": "4.6.0", "classnames": "2.3.2", "core-js": "3.27.2", "lodash.camelcase": "4.3.0", @@ -57,6 +58,121 @@ "redux-mock-store": "1.5.4" } }, + "node_modules/@algolia/cache-browser-local-storage": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.6.0.tgz", + "integrity": "sha512-3ObeNwZ5gfDvKPp9NXdtbBrCtz/yR1oyDu/AReG73Oanua3y30Y11p7VQzzpLe2R/gDCLOGdRgr17h11lGy1Hg==", + "dependencies": { + "@algolia/cache-common": "4.6.0" + } + }, + "node_modules/@algolia/cache-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.6.0.tgz", + "integrity": "sha512-mEedrPb2O3WwtiIHggFoIhTbHVCMNikxMiiN9kqmwZkdDfClfxm435OUGZfAl67rBZfc0DNs/jmPM2mUoefM9A==" + }, + "node_modules/@algolia/cache-in-memory": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.6.0.tgz", + "integrity": "sha512-J7ayGokVWEFkuLxzgrIsPS4k1/ZndyGVpG/qPrG9RHVrs7ZogEhUSY1tbEyUlW3mGy7diIh+/52dtohDL/nbGQ==", + "dependencies": { + "@algolia/cache-common": "4.6.0" + } + }, + "node_modules/@algolia/client-account": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.6.0.tgz", + "integrity": "sha512-0t2yU6wNBNJgAmrARHrM1llhANyPT4Q/1wu6yEzv2WfPXlfsHwMhtKYNti4/k8eswwUt9wAri10WFV6TJI48rg==", + "dependencies": { + "@algolia/client-common": "4.6.0", + "@algolia/client-search": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "node_modules/@algolia/client-analytics": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.6.0.tgz", + "integrity": "sha512-7yfn9pabA21Uw2iZjW1MNN4IJUT5y/YSg+ZJ+3HqBB6SgzOOqY0N3fATsPeGuN9EqSfVnqvnIrJMS8mI0b5FzQ==", + "dependencies": { + "@algolia/client-common": "4.6.0", + "@algolia/client-search": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "node_modules/@algolia/client-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.6.0.tgz", + "integrity": "sha512-60jK0LK5H+6q6HyyMyoBBD0fIs8zZzJt6BiyJGQG90o3gUV/SnjiNxO9Bx0RRlqdkE5s0OYFu1L7P9Y5TX7oAw==", + "dependencies": { + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "node_modules/@algolia/client-recommendation": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-recommendation/-/client-recommendation-4.6.0.tgz", + "integrity": "sha512-j+Yb1z5QeIRDCCO+9hS9oZS3KNqRogPHDbJJsLTt6pkrs4CG2UVLVV67M977B1nzJ9OzaEki3VbpGQhRhPGNfQ==", + "dependencies": { + "@algolia/client-common": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "node_modules/@algolia/client-search": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.6.0.tgz", + "integrity": "sha512-+qA1NA88YnXvuCKifegfgts1RQs8IzcwccQqyurz8ins4hypZL1tXN2BkrOqqDIgvYIrUvFyhv+gLO6U9PpDUA==", + "dependencies": { + "@algolia/client-common": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "node_modules/@algolia/logger-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.6.0.tgz", + "integrity": "sha512-F+0HTGSQzJfWsX/cJq2l4eG2Y5JA6pqZ0YETyo5XJhZX4JaDrGszVKuOqp8kovZF/Ifebywxb8JdCiSUskmbig==" + }, + "node_modules/@algolia/logger-console": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.6.0.tgz", + "integrity": "sha512-ers7OhfU6qBQl6s7MOe5gNUkcpa7LGrhEzDWnD0cUwLSd5BvWt7zEN69O2CZVbvAUZYlZ5zJTzMMa49s0VXrKQ==", + "dependencies": { + "@algolia/logger-common": "4.6.0" + } + }, + "node_modules/@algolia/requester-browser-xhr": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.6.0.tgz", + "integrity": "sha512-ugrJT25VUkoKrl5vJVFclMdogbhTiDZ38Gss4xfTiSsP/SGE/0ei5VEOMEcj/bjkurJjPky1HfJZ3ykJhIsfCA==", + "dependencies": { + "@algolia/requester-common": "4.6.0" + } + }, + "node_modules/@algolia/requester-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.6.0.tgz", + "integrity": "sha512-DJ5iIGBGrRudimaaFnpBFM19pv8SsXiMYuukn9q1GgQh2mPPBCBBJiezKc7+OzE1UyCVrAFBpR/hrJnflZnRdQ==" + }, + "node_modules/@algolia/requester-node-http": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.6.0.tgz", + "integrity": "sha512-MPZK3oZz0jSBsqrGiPxv7LOKMUNknlaRNyRDy0v/ASIYG+GvLhGTdEzG5Eyw5tgSvBr8CWrWM5tDC31EH40Ndw==", + "dependencies": { + "@algolia/requester-common": "4.6.0" + } + }, + "node_modules/@algolia/transporter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.6.0.tgz", + "integrity": "sha512-xp+HI8sB8gLCvP00scaOVPQEk5H7nboWUxrwLKyVUvtUO4o003bOfFPsH86NRyu5Dv7fzX9b8EH3rVxcLOhjqg==", + "dependencies": { + "@algolia/cache-common": "4.6.0", + "@algolia/logger-common": "4.6.0", + "@algolia/requester-common": "4.6.0" + } + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -5161,6 +5277,27 @@ "ajv": "^6.9.1" } }, + "node_modules/algoliasearch": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.6.0.tgz", + "integrity": "sha512-f4QVfUYnWIGZwOupZh0RAqW8zEfpZAcZG6ZT0p6wDMztEyKBrjjbTXBk9p9uEaJqoIhFUm6TtApOxodTdHbqvw==", + "dependencies": { + "@algolia/cache-browser-local-storage": "4.6.0", + "@algolia/cache-common": "4.6.0", + "@algolia/cache-in-memory": "4.6.0", + "@algolia/client-account": "4.6.0", + "@algolia/client-analytics": "4.6.0", + "@algolia/client-common": "4.6.0", + "@algolia/client-recommendation": "4.6.0", + "@algolia/client-search": "4.6.0", + "@algolia/logger-common": "4.6.0", + "@algolia/logger-console": "4.6.0", + "@algolia/requester-browser-xhr": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/requester-node-http": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -19965,6 +20102,121 @@ } }, "dependencies": { + "@algolia/cache-browser-local-storage": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.6.0.tgz", + "integrity": "sha512-3ObeNwZ5gfDvKPp9NXdtbBrCtz/yR1oyDu/AReG73Oanua3y30Y11p7VQzzpLe2R/gDCLOGdRgr17h11lGy1Hg==", + "requires": { + "@algolia/cache-common": "4.6.0" + } + }, + "@algolia/cache-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.6.0.tgz", + "integrity": "sha512-mEedrPb2O3WwtiIHggFoIhTbHVCMNikxMiiN9kqmwZkdDfClfxm435OUGZfAl67rBZfc0DNs/jmPM2mUoefM9A==" + }, + "@algolia/cache-in-memory": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.6.0.tgz", + "integrity": "sha512-J7ayGokVWEFkuLxzgrIsPS4k1/ZndyGVpG/qPrG9RHVrs7ZogEhUSY1tbEyUlW3mGy7diIh+/52dtohDL/nbGQ==", + "requires": { + "@algolia/cache-common": "4.6.0" + } + }, + "@algolia/client-account": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.6.0.tgz", + "integrity": "sha512-0t2yU6wNBNJgAmrARHrM1llhANyPT4Q/1wu6yEzv2WfPXlfsHwMhtKYNti4/k8eswwUt9wAri10WFV6TJI48rg==", + "requires": { + "@algolia/client-common": "4.6.0", + "@algolia/client-search": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "@algolia/client-analytics": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.6.0.tgz", + "integrity": "sha512-7yfn9pabA21Uw2iZjW1MNN4IJUT5y/YSg+ZJ+3HqBB6SgzOOqY0N3fATsPeGuN9EqSfVnqvnIrJMS8mI0b5FzQ==", + "requires": { + "@algolia/client-common": "4.6.0", + "@algolia/client-search": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "@algolia/client-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.6.0.tgz", + "integrity": "sha512-60jK0LK5H+6q6HyyMyoBBD0fIs8zZzJt6BiyJGQG90o3gUV/SnjiNxO9Bx0RRlqdkE5s0OYFu1L7P9Y5TX7oAw==", + "requires": { + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "@algolia/client-recommendation": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-recommendation/-/client-recommendation-4.6.0.tgz", + "integrity": "sha512-j+Yb1z5QeIRDCCO+9hS9oZS3KNqRogPHDbJJsLTt6pkrs4CG2UVLVV67M977B1nzJ9OzaEki3VbpGQhRhPGNfQ==", + "requires": { + "@algolia/client-common": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "@algolia/client-search": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.6.0.tgz", + "integrity": "sha512-+qA1NA88YnXvuCKifegfgts1RQs8IzcwccQqyurz8ins4hypZL1tXN2BkrOqqDIgvYIrUvFyhv+gLO6U9PpDUA==", + "requires": { + "@algolia/client-common": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, + "@algolia/logger-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.6.0.tgz", + "integrity": "sha512-F+0HTGSQzJfWsX/cJq2l4eG2Y5JA6pqZ0YETyo5XJhZX4JaDrGszVKuOqp8kovZF/Ifebywxb8JdCiSUskmbig==" + }, + "@algolia/logger-console": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.6.0.tgz", + "integrity": "sha512-ers7OhfU6qBQl6s7MOe5gNUkcpa7LGrhEzDWnD0cUwLSd5BvWt7zEN69O2CZVbvAUZYlZ5zJTzMMa49s0VXrKQ==", + "requires": { + "@algolia/logger-common": "4.6.0" + } + }, + "@algolia/requester-browser-xhr": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.6.0.tgz", + "integrity": "sha512-ugrJT25VUkoKrl5vJVFclMdogbhTiDZ38Gss4xfTiSsP/SGE/0ei5VEOMEcj/bjkurJjPky1HfJZ3ykJhIsfCA==", + "requires": { + "@algolia/requester-common": "4.6.0" + } + }, + "@algolia/requester-common": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.6.0.tgz", + "integrity": "sha512-DJ5iIGBGrRudimaaFnpBFM19pv8SsXiMYuukn9q1GgQh2mPPBCBBJiezKc7+OzE1UyCVrAFBpR/hrJnflZnRdQ==" + }, + "@algolia/requester-node-http": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.6.0.tgz", + "integrity": "sha512-MPZK3oZz0jSBsqrGiPxv7LOKMUNknlaRNyRDy0v/ASIYG+GvLhGTdEzG5Eyw5tgSvBr8CWrWM5tDC31EH40Ndw==", + "requires": { + "@algolia/requester-common": "4.6.0" + } + }, + "@algolia/transporter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.6.0.tgz", + "integrity": "sha512-xp+HI8sB8gLCvP00scaOVPQEk5H7nboWUxrwLKyVUvtUO4o003bOfFPsH86NRyu5Dv7fzX9b8EH3rVxcLOhjqg==", + "requires": { + "@algolia/cache-common": "4.6.0", + "@algolia/logger-common": "4.6.0", + "@algolia/requester-common": "4.6.0" + } + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -23843,6 +24095,27 @@ "dev": true, "requires": {} }, + "algoliasearch": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.6.0.tgz", + "integrity": "sha512-f4QVfUYnWIGZwOupZh0RAqW8zEfpZAcZG6ZT0p6wDMztEyKBrjjbTXBk9p9uEaJqoIhFUm6TtApOxodTdHbqvw==", + "requires": { + "@algolia/cache-browser-local-storage": "4.6.0", + "@algolia/cache-common": "4.6.0", + "@algolia/cache-in-memory": "4.6.0", + "@algolia/client-account": "4.6.0", + "@algolia/client-analytics": "4.6.0", + "@algolia/client-common": "4.6.0", + "@algolia/client-recommendation": "4.6.0", + "@algolia/client-search": "4.6.0", + "@algolia/logger-common": "4.6.0", + "@algolia/logger-console": "4.6.0", + "@algolia/requester-browser-xhr": "4.6.0", + "@algolia/requester-common": "4.6.0", + "@algolia/requester-node-http": "4.6.0", + "@algolia/transporter": "4.6.0" + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", diff --git a/package.json b/package.json index 620198b..d603f1f 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "@fortawesome/free-regular-svg-icons": "5.15.4", "@fortawesome/free-solid-svg-icons": "5.15.4", "@fortawesome/react-fontawesome": "0.2.0", + "algoliasearch": "4.6.0", "classnames": "2.3.2", "core-js": "3.27.2", "lodash.camelcase": "4.3.0", diff --git a/src/index.jsx b/src/index.jsx index 951014b..7705089 100755 --- a/src/index.jsx +++ b/src/index.jsx @@ -68,6 +68,10 @@ initialize({ COLLECT_YEAR_OF_BIRTH: process.env.COLLECT_YEAR_OF_BIRTH, ENABLE_SKILLS_BUILDER: process.env.ENABLE_SKILLS_BUILDER, ENABLE_SKILLS_BUILDER_PROFILE: process.env.ENABLE_SKILLS_BUILDER_PROFILE, + ALGOLIA_APP_ID: process.env.ALGOLIA_APP_ID || null, + ALGOLIA_JOBS_INDEX_NAME: process.env.ALGOLIA_JOBS_INDEX_NAME || null, + ALGOLIA_PRODUCT_INDEX_NAME: process.env.ALGOLIA_PRODUCT_INDEX_NAME || null, + ALGOLIA_SEARCH_API_KEY: process.env.ALGOLIA_SEARCH_API_KEY || null, }, 'App loadConfig override handler'); }, }, diff --git a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx index 0bcd7d6..13bf2eb 100644 --- a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx +++ b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx @@ -16,14 +16,19 @@ import { SkillsBuilderHeader } from '../skills-builder-header'; import headerImage from '../images/headerImage.png'; +import { useAlgoliaSearch } from '../utils/hooks'; + const SkillsBuilderModal = () => { + const [state, dispatch] = useContext(SkillsBuilderContext); + const [learnerGoal, setLearnerGoal] = useState(''); + // TODO: Temporarily disable the no-unused-vars check, we'll see these later + // eslint-disable-next-line no-unused-vars + const [algoliaClient, productSearchIndex, jobSearchIndex] = useAlgoliaSearch(); + const onCloseHandle = () => { window.history.back(); }; - const [state, dispatch] = useContext(SkillsBuilderContext); - const [learnerGoal, setLearnerGoal] = useState(''); - return ( { + const config = getConfig(); + + const [searchClient, productSearchIndex, jobSearchIndex] = useMemo( + () => { + const client = algoliasearch( + config.ALGOLIA_APP_ID, + config.ALGOLIA_SEARCH_API_KEY, + ); + const productIndex = client.initIndex(config.ALGOLIA_PRODUCT_INDEX_NAME); + const jobIndex = client.initIndex(config.ALGOLIA_JOBS_INDEX_NAME); + return [client, productIndex, jobIndex]; + }, + [ + config.ALGOLIA_APP_ID, + config.ALGOLIA_PRODUCT_INDEX_NAME, + config.ALGOLIA_JOBS_INDEX_NAME, + config.ALGOLIA_SEARCH_API_KEY, + ], + ); + return [searchClient, productSearchIndex, jobSearchIndex]; +}; From 8f42e6fbfbed8a4c3dc5c2cefe4a2f588ba11c82 Mon Sep 17 00:00:00 2001 From: Maxwell Frank Date: Wed, 1 Feb 2023 21:46:44 +0000 Subject: [PATCH 03/63] feat: adding actions and reducer --- src/skills-builder/data/actions.js | 19 ++- src/skills-builder/data/constants.js | 7 +- src/skills-builder/data/reducer.js | 20 +++ src/skills-builder/data/test/reducer.test.js | 52 ++++++- .../SelectPreferences.jsx | 63 +++++++++ .../SkillsBuilderModal.jsx | 128 ++++++++++-------- .../skills-builder-modal/ViewResults.jsx | 7 + .../skills-builder-modal/messages.js | 5 + 8 files changed, 236 insertions(+), 65 deletions(-) create mode 100644 src/skills-builder/skills-builder-modal/SelectPreferences.jsx create mode 100644 src/skills-builder/skills-builder-modal/ViewResults.jsx diff --git a/src/skills-builder/data/actions.js b/src/skills-builder/data/actions.js index a77db82..b4df8c9 100644 --- a/src/skills-builder/data/actions.js +++ b/src/skills-builder/data/actions.js @@ -1,9 +1,26 @@ import { SET_GOAL, + SET_CURRENT_JOB_TITLE, + ADD_CAREER_INTEREST, + REMOVE_CAREER_INTEREEST, } from './constants'; -// eslint-disable-next-line import/prefer-default-export export const setGoal = (payload) => ({ type: SET_GOAL, payload, }); + +export const setCurrentJobTitle = (payload) => ({ + type: SET_CURRENT_JOB_TITLE, + payload, +}); + +export const addCareerInterest = (payload) => ({ + type: ADD_CAREER_INTEREST, + payload, +}); + +export const removeCareerInterest = (payload) => ({ + type: REMOVE_CAREER_INTEREEST, + payload, +}); diff --git a/src/skills-builder/data/constants.js b/src/skills-builder/data/constants.js index fcd3d81..5d801c6 100644 --- a/src/skills-builder/data/constants.js +++ b/src/skills-builder/data/constants.js @@ -1,2 +1,7 @@ -// eslint-disable-next-line import/prefer-default-export export const SET_GOAL = 'SET_GOAL'; +export const SET_CURRENT_JOB_TITLE = 'SET_CURRENT_JOB_TITLE'; +export const ADD_CAREER_INTEREST = 'ADD_CAREER_INTEREST'; +export const REMOVE_CAREER_INTEREEST = 'REMOVE_CAREER_INTEREEST'; + +export const STEP1 = 'select-your-preferences'; +export const STEP2 = 'review-your-results'; diff --git a/src/skills-builder/data/reducer.js b/src/skills-builder/data/reducer.js index 0db2ae5..6f6af67 100644 --- a/src/skills-builder/data/reducer.js +++ b/src/skills-builder/data/reducer.js @@ -1,5 +1,8 @@ import { SET_GOAL, + SET_CURRENT_JOB_TITLE, + ADD_CAREER_INTEREST, + REMOVE_CAREER_INTEREEST, } from './constants'; export function skillsReducer(state, action) { @@ -9,6 +12,21 @@ export function skillsReducer(state, action) { ...state, currentGoal: action.payload, }; + case SET_CURRENT_JOB_TITLE: + return { + ...state, + currentJobTitle: action.payload, + }; + case ADD_CAREER_INTEREST: + return { + ...state, + careerInterests: [...state.careerInterests, action.payload], + }; + case REMOVE_CAREER_INTEREEST: + return { + ...state, + careerInterests: state.careerInterests.filter(interest => interest !== action.payload), + }; default: return state; } @@ -16,6 +34,8 @@ export function skillsReducer(state, action) { export const skillsInitialState = { currentGoal: '', + currentJobTitle: '', + careerInterests: [], }; export default skillsReducer; diff --git a/src/skills-builder/data/test/reducer.test.js b/src/skills-builder/data/test/reducer.test.js index 4f537fe..0cfbb3c 100644 --- a/src/skills-builder/data/test/reducer.test.js +++ b/src/skills-builder/data/test/reducer.test.js @@ -1,20 +1,60 @@ -import { skillsReducer } from '../reducer'; +import { skillsReducer, skillsInitialState } from '../reducer'; import { SET_GOAL, + SET_CURRENT_JOB_TITLE, + ADD_CAREER_INTEREST, + REMOVE_CAREER_INTEREEST, } from '../constants'; describe('skillsReducer', () => { - const testState = { - currentGoal: '', - }; + const testState = skillsInitialState; + beforeEach(() => jest.resetModules()); it('does not remove present data when SET_GOAL action is dispatched', () => { - const newSkillsPayload = 'test-goal'; - const returnedState = skillsReducer(testState, { type: SET_GOAL, payload: newSkillsPayload }); + const newGoalPayload = 'test-goal'; + const returnedState = skillsReducer(testState, { type: SET_GOAL, payload: newGoalPayload }); const finalState = { ...testState, currentGoal: 'test-goal', }; expect(returnedState).toEqual(finalState); }); + + it('does not remove present data when SET_JOB_TITLE action is dispatched', () => { + const newJobTitlePayload = 'test-job-title'; + const returnedState = skillsReducer(testState, { type: SET_CURRENT_JOB_TITLE, payload: newJobTitlePayload }); + const finalState = { + ...testState, + currentJobTitle: 'test-job-title', + }; + expect(returnedState).toEqual(finalState); + }); + + it('adds a careerInterest when ADD_CAREER_INTEREST action is dispatched', () => { + const newCareerInterestPayload = 'test-career-interest'; + const returnedState = skillsReducer(testState, { type: ADD_CAREER_INTEREST, payload: newCareerInterestPayload }); + const finalState = { + ...testState, + careerInterests: [...testState.careerInterests, 'test-career-interest'], + }; + expect(returnedState).toEqual(finalState); + }); + + it('removes a careerInterest when REMOVE_CAREER_INTEREST action is dispatched', () => { + const newCareerInterestPayload = 'test-career-interest'; + const testStateWithInterest = { + ...testState, + careerInterests: [newCareerInterestPayload], + }; + const returnedState = skillsReducer( + testStateWithInterest, + { type: REMOVE_CAREER_INTEREEST, payload: newCareerInterestPayload }, + ); + const finalState = { + ...testStateWithInterest, + // override the 'careerInterests` field and remove 'test-career-interest' from the array + careerInterests: testStateWithInterest.careerInterests.filter(interest => interest !== newCareerInterestPayload), + }; + expect(returnedState).toEqual(finalState); + }); }); diff --git a/src/skills-builder/skills-builder-modal/SelectPreferences.jsx b/src/skills-builder/skills-builder-modal/SelectPreferences.jsx new file mode 100644 index 0000000..d51ccf5 --- /dev/null +++ b/src/skills-builder/skills-builder-modal/SelectPreferences.jsx @@ -0,0 +1,63 @@ +import React, { useContext } from 'react'; +import { + Button, +} from '@edx/paragon'; +import { + setGoal, + setCurrentJobTitle, + addCareerInterest, + removeCareerInterest, +} from '../data/actions'; +import { SkillsBuilderContext } from '../skills-builder-context'; +import { useAlgoliaSearch } from '../utils/hooks'; + +const SelectPreferences = () => { + // TODO: Temporarily disable the no-unused-vars check, we'll see these later + // eslint-disable-next-line no-unused-vars + const [algoliaClient, productSearchIndex, jobSearchIndex] = useAlgoliaSearch(); + const [{ currentGoal, currentJobTitle, careerInterests }, dispatch] = useContext(SkillsBuilderContext); + + return ( + <> +
+

Render Question 1

+ +

Goal: {currentGoal}

+
+ + {currentGoal && ( +
+

Render question 2

+ +

Current Job Title: {currentJobTitle}

+
+ )} + + {currentJobTitle && ( +
+

Render Question 3

+ +

+ Career Interests (click to remove): + {careerInterests.map(interest => ( + + ))} +

+
+ )} + + ); +}; + +export default SelectPreferences; diff --git a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx index 13bf2eb..eaee071 100644 --- a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx +++ b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx @@ -1,79 +1,93 @@ -import React, { useContext, useState } from 'react'; +import React, { useState, useContext } from 'react'; import { - ActionRow, Button, Container, - Form, + Stepper, ModalDialog, } from '@edx/paragon'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { useHistory } from 'react-router'; import { - setGoal, -} from '../data/actions'; + STEP1, + STEP2, +} from '../data/constants'; import messages from './messages'; + import { SkillsBuilderContext } from '../skills-builder-context'; import { SkillsBuilderHeader } from '../skills-builder-header'; +import SelectPreferences from './SelectPreferences'; +import ViewResults from './ViewResults'; import headerImage from '../images/headerImage.png'; -import { useAlgoliaSearch } from '../utils/hooks'; - const SkillsBuilderModal = () => { - const [state, dispatch] = useContext(SkillsBuilderContext); - const [learnerGoal, setLearnerGoal] = useState(''); - // TODO: Temporarily disable the no-unused-vars check, we'll see these later - // eslint-disable-next-line no-unused-vars - const [algoliaClient, productSearchIndex, jobSearchIndex] = useAlgoliaSearch(); + const [{ careerInterests }] = useContext(SkillsBuilderContext); + const [currentStep, setCurrentStep] = useState(STEP1); + + const history = useHistory(); const onCloseHandle = () => { - window.history.back(); + history.goBack(); }; return ( - - - - - - - - - - - -

Your current goal: {state.currentGoal}

-
- - setLearnerGoal(e.target.value)} - /> - - -
-
- - - - - - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); }; diff --git a/src/skills-builder/skills-builder-modal/ViewResults.jsx b/src/skills-builder/skills-builder-modal/ViewResults.jsx new file mode 100644 index 0000000..3477aeb --- /dev/null +++ b/src/skills-builder/skills-builder-modal/ViewResults.jsx @@ -0,0 +1,7 @@ +import React from 'react'; + +const ViewResults = () => ( +

Results will render on this step

+); + +export default ViewResults; diff --git a/src/skills-builder/skills-builder-modal/messages.js b/src/skills-builder/skills-builder-modal/messages.js index a4f053e..6938a8c 100644 --- a/src/skills-builder/skills-builder-modal/messages.js +++ b/src/skills-builder/skills-builder-modal/messages.js @@ -12,6 +12,11 @@ const messages = defineMessages({ defaultMessage: 'Next Step', description: 'Button that sends the user to the next step in the skills builder.', }, + exitButton: { + id: 'exit.button', + defaultMessage: 'Exit', + description: 'Button that exits the Skills Builder.', + }, }); export default messages; From 10f93420f43f2623756487992a56cbe93af286c1 Mon Sep 17 00:00:00 2001 From: Justin Hynes Date: Thu, 16 Feb 2023 09:39:17 -0500 Subject: [PATCH 04/63] feat: Add utility functions for querying job related data from Algolia [APER-2261] * rename `hooks.jsx` to `search.jsx` as this is more of a collection of utilities for working with Algolia * add a utiltiy function for returning job info (from our "job" Algolia index) based on a list of jobs a learner is interested in * add a utility function for formatting job names based on the syntax Algolia expects --- .../SelectPreferences.jsx | 2 +- src/skills-builder/utils/hooks.jsx | 28 ------- src/skills-builder/utils/search.jsx | 84 +++++++++++++++++++ .../utils/tests/search.test.jsx | 16 ++++ 4 files changed, 101 insertions(+), 29 deletions(-) delete mode 100644 src/skills-builder/utils/hooks.jsx create mode 100644 src/skills-builder/utils/search.jsx create mode 100644 src/skills-builder/utils/tests/search.test.jsx diff --git a/src/skills-builder/skills-builder-modal/SelectPreferences.jsx b/src/skills-builder/skills-builder-modal/SelectPreferences.jsx index d51ccf5..43320d1 100644 --- a/src/skills-builder/skills-builder-modal/SelectPreferences.jsx +++ b/src/skills-builder/skills-builder-modal/SelectPreferences.jsx @@ -9,7 +9,7 @@ import { removeCareerInterest, } from '../data/actions'; import { SkillsBuilderContext } from '../skills-builder-context'; -import { useAlgoliaSearch } from '../utils/hooks'; +import { useAlgoliaSearch } from '../utils/search'; const SelectPreferences = () => { // TODO: Temporarily disable the no-unused-vars check, we'll see these later diff --git a/src/skills-builder/utils/hooks.jsx b/src/skills-builder/utils/hooks.jsx deleted file mode 100644 index d504a75..0000000 --- a/src/skills-builder/utils/hooks.jsx +++ /dev/null @@ -1,28 +0,0 @@ -import { useMemo } from 'react'; -import { getConfig } from '@edx/frontend-platform'; - -import algoliasearch from 'algoliasearch'; - -// eslint-disable-next-line import/prefer-default-export -export const useAlgoliaSearch = () => { - const config = getConfig(); - - const [searchClient, productSearchIndex, jobSearchIndex] = useMemo( - () => { - const client = algoliasearch( - config.ALGOLIA_APP_ID, - config.ALGOLIA_SEARCH_API_KEY, - ); - const productIndex = client.initIndex(config.ALGOLIA_PRODUCT_INDEX_NAME); - const jobIndex = client.initIndex(config.ALGOLIA_JOBS_INDEX_NAME); - return [client, productIndex, jobIndex]; - }, - [ - config.ALGOLIA_APP_ID, - config.ALGOLIA_PRODUCT_INDEX_NAME, - config.ALGOLIA_JOBS_INDEX_NAME, - config.ALGOLIA_SEARCH_API_KEY, - ], - ); - return [searchClient, productSearchIndex, jobSearchIndex]; -}; diff --git a/src/skills-builder/utils/search.jsx b/src/skills-builder/utils/search.jsx new file mode 100644 index 0000000..1c4fa57 --- /dev/null +++ b/src/skills-builder/utils/search.jsx @@ -0,0 +1,84 @@ +/* +Algolia utility functions used by the Skills Builder feature. +*/ +import { useMemo } from 'react'; +import { getConfig } from '@edx/frontend-platform'; +import { logError } from '@edx/frontend-platform/logging'; + +import algoliasearch from 'algoliasearch'; + +/* + * Utility function to create and return an Algolia client, as well as Index objects for our product and job data. + * + * @return {SearchClient} searchClient - An instantiated Algolia client + * @return {SearchIndex} productSearchIndex - An Algolia index of product data. Used to retrieve product + * recommendations for learners + * @return {SearchIndex} jobSearchIndex - An Algolia index of job taxonomy data. Used to retrieve job metadata that a + * learner is interested in. + */ +// eslint-disable-next-line import/prefer-default-export +export const useAlgoliaSearch = () => { + const config = getConfig(); + + const [searchClient, productSearchIndex, jobSearchIndex] = useMemo( + () => { + const client = algoliasearch( + config.ALGOLIA_APP_ID, + config.ALGOLIA_SEARCH_API_KEY, + ); + const productIndex = client.initIndex(config.ALGOLIA_PRODUCT_INDEX_NAME); + const jobIndex = client.initIndex(config.ALGOLIA_JOBS_INDEX_NAME); + return [client, productIndex, jobIndex]; + }, + [ + config.ALGOLIA_APP_ID, + config.ALGOLIA_PRODUCT_INDEX_NAME, + config.ALGOLIA_JOBS_INDEX_NAME, + config.ALGOLIA_SEARCH_API_KEY, + ], + ); + return [searchClient, productSearchIndex, jobSearchIndex]; +}; + +/* + * Utility function used to reformat incoming job names to match the syntax Algolia expects when querying index data. + * + * @param {Array[String]} jobNames - A list of job names a learner is interested in + * + * @return formattedJobNames - The transformed array of job names + */ +export function formatJobNames(jobNames) { + const formattedJobNames = []; + if (jobNames) { + jobNames.forEach(job => formattedJobNames.push(`name:${job}`)); + } + return formattedJobNames; +} + +/* + * Utility function responsible for querying and returning job information based on input received from a learner. + * + * @param {SearchIndex} jobIndex - An Algolia index of job taxonomy data. Used to retrieve job metadata that a + * learner is interested in. + * @param {Array[String]} jobNames - A list of job names a learner is interested in + * + * @return Job information retrieved from Algolia + */ +export const searchJobs = async (jobSearchIndex, jobNames) => { + let results = null; + + const formattedJobNames = formatJobNames(jobNames); + try { + const { hits } = await jobSearchIndex.search('', { + facetFilters: [ + formattedJobNames, + ], + }); + results = hits; + } catch (error) { + logError(error); + results = []; + } + + return results; +}; diff --git a/src/skills-builder/utils/tests/search.test.jsx b/src/skills-builder/utils/tests/search.test.jsx new file mode 100644 index 0000000..e995aa0 --- /dev/null +++ b/src/skills-builder/utils/tests/search.test.jsx @@ -0,0 +1,16 @@ +import { formatJobNames, searchJobs } from '../search'; + +jest.mock('@edx/frontend-platform/logging'); + +describe('Algolias utility function', () => { + it('formatJobNames() should return a new array with data formatted as expected', () => { + const jobNameArray = ['Organic Farmer']; + const result = formatJobNames(jobNameArray); + expect(result).toEqual(['name:Organic Farmer']); + }); + + it('searchJobs() returns an empty array when an exception occurs querying Algolia', async () => { + const results = await searchJobs(null, ['name:Organic Farmer']); + expect(results).toEqual([]); + }); +}); From 20159f140e42c06d52169f0c89cf4102281c807e Mon Sep 17 00:00:00 2001 From: Jenkins Date: Sun, 19 Feb 2023 20:35:17 +0000 Subject: [PATCH 05/63] chore(i18n): update translations --- src/i18n/messages/ar.json | 3 ++- src/i18n/messages/de.json | 3 ++- src/i18n/messages/es_419.json | 17 +++++++++-------- src/i18n/messages/fr.json | 3 ++- src/i18n/messages/fr_CA.json | 3 ++- src/i18n/messages/hi.json | 3 ++- src/i18n/messages/it.json | 3 ++- src/i18n/messages/pt.json | 3 ++- src/i18n/messages/ru.json | 3 ++- src/i18n/messages/uk.json | 3 ++- src/i18n/messages/zh_CN.json | 3 ++- 11 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index 43296ce..b2364e8 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 86e3525..4d3f107 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/es_419.json b/src/i18n/messages/es_419.json index b8d7baf..a92f302 100644 --- a/src/i18n/messages/es_419.json +++ b/src/i18n/messages/es_419.json @@ -34,11 +34,11 @@ "profile.formcontrols.button.saved": "Guardado", "profile.visibility.who.just.me": "Solo yo", "profile.visibility.who.everyone": "Todos en {siteName}", - "profile.learningGoal.learningGoal": "Learning Goal", - "profile.learningGoal.options.start_career": "I want to start my career", - "profile.learningGoal.options.advance_career": "I want to advance my career", - "profile.learningGoal.options.learn_something_new": "I want to learn something new", - "profile.learningGoal.options.something_else": "Something else", + "profile.learningGoal.learningGoal": "Objetivo de aprendizaje", + "profile.learningGoal.options.start_career": "quiero empezar mi carrera", + "profile.learningGoal.options.advance_career": "Quiero avanzar en mi carrera", + "profile.learningGoal.options.learn_something_new": "quiero aprender algo nuevo", + "profile.learningGoal.options.something_else": "Algo más", "profile.name.full.name": "Nombre completo", "profile.name.details": "Este es el nombre que aparecerá en tu cuenta y en tus certificados.", "profile.name.empty": "Añade nombre", @@ -54,8 +54,9 @@ "profile.viewMyRecords": "Ver mis registros", "profile.loading": "Cargando perfil...", "profile.username.description": "La información del perfil solo la visualiza usted. Solo el nombre de usuario es visible para los demás en {siteName}.", - "skills.builder.header.title": "Skills Builder", - "skills.builder.header.subheading": "Let edX be your guide", + "skills.builder.header.title": "Constructor de habilidades", + "skills.builder.header.subheading": "Dejanos ser tu guía", "go.back.button": "Volver Atrás", - "next.step.button": "Próximo paso" + "next.step.button": "Próximo paso", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index 1230b86..0010d52 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/fr_CA.json b/src/i18n/messages/fr_CA.json index e065bdb..b81f326 100644 --- a/src/i18n/messages/fr_CA.json +++ b/src/i18n/messages/fr_CA.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Constructeur de compétences", "skills.builder.header.subheading": "Laissez EDUlib être votre guide", "go.back.button": "Retour", - "next.step.button": "Prochaine étape" + "next.step.button": "Prochaine étape", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/hi.json b/src/i18n/messages/hi.json index 86e3525..4d3f107 100644 --- a/src/i18n/messages/hi.json +++ b/src/i18n/messages/hi.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/it.json b/src/i18n/messages/it.json index 86e3525..4d3f107 100644 --- a/src/i18n/messages/it.json +++ b/src/i18n/messages/it.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index 86e3525..4d3f107 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index 86e3525..4d3f107 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/uk.json b/src/i18n/messages/uk.json index 86e3525..4d3f107 100644 --- a/src/i18n/messages/uk.json +++ b/src/i18n/messages/uk.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file diff --git a/src/i18n/messages/zh_CN.json b/src/i18n/messages/zh_CN.json index 86e3525..4d3f107 100644 --- a/src/i18n/messages/zh_CN.json +++ b/src/i18n/messages/zh_CN.json @@ -57,5 +57,6 @@ "skills.builder.header.title": "Skills Builder", "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", - "next.step.button": "Next Step" + "next.step.button": "Next Step", + "exit.button": "Exit" } \ No newline at end of file From 8e0ab6db4d38e9aefe90b7e4e24d66cdf019ffb9 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 23 Feb 2023 14:01:48 -0500 Subject: [PATCH 06/63] build: Creating a missing workflow file `self-assign-issue.yml`. The .github/workflows/self-assign-issue.yml workflow is missing or needs an update to stay in sync with the current standard for this workflow as defined in the `.github` repo of the `openedx` GitHub org. --- .github/workflows/self-assign-issue.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .github/workflows/self-assign-issue.yml diff --git a/.github/workflows/self-assign-issue.yml b/.github/workflows/self-assign-issue.yml new file mode 100644 index 0000000..37522fd --- /dev/null +++ b/.github/workflows/self-assign-issue.yml @@ -0,0 +1,12 @@ +# This workflow runs when a comment is made on the ticket +# If the comment starts with "assign me" it assigns the author to the +# ticket (case insensitive) + +name: Assign comment author to ticket if they say "assign me" +on: + issue_comment: + types: [created] + +jobs: + self_assign_by_comment: + uses: openedx/.github/.github/workflows/self-assign-issue.yml@master From 47c06c0f5df2b4d7b4f296df5b45be04a69a8bc0 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 23 Feb 2023 14:01:49 -0500 Subject: [PATCH 07/63] build: Creating a missing workflow file `add-remove-label-on-comment.yml`. The .github/workflows/add-remove-label-on-comment.yml workflow is missing or needs an update to stay in sync with the current standard for this workflow as defined in the `.github` repo of the `openedx` GitHub org. --- .../workflows/add-remove-label-on-comment.yml | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/workflows/add-remove-label-on-comment.yml diff --git a/.github/workflows/add-remove-label-on-comment.yml b/.github/workflows/add-remove-label-on-comment.yml new file mode 100644 index 0000000..0f369db --- /dev/null +++ b/.github/workflows/add-remove-label-on-comment.yml @@ -0,0 +1,20 @@ +# This workflow runs when a comment is made on the ticket +# If the comment starts with "label: " it tries to apply +# the label indicated in rest of comment. +# If the comment starts with "remove label: ", it tries +# to remove the indicated label. +# Note: Labels are allowed to have spaces and this script does +# not parse spaces (as often a space is legitimate), so the command +# "label: really long lots of words label" will apply the +# label "really long lots of words label" + +name: Allows for the adding and removing of labels via comment + +on: + issue_comment: + types: [created] + +jobs: + add_remove_labels: + uses: openedx/.github/.github/workflows/add-remove-label-on-comment.yml@master + From 75ea8bc207ff36c8528b3636cfb722da6052c891 Mon Sep 17 00:00:00 2001 From: Feanil Patel Date: Thu, 23 Feb 2023 14:01:50 -0500 Subject: [PATCH 08/63] build: Updating a missing workflow file `add-depr-ticket-to-depr-board.yml`. The .github/workflows/add-depr-ticket-to-depr-board.yml workflow is missing or needs an update to stay in sync with the current standard for this workflow as defined in the `.github` repo of the `openedx` GitHub org. --- .github/workflows/add-depr-ticket-to-depr-board.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/add-depr-ticket-to-depr-board.yml b/.github/workflows/add-depr-ticket-to-depr-board.yml index 73ca4c5..250e394 100644 --- a/.github/workflows/add-depr-ticket-to-depr-board.yml +++ b/.github/workflows/add-depr-ticket-to-depr-board.yml @@ -16,4 +16,4 @@ jobs: secrets: GITHUB_APP_ID: ${{ secrets.GRAPHQL_AUTH_APP_ID }} GITHUB_APP_PRIVATE_KEY: ${{ secrets.GRAPHQL_AUTH_APP_PEM }} - SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }} \ No newline at end of file + SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }} From 0c427cf5e37a704e7f1cffabfa239053ed6f3da8 Mon Sep 17 00:00:00 2001 From: edX requirements bot <49161187+edx-requirements-bot@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:44:15 -0500 Subject: [PATCH 09/63] chore: update browserslist DB (#656) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6e503ae..87d3f99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6432,9 +6432,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001448", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz", - "integrity": "sha512-tq2YI+MJnooG96XpbTRYkBxLxklZPOdLmNIOdIhvf7SNJan6u5vCKum8iT7ZfCt70m1GPkuC7P3TtX6UuhupuA==", + "version": "1.0.30001456", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001456.tgz", + "integrity": "sha512-XFHJY5dUgmpMV25UqaD4kVq2LsiaU5rS8fb0f17pCoXQiQslzmFgnfOxfvo1bTpTqf7dwG/N/05CnLCnOEKmzA==", "dev": true, "funding": [ { @@ -24939,9 +24939,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001448", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001448.tgz", - "integrity": "sha512-tq2YI+MJnooG96XpbTRYkBxLxklZPOdLmNIOdIhvf7SNJan6u5vCKum8iT7ZfCt70m1GPkuC7P3TtX6UuhupuA==", + "version": "1.0.30001456", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001456.tgz", + "integrity": "sha512-XFHJY5dUgmpMV25UqaD4kVq2LsiaU5rS8fb0f17pCoXQiQslzmFgnfOxfvo1bTpTqf7dwG/N/05CnLCnOEKmzA==", "dev": true }, "capture-exit": { From a6086fd4bfcc7bfdb7cd2cf019b8473d97d90fcf Mon Sep 17 00:00:00 2001 From: Justin Hynes Date: Thu, 23 Feb 2023 08:41:34 -0500 Subject: [PATCH 10/63] feat: add utility function to retrieve product recommendations based on job skills [APER-2262] - add a utility function to retrieve product recommendations based on skills from a job a learner is interested in - add additional tests and coverage around new utility functions in `search.jsx` --- src/skills-builder/utils/search.jsx | 64 +++++++++++------ .../utils/tests/search.test.jsx | 68 +++++++++++++++++-- 2 files changed, 108 insertions(+), 24 deletions(-) diff --git a/src/skills-builder/utils/search.jsx b/src/skills-builder/utils/search.jsx index 1c4fa57..0e4d0ac 100644 --- a/src/skills-builder/utils/search.jsx +++ b/src/skills-builder/utils/search.jsx @@ -41,44 +41,70 @@ export const useAlgoliaSearch = () => { }; /* - * Utility function used to reformat incoming job names to match the syntax Algolia expects when querying index data. + * Utility function used to format a list of data so it matches syntax Algolia expects. * - * @param {Array[String]} jobNames - A list of job names a learner is interested in + * @param {String} facetFilterType - A string declaring the facet filter type to prepend each search item (e.g. `name`) + * @param {Array[String]} data - An array of job or skills used to query data in Algolia. * - * @return formattedJobNames - The transformed array of job names + * @return {Array[String]} formattedData - The transformed array of data to search prepended with the facet filter type */ -export function formatJobNames(jobNames) { - const formattedJobNames = []; - if (jobNames) { - jobNames.forEach(job => formattedJobNames.push(`name:${job}`)); +export function formatFacetFilterData(facetFilterType, data) { + const formattedData = []; + if (data) { + data.forEach(item => formattedData.push(`${facetFilterType}:${item}`)); } - return formattedJobNames; + + return formattedData; } /* * Utility function responsible for querying and returning job information based on input received from a learner. * - * @param {SearchIndex} jobIndex - An Algolia index of job taxonomy data. Used to retrieve job metadata that a - * learner is interested in. + * @param {SearchIndex} jobIndex - An Algolia index of taxonomy connector data used to retrieve job information a + * learner is interested in * @param {Array[String]} jobNames - A list of job names a learner is interested in * - * @return Job information retrieved from Algolia + * @return {Array[Object]} results - Job information retrieved from Algolia */ -export const searchJobs = async (jobSearchIndex, jobNames) => { - let results = null; - - const formattedJobNames = formatJobNames(jobNames); +export const searchJobs = async (jobIndex, jobNames) => { + const formattedJobNames = formatFacetFilterData('name', jobNames); try { - const { hits } = await jobSearchIndex.search('', { + const { hits } = await jobIndex.search('', { facetFilters: [ formattedJobNames, ], }); - results = hits; + return hits; } catch (error) { logError(error); - results = []; } - return results; + return []; +}; + +/* + * Utility function responsible for returning recommendations on products based on the skills of a job a learner is + * interested in. + * + * @param {SearchIndex} productIndex - An Algolia index of product data used to retrieve recommendations for learners. + * @param {String} productType - The type of product information you are trying to retrieve (e.g. `course` or `program`) + * @param {Array[String]} skills - An array of skill names related to a job/career a learner expressed interest in + * + * @return {Array[Object]} results - Product information retrieved from Algolia + */ +export const getProductRecommendations = async (productIndex, productType, skills) => { + const formattedSkillNames = formatFacetFilterData('skills.skill', skills); + try { + const { hits } = await productIndex.search('', { + filters: `product:${productType}`, + facetFilters: [ + formattedSkillNames, + ], + }); + return hits; + } catch (error) { + logError(error); + } + + return []; }; diff --git a/src/skills-builder/utils/tests/search.test.jsx b/src/skills-builder/utils/tests/search.test.jsx index e995aa0..6fa20ca 100644 --- a/src/skills-builder/utils/tests/search.test.jsx +++ b/src/skills-builder/utils/tests/search.test.jsx @@ -1,16 +1,74 @@ -import { formatJobNames, searchJobs } from '../search'; +import { + formatFacetFilterData, + getProductRecommendations, + searchJobs, +} from '../search'; jest.mock('@edx/frontend-platform/logging'); +const mockAlgoliaResult = { + hits: [ + { + key: 'test-course-key', + title: 'Test Title', + skill_names: [ + { + id: 1, + name: 'Skill Name', + }, + ], + }, + ], +}; + +const mockIndex = { + search: jest.fn().mockImplementation(() => mockAlgoliaResult), +}; + describe('Algolias utility function', () => { - it('formatJobNames() should return a new array with data formatted as expected', () => { - const jobNameArray = ['Organic Farmer']; - const result = formatJobNames(jobNameArray); + afterEach(() => { + jest.clearAllMocks(); + }); + + it('formatFacetFilterData() should return a new array with data formatted as expected', () => { + const result = formatFacetFilterData('name', ['Organic Farmer']); expect(result).toEqual(['name:Organic Farmer']); }); + it('searchJobs() queries Algolia with the expected search parameters', async () => { + const expectedSearchParameters = { + facetFilters: [ + ['name:Enchanter'], + ], + }; + + const results = await searchJobs(mockIndex, ['Enchanter']); + expect(mockIndex.search).toHaveBeenCalledTimes(1); + expect(mockIndex.search).toHaveBeenCalledWith('', expectedSearchParameters); + expect(results).toEqual(mockAlgoliaResult.hits); + }); + it('searchJobs() returns an empty array when an exception occurs querying Algolia', async () => { - const results = await searchJobs(null, ['name:Organic Farmer']); + const results = await searchJobs(null, ['Organic Farmer']); + expect(results).toEqual([]); + }); + + it('getProductRecommendations() queries Algolia with the expected search parameters', async () => { + const expectedSearchParameters = { + filters: 'product:Course', + facetFilters: [ + ['skills.skill:Sword Lobbing'], + ], + }; + + const results = await getProductRecommendations(mockIndex, 'Course', ['Sword Lobbing']); + expect(mockIndex.search).toHaveBeenCalledTimes(1); + expect(mockIndex.search).toHaveBeenCalledWith('', expectedSearchParameters); + expect(results).toEqual(mockAlgoliaResult.hits); + }); + + it('getProductRecommendations() returns an empty array when an exception occurs querying Algolia', async () => { + const results = await getProductRecommendations(null, 'Course', ['Management']); expect(results).toEqual([]); }); }); From 68dc8a1045a64248febc874cf1adf60288fd1eee Mon Sep 17 00:00:00 2001 From: Maxwell Frank Date: Fri, 17 Feb 2023 20:00:36 +0000 Subject: [PATCH 11/63] feat: first two questions of Skills Builder --- package-lock.json | 326 +++++++++++++++++- package.json | 1 + src/skills-builder/data/constants.js | 2 + .../SkillsBuilderProvider.jsx | 14 +- .../SelectPreferences.jsx | 63 ---- .../SkillsBuilderModal.jsx | 28 +- .../skills-builder-modal/messages.js | 10 + .../CareerInterestSelect.jsx | 16 + .../select-preferences/GoalSelect.jsx | 38 ++ .../JobTitleInstantSearch.jsx | 39 +++ .../select-preferences/JobTitleSelect.jsx | 46 +++ .../select-preferences/SelectPreferences.jsx | 36 ++ .../select-preferences/index.js | 2 + .../select-preferences/messages.js | 66 ++++ .../{ => view-results}/ViewResults.jsx | 0 .../view-results/index.js | 2 + .../test/SkillsBuilder.test.jsx | 91 ++++- 17 files changed, 691 insertions(+), 89 deletions(-) delete mode 100644 src/skills-builder/skills-builder-modal/SelectPreferences.jsx create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/index.js create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/messages.js rename src/skills-builder/skills-builder-modal/{ => view-results}/ViewResults.jsx (100%) create mode 100644 src/skills-builder/skills-builder-modal/view-results/index.js diff --git a/package-lock.json b/package-lock.json index 87d3f99..dc4a7dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "react": "16.14.0", "react-dom": "16.14.0", "react-helmet": "6.1.0", + "react-instantsearch-hooks-web": "^6.40.1", "react-redux": "7.2.9", "react-router": "5.3.4", "react-router-dom": "5.3.4", @@ -129,6 +130,11 @@ "@algolia/transporter": "4.6.0" } }, + "node_modules/@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, "node_modules/@algolia/logger-common": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.6.0.tgz", @@ -173,6 +179,20 @@ "@algolia/requester-common": "4.6.0" } }, + "node_modules/@algolia/ui-components-highlight-vdom": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@algolia/ui-components-highlight-vdom/-/ui-components-highlight-vdom-1.2.1.tgz", + "integrity": "sha512-IlYgIaCUEkz9ezNbwugwKv991oOHhveyq6nzL0F1jDzg1p3q5Yj/vO4KpNG910r2dwGCG3nEm5GtChcLnarhFA==", + "dependencies": { + "@algolia/ui-components-shared": "1.2.1", + "@babel/runtime": "^7.0.0" + } + }, + "node_modules/@algolia/ui-components-shared": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@algolia/ui-components-shared/-/ui-components-shared-1.2.1.tgz", + "integrity": "sha512-a7mYHf/GVQfhAx/HRiMveKkFvHspQv/REdG+C/FIOosiSmNZxX7QebDwJkrGSmDWdXO12D0Qv1xn3AytFcEDlQ==" + }, "node_modules/@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -4496,6 +4516,11 @@ "version": "0.3.3", "license": "MIT" }, + "node_modules/@types/dom-speech-recognition": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.1.tgz", + "integrity": "sha512-udCxb8DvjcDKfk1WTBzDsxFbLgYxmQGKrE/ricoMqHRNjSlSUCcamVTA5lIQqzY10mY5qCY0QDwBfFEwhfoDPw==" + }, "node_modules/@types/eslint": { "version": "8.4.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", @@ -4564,6 +4589,11 @@ "@types/node": "*" } }, + "node_modules/@types/google.maps": { + "version": "3.52.0", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.52.0.tgz", + "integrity": "sha512-cIwkgSBUOCerEwEpAahg1SxUqqGV+D786TkVWrcZZyPvuCozmXFtzQcpOzvUXBtTUqDzEbCDGlAXDfDSYFXFIw==" + }, "node_modules/@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -4573,6 +4603,11 @@ "@types/node": "*" } }, + "node_modules/@types/hogan.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/hogan.js/-/hogan.js-3.0.1.tgz", + "integrity": "sha512-D03i/2OY7kGyMq9wdQ7oD8roE49z/ZCZThe/nbahtvuqCNZY9T2MfedOWyeBdbEpY2W8Gnh/dyJLdFtUCOkYbg==" + }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", "license": "MIT", @@ -4681,8 +4716,7 @@ "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "node_modules/@types/range-parser": { "version": "1.2.4", @@ -5071,6 +5105,11 @@ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -5298,6 +5337,17 @@ "@algolia/transporter": "4.6.0" } }, + "node_modules/algoliasearch-helper": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.11.3.tgz", + "integrity": "sha512-TbaEvLwiuGygHQIB8y+OsJKQQ40+JKUua5B91X66tMUHyyhbNHvqyr0lqd3wCoyKx7WybyQrC0WJvzoIeh24Aw==", + "dependencies": { + "@algolia/events": "^4.0.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -10334,6 +10384,27 @@ "value-equal": "^1.0.1" } }, + "node_modules/hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", + "dependencies": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "bin": { + "hulk": "bin/hulk" + } + }, + "node_modules/hogan.js/node_modules/mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "engines": { + "node": "*" + } + }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", "license": "BSD-3-Clause", @@ -10400,6 +10471,11 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/htm": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz", + "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==" + }, "node_modules/html-element-map": { "version": "1.3.1", "dev": true, @@ -10885,6 +10961,40 @@ "dev": true, "license": "ISC" }, + "node_modules/instantsearch.js": { + "version": "4.51.1", + "resolved": "https://registry.npmjs.org/instantsearch.js/-/instantsearch.js-4.51.1.tgz", + "integrity": "sha512-l4nETzassgSMBqOhNxntNH2MGG0KvFagwVwnXFis9P06nlspAyOdFLCQ0HA5wnlRDDev2WAZg9xRcTPCTLrwZw==", + "dependencies": { + "@algolia/events": "^4.0.1", + "@algolia/ui-components-highlight-vdom": "^1.2.1", + "@algolia/ui-components-shared": "^1.2.1", + "@types/dom-speech-recognition": "^0.0.1", + "@types/google.maps": "^3.45.3", + "@types/hogan.js": "^3.0.0", + "@types/qs": "^6.5.3", + "algoliasearch-helper": "^3.11.3", + "hogan.js": "^3.0.2", + "htm": "^3.0.0", + "preact": "^10.10.0", + "qs": "^6.5.1 < 6.10", + "search-insights": "^2.1.0" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 6" + } + }, + "node_modules/instantsearch.js/node_modules/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==", + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/internal-slot": { "version": "1.0.3", "dev": true, @@ -13524,6 +13634,20 @@ "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", "dev": true }, + "node_modules/nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "*" + } + }, "node_modules/normalize-package-data": { "version": "3.0.3", "dev": true, @@ -14920,6 +15044,15 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "node_modules/preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/prebuild-install": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", @@ -15502,6 +15635,36 @@ "react": ">=16.3.0" } }, + "node_modules/react-instantsearch-hooks": { + "version": "6.40.1", + "resolved": "https://registry.npmjs.org/react-instantsearch-hooks/-/react-instantsearch-hooks-6.40.1.tgz", + "integrity": "sha512-Nqbmencg5816UVDkWUFpGyurAhp8WUBQgHiYj/bTnYQ7KuwXbbxIppIwexZqzXG8Q3DKVBWZw4PnmJiStLK2CA==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "algoliasearch-helper": "^3.11.3", + "instantsearch.js": "4.51.1", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 5", + "react": ">= 16.8.0 < 19" + } + }, + "node_modules/react-instantsearch-hooks-web": { + "version": "6.40.1", + "resolved": "https://registry.npmjs.org/react-instantsearch-hooks-web/-/react-instantsearch-hooks-web-6.40.1.tgz", + "integrity": "sha512-MbsS1nhyZWPJjSVRzkDVmb0TM4L2kjHANsr0e1NDwkVWicP8LtXdX6UINDnekMKVnk1OmoF10NAJt4LmcSOqaA==", + "dependencies": { + "@babel/runtime": "^7.1.2", + "instantsearch.js": "4.51.1", + "react-instantsearch-hooks": "6.40.1" + }, + "peerDependencies": { + "algoliasearch": ">= 3.1 < 5", + "react": ">= 16.8.0 < 19", + "react-dom": ">= 16.8.0 < 19" + } + }, "node_modules/react-intl": { "version": "5.25.1", "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.25.1.tgz", @@ -16951,6 +17114,14 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/search-insights": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.3.0.tgz", + "integrity": "sha512-0v/TTO4fbd6I91sFBK/e2zNfD0f51A+fMoYNkMplmR77NpThUye/7gIxNoJ3LejKpZH6Z2KNBIpxxFmDKj10Yw==", + "engines": { + "node": ">=8.16.0" + } + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -19189,6 +19360,14 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "dev": true, @@ -20173,6 +20352,11 @@ "@algolia/transporter": "4.6.0" } }, + "@algolia/events": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", + "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + }, "@algolia/logger-common": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.6.0.tgz", @@ -20217,6 +20401,20 @@ "@algolia/requester-common": "4.6.0" } }, + "@algolia/ui-components-highlight-vdom": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@algolia/ui-components-highlight-vdom/-/ui-components-highlight-vdom-1.2.1.tgz", + "integrity": "sha512-IlYgIaCUEkz9ezNbwugwKv991oOHhveyq6nzL0F1jDzg1p3q5Yj/vO4KpNG910r2dwGCG3nEm5GtChcLnarhFA==", + "requires": { + "@algolia/ui-components-shared": "1.2.1", + "@babel/runtime": "^7.0.0" + } + }, + "@algolia/ui-components-shared": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@algolia/ui-components-shared/-/ui-components-shared-1.2.1.tgz", + "integrity": "sha512-a7mYHf/GVQfhAx/HRiMveKkFvHspQv/REdG+C/FIOosiSmNZxX7QebDwJkrGSmDWdXO12D0Qv1xn3AytFcEDlQ==" + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -23399,6 +23597,11 @@ "@types/cookie": { "version": "0.3.3" }, + "@types/dom-speech-recognition": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/@types/dom-speech-recognition/-/dom-speech-recognition-0.0.1.tgz", + "integrity": "sha512-udCxb8DvjcDKfk1WTBzDsxFbLgYxmQGKrE/ricoMqHRNjSlSUCcamVTA5lIQqzY10mY5qCY0QDwBfFEwhfoDPw==" + }, "@types/eslint": { "version": "8.4.10", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.10.tgz", @@ -23467,6 +23670,11 @@ "@types/node": "*" } }, + "@types/google.maps": { + "version": "3.52.0", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.52.0.tgz", + "integrity": "sha512-cIwkgSBUOCerEwEpAahg1SxUqqGV+D786TkVWrcZZyPvuCozmXFtzQcpOzvUXBtTUqDzEbCDGlAXDfDSYFXFIw==" + }, "@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -23476,6 +23684,11 @@ "@types/node": "*" } }, + "@types/hogan.js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/hogan.js/-/hogan.js-3.0.1.tgz", + "integrity": "sha512-D03i/2OY7kGyMq9wdQ7oD8roE49z/ZCZThe/nbahtvuqCNZY9T2MfedOWyeBdbEpY2W8Gnh/dyJLdFtUCOkYbg==" + }, "@types/hoist-non-react-statics": { "version": "3.3.1", "requires": { @@ -23577,8 +23790,7 @@ "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/range-parser": { "version": "1.2.4", @@ -23945,6 +24157,11 @@ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", "dev": true }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -24116,6 +24333,14 @@ "@algolia/transporter": "4.6.0" } }, + "algoliasearch-helper": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.11.3.tgz", + "integrity": "sha512-TbaEvLwiuGygHQIB8y+OsJKQQ40+JKUua5B91X66tMUHyyhbNHvqyr0lqd3wCoyKx7WybyQrC0WJvzoIeh24Aw==", + "requires": { + "@algolia/events": "^4.0.1" + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -27838,6 +28063,22 @@ "value-equal": "^1.0.1" } }, + "hogan.js": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/hogan.js/-/hogan.js-3.0.2.tgz", + "integrity": "sha512-RqGs4wavGYJWE07t35JQccByczmNUXQT0E12ZYV1VKYu5UiAU9lsos/yBAcf840+zrUQQxgVduCR5/B8nNtibg==", + "requires": { + "mkdirp": "0.3.0", + "nopt": "1.0.10" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==" + } + } + }, "hoist-non-react-statics": { "version": "3.3.2", "requires": { @@ -27901,6 +28142,11 @@ } } }, + "htm": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/htm/-/htm-3.1.1.tgz", + "integrity": "sha512-983Vyg8NwUE7JkZ6NmOqpCZ+sh1bKv2iYTlUkzlWmA5JD2acKoxd4KVxbMmxX/85mtfdnDmTFoNKcg5DGAvxNQ==" + }, "html-element-map": { "version": "1.3.1", "dev": true, @@ -28221,6 +28467,33 @@ "version": "1.3.8", "dev": true }, + "instantsearch.js": { + "version": "4.51.1", + "resolved": "https://registry.npmjs.org/instantsearch.js/-/instantsearch.js-4.51.1.tgz", + "integrity": "sha512-l4nETzassgSMBqOhNxntNH2MGG0KvFagwVwnXFis9P06nlspAyOdFLCQ0HA5wnlRDDev2WAZg9xRcTPCTLrwZw==", + "requires": { + "@algolia/events": "^4.0.1", + "@algolia/ui-components-highlight-vdom": "^1.2.1", + "@algolia/ui-components-shared": "^1.2.1", + "@types/dom-speech-recognition": "^0.0.1", + "@types/google.maps": "^3.45.3", + "@types/hogan.js": "^3.0.0", + "@types/qs": "^6.5.3", + "algoliasearch-helper": "^3.11.3", + "hogan.js": "^3.0.2", + "htm": "^3.0.0", + "preact": "^10.10.0", + "qs": "^6.5.1 < 6.10", + "search-insights": "^2.1.0" + }, + "dependencies": { + "qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-IhMFgUmuNpyRfxA90umL7ByLlgRXu6tIfKPpF5TmcfRLlLCckfP/g3IQmju6jjpu+Hh8rA+2p6A27ZSPOOHdKw==" + } + } + }, "internal-slot": { "version": "1.0.3", "dev": true, @@ -30206,6 +30479,14 @@ "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", "dev": true }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==", + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "3.0.3", "dev": true, @@ -31136,6 +31417,11 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "dev": true }, + "preact": { + "version": "10.12.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.12.1.tgz", + "integrity": "sha512-l8386ixSsBdbreOAkqtrwqHwdvR35ID8c3rKPa8lCWuO86dBi32QWHV4vfsZK1utLLFMvw+Z5Ad4XLkZzchscg==" + }, "prebuild-install": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", @@ -31566,6 +31852,27 @@ "react-side-effect": "^2.1.0" } }, + "react-instantsearch-hooks": { + "version": "6.40.1", + "resolved": "https://registry.npmjs.org/react-instantsearch-hooks/-/react-instantsearch-hooks-6.40.1.tgz", + "integrity": "sha512-Nqbmencg5816UVDkWUFpGyurAhp8WUBQgHiYj/bTnYQ7KuwXbbxIppIwexZqzXG8Q3DKVBWZw4PnmJiStLK2CA==", + "requires": { + "@babel/runtime": "^7.1.2", + "algoliasearch-helper": "^3.11.3", + "instantsearch.js": "4.51.1", + "use-sync-external-store": "^1.0.0" + } + }, + "react-instantsearch-hooks-web": { + "version": "6.40.1", + "resolved": "https://registry.npmjs.org/react-instantsearch-hooks-web/-/react-instantsearch-hooks-web-6.40.1.tgz", + "integrity": "sha512-MbsS1nhyZWPJjSVRzkDVmb0TM4L2kjHANsr0e1NDwkVWicP8LtXdX6UINDnekMKVnk1OmoF10NAJt4LmcSOqaA==", + "requires": { + "@babel/runtime": "^7.1.2", + "instantsearch.js": "4.51.1", + "react-instantsearch-hooks": "6.40.1" + } + }, "react-intl": { "version": "5.25.1", "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-5.25.1.tgz", @@ -32592,6 +32899,11 @@ "ajv-keywords": "^3.5.2" } }, + "search-insights": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.3.0.tgz", + "integrity": "sha512-0v/TTO4fbd6I91sFBK/e2zNfD0f51A+fMoYNkMplmR77NpThUye/7gIxNoJ3LejKpZH6Z2KNBIpxxFmDKj10Yw==" + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -34297,6 +34609,12 @@ "tslib": "^2.0.0" } }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, "util-deprecate": { "version": "1.0.2", "dev": true diff --git a/package.json b/package.json index d603f1f..c345402 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "react": "16.14.0", "react-dom": "16.14.0", "react-helmet": "6.1.0", + "react-instantsearch-hooks-web": "^6.40.1", "react-redux": "7.2.9", "react-router": "5.3.4", "react-router-dom": "5.3.4", diff --git a/src/skills-builder/data/constants.js b/src/skills-builder/data/constants.js index 5d801c6..65847df 100644 --- a/src/skills-builder/data/constants.js +++ b/src/skills-builder/data/constants.js @@ -1,7 +1,9 @@ +// Actions for Skills Context export const SET_GOAL = 'SET_GOAL'; export const SET_CURRENT_JOB_TITLE = 'SET_CURRENT_JOB_TITLE'; export const ADD_CAREER_INTEREST = 'ADD_CAREER_INTEREST'; export const REMOVE_CAREER_INTEREEST = 'REMOVE_CAREER_INTEREEST'; +// Stepper keys export const STEP1 = 'select-your-preferences'; export const STEP2 = 'review-your-results'; diff --git a/src/skills-builder/skills-builder-context/SkillsBuilderProvider.jsx b/src/skills-builder/skills-builder-context/SkillsBuilderProvider.jsx index 2df4004..f5984c4 100644 --- a/src/skills-builder/skills-builder-context/SkillsBuilderProvider.jsx +++ b/src/skills-builder/skills-builder-context/SkillsBuilderProvider.jsx @@ -1,12 +1,24 @@ import React, { createContext, useReducer, useMemo } from 'react'; import PropTypes from 'prop-types'; import reducer, { skillsInitialState } from '../data/reducer'; +import { useAlgoliaSearch } from '../utils/search'; export const SkillsBuilderContext = createContext(); export const SkillsBuilderProvider = ({ children }) => { const [state, dispatch] = useReducer(reducer, skillsInitialState); - const value = useMemo(() => ([state, dispatch]), [state]); + + const [searchClient, productSearchIndex, jobSearchIndex] = useAlgoliaSearch(); + + const value = useMemo(() => ({ + state, + dispatch, + algolia: { + searchClient, + productSearchIndex, + jobSearchIndex, + }, + }), [state, searchClient, productSearchIndex, jobSearchIndex]); return ( diff --git a/src/skills-builder/skills-builder-modal/SelectPreferences.jsx b/src/skills-builder/skills-builder-modal/SelectPreferences.jsx deleted file mode 100644 index 43320d1..0000000 --- a/src/skills-builder/skills-builder-modal/SelectPreferences.jsx +++ /dev/null @@ -1,63 +0,0 @@ -import React, { useContext } from 'react'; -import { - Button, -} from '@edx/paragon'; -import { - setGoal, - setCurrentJobTitle, - addCareerInterest, - removeCareerInterest, -} from '../data/actions'; -import { SkillsBuilderContext } from '../skills-builder-context'; -import { useAlgoliaSearch } from '../utils/search'; - -const SelectPreferences = () => { - // TODO: Temporarily disable the no-unused-vars check, we'll see these later - // eslint-disable-next-line no-unused-vars - const [algoliaClient, productSearchIndex, jobSearchIndex] = useAlgoliaSearch(); - const [{ currentGoal, currentJobTitle, careerInterests }, dispatch] = useContext(SkillsBuilderContext); - - return ( - <> -
-

Render Question 1

- -

Goal: {currentGoal}

-
- - {currentGoal && ( -
-

Render question 2

- -

Current Job Title: {currentJobTitle}

-
- )} - - {currentJobTitle && ( -
-

Render Question 3

- -

- Career Interests (click to remove): - {careerInterests.map(interest => ( - - ))} -

-
- )} - - ); -}; - -export default SelectPreferences; diff --git a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx index eaee071..470618e 100644 --- a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx +++ b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx @@ -1,27 +1,25 @@ import React, { useState, useContext } from 'react'; import { - Button, - Container, - Stepper, - ModalDialog, + Button, Container, Stepper, ModalDialog, } from '@edx/paragon'; -import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; import { useHistory } from 'react-router'; import { - STEP1, - STEP2, + STEP1, STEP2, } from '../data/constants'; import messages from './messages'; import { SkillsBuilderContext } from '../skills-builder-context'; import { SkillsBuilderHeader } from '../skills-builder-header'; -import SelectPreferences from './SelectPreferences'; -import ViewResults from './ViewResults'; +import { SelectPreferences } from './select-preferences'; +import ViewResults from './view-results/ViewResults'; import headerImage from '../images/headerImage.png'; const SkillsBuilderModal = () => { - const [{ careerInterests }] = useContext(SkillsBuilderContext); + const intl = useIntl(); + const { state } = useContext(SkillsBuilderContext); + const { careerInterests } = state; const [currentStep, setCurrentStep] = useState(STEP1); const history = useHistory(); @@ -48,13 +46,15 @@ const SkillsBuilderModal = () => { + + - - + + - + @@ -62,7 +62,7 @@ const SkillsBuilderModal = () => { - diff --git a/src/skills-builder/skills-builder-modal/messages.js b/src/skills-builder/skills-builder-modal/messages.js index 6938a8c..66f207f 100644 --- a/src/skills-builder/skills-builder-modal/messages.js +++ b/src/skills-builder/skills-builder-modal/messages.js @@ -17,6 +17,16 @@ const messages = defineMessages({ defaultMessage: 'Exit', description: 'Button that exits the Skills Builder.', }, + selectPreferences: { + id: 'select.preferences', + defaultMessage: 'Select preferences', + description: 'The first step of the Skills Builder for selecting a goal, a current job/occupation, and career interests', + }, + reviewResults: { + id: 'review.results', + defaultMessage: 'Review results', + description: 'The second step of the Skills Builder for rendering results from learner input', + }, }); export default messages; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx new file mode 100644 index 0000000..68f314f --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import messages from './messages'; + +const CareerInterestSelect = () => ( +
+

+ +

+

+ JobTitleAutosuggest component can be reused here +

+
+); + +export default CareerInterestSelect; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx new file mode 100644 index 0000000..2c2f5f6 --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx @@ -0,0 +1,38 @@ +import React, { useContext } from 'react'; +import { + Form, + Stack, +} from '@edx/paragon'; +import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; +import { setGoal } from '../../data/actions'; +import { SkillsBuilderContext } from '../../skills-builder-context'; +import messages from './messages'; + +const GoalDropdown = () => { + const intl = useIntl(); + const { state, dispatch } = useContext(SkillsBuilderContext); + const { currentGoal } = state; + + return ( + +

+ + dispatch(setGoal(e.target.value))} + > + + + + + + + + +
+ + ); +}; + +export default GoalDropdown; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx new file mode 100644 index 0000000..e147d5d --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx @@ -0,0 +1,39 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import { + Form, +} from '@edx/paragon'; +import { useHits, useSearchBox } from 'react-instantsearch-hooks-web'; + +const JobTitleInstantSearch = (props) => { + const { refine } = useSearchBox(props); + const { hits } = useHits(props); + + const [jobInput, setJobInput] = useState(''); + + const handleAutosuggestChange = (value) => { + setJobInput(value); + refine(value); + }; + + return ( + + {hits.map(job => ( + + {job.name} + + ))} + + ); +}; + +JobTitleInstantSearch.propTypes = { + onSelected: PropTypes.func.isRequired, +}; + +export default JobTitleInstantSearch; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx new file mode 100644 index 0000000..1d02bdd --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx @@ -0,0 +1,46 @@ +import React, { useContext } from 'react'; +import { + Form, Stack, +} from '@edx/paragon'; +import { getConfig } from '@edx/frontend-platform'; +import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { InstantSearch } from 'react-instantsearch-hooks-web'; +import { setCurrentJobTitle } from '../../data/actions'; +import { SkillsBuilderContext } from '../../skills-builder-context'; +import JobTitleInstantSearch from './JobTitleInstantSearch'; +import messages from './messages'; + +const JobTitleSelect = () => { + const { dispatch, algolia } = useContext(SkillsBuilderContext); + const { searchClient } = algolia; + + // Below implementation sets the job title to "student" or "looking_for_work" — this overwrites any previous selection + // This will need to be revisited when we decide what to do with this data + const handleCheckboxChange = (e) => dispatch(setCurrentJobTitle(e.target.value)); + + return ( + +

+ +

+ + dispatch(setCurrentJobTitle(value))} /> + + + + + + + + + + + +
+ ); +}; + +export default JobTitleSelect; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx b/src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx new file mode 100644 index 0000000..11526ab --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx @@ -0,0 +1,36 @@ +import React, { useContext } from 'react'; +import { + Stack, +} from '@edx/paragon'; +import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { SkillsBuilderContext } from '../../skills-builder-context'; + +import GoalSelect from './GoalSelect'; +import JobTitleSelect from './JobTitleSelect'; +import CareerInterestSelect from './CareerInterestSelect'; +import messages from './messages'; + +const SelectPreferences = () => { + const { state } = useContext(SkillsBuilderContext); + const { currentGoal, currentJobTitle } = state; + + return ( + +

+ +

+ + + + {currentGoal && ( + + )} + + {currentJobTitle && ( + + )} +
+ ); +}; + +export default SelectPreferences; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/index.js b/src/skills-builder/skills-builder-modal/select-preferences/index.js new file mode 100644 index 0000000..f8d553d --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/index.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/prefer-default-export +export { default as SelectPreferences } from './SelectPreferences'; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/messages.js b/src/skills-builder/skills-builder-modal/select-preferences/messages.js new file mode 100644 index 0000000..76e124a --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/messages.js @@ -0,0 +1,66 @@ +import { defineMessages } from '@edx/frontend-platform/i18n'; + +const messages = defineMessages({ + skillsBuilderDescription: { + id: 'skills.builder.description', + defaultMessage: 'Find the right courses and programs that help you reach your goals.', + description: 'Description of what the Skills Builder seeks to accomplish', + }, + learningGoalPrompt: { + id: 'learning.goal.prompt', + defaultMessage: 'First, tell us what you want to achieve', + description: 'Prompts the user to select their current goal.', + }, + selectLearningGoal: { + id: 'select.learning.goal', + defaultMessage: 'Select a goal', + description: 'Placeholder text for the goal selection component.', + }, + learningGoalStartCareer: { + id: 'learning.goal.start_career', + defaultMessage: 'I want to start my career', + description: 'Selected by user if their goal is to start their career.', + }, + learningGoalAdvanceCareer: { + id: 'learning.goal.advance_career', + defaultMessage: 'I want to advance my career', + description: 'Selected by user if their goal is to advance their career.', + }, + learningGoalChangeCareer: { + id: 'learning.goal.change_career', + defaultMessage: 'I want to change careers', + description: 'Selected by user if their goal is to change careers.', + }, + learningGoalSomethingNew: { + id: 'learning.goal.something.new', + defaultMessage: 'I want to learn something new', + description: 'Selected by user if their goal is to learn something new.', + }, + learningGoalSomethingElse: { + id: 'learning.goal.something.else', + defaultMessage: 'Something else', + description: 'Selected by user if their goal is not described by the other choices.', + }, + jobTitlePrompt: { + id: 'job.title.prompt', + defaultMessage: 'Next, search and select your current job title', + description: 'Prompts the user to select their current job title or occupation.', + }, + studentCheckboxPrompt: { + id: 'student.checkbox.prompt', + defaultMessage: 'I\'m a student', + description: 'Label text for the corresponding checkbox', + }, + currentlyLookingCheckboxPrompt: { + id: 'currently.looking.checkbox.prompt', + defaultMessage: 'I\'m currently looking for work', + description: 'Label text for the corresponding checkbox', + }, + careerInterestPrompt: { + id: 'career.interest.prompt', + defaultMessage: 'What careers are you interested in?', + description: 'Prompts the user to select careers they are interested in pursuing.', + }, +}); + +export default messages; diff --git a/src/skills-builder/skills-builder-modal/ViewResults.jsx b/src/skills-builder/skills-builder-modal/view-results/ViewResults.jsx similarity index 100% rename from src/skills-builder/skills-builder-modal/ViewResults.jsx rename to src/skills-builder/skills-builder-modal/view-results/ViewResults.jsx diff --git a/src/skills-builder/skills-builder-modal/view-results/index.js b/src/skills-builder/skills-builder-modal/view-results/index.js new file mode 100644 index 0000000..b0af023 --- /dev/null +++ b/src/skills-builder/skills-builder-modal/view-results/index.js @@ -0,0 +1,2 @@ +// eslint-disable-next-line import/prefer-default-export +export { default as ViewResults } from './ViewResults'; diff --git a/src/skills-builder/test/SkillsBuilder.test.jsx b/src/skills-builder/test/SkillsBuilder.test.jsx index 2d6f073..0925b15 100644 --- a/src/skills-builder/test/SkillsBuilder.test.jsx +++ b/src/skills-builder/test/SkillsBuilder.test.jsx @@ -1,19 +1,96 @@ import { IntlProvider } from '@edx/frontend-platform/i18n'; import React from 'react'; -import { screen, render } from '@testing-library/react'; +import { + screen, render, cleanup, fireEvent, act, +} from '@testing-library/react'; +import { mergeConfig } from '@edx/frontend-platform'; import { SkillsBuilder } from '..'; +import { SkillsBuilderModal } from '../skills-builder-modal'; +import { SkillsBuilderProvider, SkillsBuilderContext } from '../skills-builder-context'; +import { skillsInitialState } from '../data/reducer'; -const SkillsBuilderWrapper = () => ( +jest.mock('react-instantsearch-hooks-web', () => ({ + // eslint-disable-next-line react/prop-types + InstantSearch: ({ children }) => (
{children}
), + useSearchBox: jest.fn(() => ({ refine: jest.fn() })), + useHits: jest.fn(() => ({ hits: [{ name: 'Text File Engineer' }, { name: 'Screen Viewer' }] })), +})); + +const dispatchMock = jest.fn(); + +const contextValue = { + state: { + ...skillsInitialState, + }, + dispatch: dispatchMock, + algolia: { + // Without this, tests would fail to destructure `searchClient` in the component + searchClient: {}, + }, +}; + +const SkillsBuilderWrapperWithContext = (value) => ( - + + + ); describe('skills-builder', () => { - it('should render a Skills Builder modal', () => { - render( - , - ); + beforeAll(async () => { + await mergeConfig({ + ALGOLIA_JOBS_INDEX_NAME: 'test-job-index-name', + }); + }); + beforeEach(() => cleanup()); + + it('should render a Skills Builder modal with a prompt for the user', () => { + act(() => { + render( + + + + + , + ); + }); expect(screen.getByText('Skills Builder')).toBeTruthy(); + expect(screen.getByText('First, tell us what you want to achieve')).toBeTruthy(); + }); + + it('should render the second prompt if a goal is selected', () => { + render( + SkillsBuilderWrapperWithContext( + { + ...contextValue, + state: { + ...contextValue.state, + currentGoal: 'I want to start my career', + }, + }, + ), + ); + expect(screen.getByText('Next, search and select your current job title')).toBeTruthy(); + + const checkbox = screen.getByRole('checkbox', { name: 'I\'m a student' }); + fireEvent.click(checkbox); + expect(dispatchMock).toHaveBeenCalled(); + }); + + it('should render the third prompt if a goal is selected', () => { + render( + SkillsBuilderWrapperWithContext( + { + ...contextValue, + state: { + ...contextValue.state, + currentGoal: 'I want to start my career', + currentJobTitle: 'Goblin Guide', + }, + }, + ), + ); + expect(screen.getByText('What careers are you interested in?')).toBeTruthy(); }); }); From 17b493327870f1e4d0341b22e662696182afc2f8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 12:52:53 -0800 Subject: [PATCH 12/63] fix(deps): update dependency @edx/frontend-platform to v3 (#660) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package-lock.json | 198 +++++++++++++++++++++++++--------------------- package.json | 2 +- 2 files changed, 108 insertions(+), 92 deletions(-) diff --git a/package-lock.json b/package-lock.json index 87d3f99..15411a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@edx/brand": "npm:@edx/brand-openedx@1.2.0", "@edx/frontend-component-footer": "11.6.2", "@edx/frontend-component-header": "3.6.1", - "@edx/frontend-platform": "2.6.2", + "@edx/frontend-platform": "3.3.1", "@edx/paragon": "^20.20.0", "@fortawesome/fontawesome-svg-core": "1.2.36", "@fortawesome/free-brands-svg-icons": "5.15.4", @@ -2697,17 +2697,17 @@ } }, "node_modules/@edx/frontend-platform": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-2.6.2.tgz", - "integrity": "sha512-h+gYLkPYw41krGiSGs59o2jaq/g3Yk6ay/3rBq0y1/KM6eeaq/F7o14YOhfTRLTpld9Hg+MPKzfOuHyqQN2TEw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-3.3.1.tgz", + "integrity": "sha512-EF2a5Ovzhu5URo7ER6Mc/K+l02UGuXpd2bQw+dW/xGe/hlv+1CDnrzDTqM8QEk+suZyQfI9U0fnsqwcwr0a2SA==", "dependencies": { "@cospired/i18n-iso-languages": "2.2.0", "@formatjs/intl-pluralrules": "4.3.3", "@formatjs/intl-relativetimeformat": "10.0.1", - "axios": "0.26.1", - "axios-cache-adapter": "2.7.3", + "axios": "0.27.2", + "axios-cache-interceptor": "0.10.7", "form-urlencoded": "4.1.4", - "glob": "7.2.0", + "glob": "7.2.3", "history": "4.10.1", "i18n-iso-countries": "4.3.1", "jwt-decode": "3.1.2", @@ -2735,20 +2735,36 @@ } }, "node_modules/@edx/frontend-platform/node_modules/axios": { - "version": "0.26.1", - "license": "MIT", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "dependencies": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "node_modules/@edx/frontend-platform/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" } }, "node_modules/@edx/frontend-platform/node_modules/glob": { - "version": "7.2.0", - "license": "ISC", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -5615,8 +5631,7 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/at-least-node": { "version": "1.0.0", @@ -5691,20 +5706,23 @@ }, "node_modules/axios": { "version": "0.21.4", + "dev": true, "license": "MIT", "dependencies": { "follow-redirects": "^1.14.0" } }, - "node_modules/axios-cache-adapter": { - "version": "2.7.3", - "license": "MIT", + "node_modules/axios-cache-interceptor": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-0.10.7.tgz", + "integrity": "sha512-UjpxChG5DpF6Kf1IPGMLOzRDNL8ZNS6TOn1jTaVvCE7cWFU904jJwi0T1s+IbijpnLEjK2iq5uLIuR8Sj+RsFQ==", "dependencies": { - "cache-control-esm": "1.0.0", - "md5": "^2.2.1" + "cache-parser": "^1.2.4", + "fast-defer": "^1.1.7", + "object-code": "^1.2.4" }, - "peerDependencies": { - "axios": "~0.21.1" + "funding": { + "url": "https://github.com/ArthurFiorette/axios-cache-interceptor?sponsor=1" } }, "node_modules/axobject-query": { @@ -6349,9 +6367,10 @@ "node": ">=0.10.0" } }, - "node_modules/cache-control-esm": { - "version": "1.0.0", - "license": "MIT" + "node_modules/cache-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.4.tgz", + "integrity": "sha512-O0KwuHuJnbHUrghHi2kGp0SxnWSIBXTYt7M8WVhW0kbPRUNUKoE/Of6e1rRD6AAxmfxFunKnt90yEK09D+sc5g==" }, "node_modules/call-bind": { "version": "1.0.2", @@ -6491,13 +6510,6 @@ "node": ">=10" } }, - "node_modules/charenc": { - "version": "0.0.2", - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/cheerio": { "version": "1.0.0-rc.12", "dev": true, @@ -6863,7 +6875,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -7156,13 +7167,6 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "license": "BSD-3-Clause", - "engines": { - "node": "*" - } - }, "node_modules/css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", @@ -7600,7 +7604,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -9251,6 +9254,11 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-defer": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.7.tgz", + "integrity": "sha512-tJ01ulDWT2WhqxMKS20nXX6wyX2iInBYpbN3GO7yjKwXMY4qvkdBRxak9IFwBLlFDESox+SwSvqMCZDfe1tqeg==" + }, "node_modules/fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -11032,6 +11040,7 @@ }, "node_modules/is-buffer": { "version": "1.1.6", + "dev": true, "license": "MIT" }, "node_modules/is-callable": { @@ -13031,15 +13040,6 @@ "css-mediaquery": "^0.1.2" } }, - "node_modules/md5": { - "version": "2.3.0", - "license": "BSD-3-Clause", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, "node_modules/mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", @@ -13160,7 +13160,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -13169,7 +13168,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -13603,6 +13601,11 @@ "node": ">=0.10.0" } }, + "node_modules/object-code": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.2.4.tgz", + "integrity": "sha512-uGq4ETUuWe+GA586NXEriiaozNuff+YNFXlpD8cVrM1GoiuTZpCABP+bZCWDrvQDoCiSTyiWAFHD/HF/iwhb2w==" + }, "node_modules/object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", @@ -22023,17 +22026,17 @@ } }, "@edx/frontend-platform": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-2.6.2.tgz", - "integrity": "sha512-h+gYLkPYw41krGiSGs59o2jaq/g3Yk6ay/3rBq0y1/KM6eeaq/F7o14YOhfTRLTpld9Hg+MPKzfOuHyqQN2TEw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-3.3.1.tgz", + "integrity": "sha512-EF2a5Ovzhu5URo7ER6Mc/K+l02UGuXpd2bQw+dW/xGe/hlv+1CDnrzDTqM8QEk+suZyQfI9U0fnsqwcwr0a2SA==", "requires": { "@cospired/i18n-iso-languages": "2.2.0", "@formatjs/intl-pluralrules": "4.3.3", "@formatjs/intl-relativetimeformat": "10.0.1", - "axios": "0.26.1", - "axios-cache-adapter": "2.7.3", + "axios": "0.27.2", + "axios-cache-interceptor": "0.10.7", "form-urlencoded": "4.1.4", - "glob": "7.2.0", + "glob": "7.2.3", "history": "4.10.1", "i18n-iso-countries": "4.3.1", "jwt-decode": "3.1.2", @@ -22049,18 +22052,33 @@ }, "dependencies": { "axios": { - "version": "0.26.1", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz", + "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==", "requires": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.14.9", + "form-data": "^4.0.0" + } + }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" } }, "glob": { - "version": "7.2.0", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -24341,8 +24359,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "at-least-node": { "version": "1.0.0", @@ -24383,15 +24400,19 @@ }, "axios": { "version": "0.21.4", + "dev": true, "requires": { "follow-redirects": "^1.14.0" } }, - "axios-cache-adapter": { - "version": "2.7.3", + "axios-cache-interceptor": { + "version": "0.10.7", + "resolved": "https://registry.npmjs.org/axios-cache-interceptor/-/axios-cache-interceptor-0.10.7.tgz", + "integrity": "sha512-UjpxChG5DpF6Kf1IPGMLOzRDNL8ZNS6TOn1jTaVvCE7cWFU904jJwi0T1s+IbijpnLEjK2iq5uLIuR8Sj+RsFQ==", "requires": { - "cache-control-esm": "1.0.0", - "md5": "^2.2.1" + "cache-parser": "^1.2.4", + "fast-defer": "^1.1.7", + "object-code": "^1.2.4" } }, "axobject-query": { @@ -24880,8 +24901,10 @@ "unset-value": "^1.0.0" } }, - "cache-control-esm": { - "version": "1.0.0" + "cache-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/cache-parser/-/cache-parser-1.2.4.tgz", + "integrity": "sha512-O0KwuHuJnbHUrghHi2kGp0SxnWSIBXTYt7M8WVhW0kbPRUNUKoE/Of6e1rRD6AAxmfxFunKnt90yEK09D+sc5g==" }, "call-bind": { "version": "1.0.2", @@ -24975,9 +24998,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "charenc": { - "version": "0.0.2" - }, "cheerio": { "version": "1.0.0-rc.12", "dev": true, @@ -25261,7 +25281,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -25487,9 +25506,6 @@ "which": "^2.0.1" } }, - "crypt": { - "version": "0.0.2" - }, "css-declaration-sorter": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz", @@ -25798,8 +25814,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "depd": { "version": "2.0.0", @@ -27068,6 +27083,11 @@ "version": "3.1.3", "dev": true }, + "fast-defer": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/fast-defer/-/fast-defer-1.1.7.tgz", + "integrity": "sha512-tJ01ulDWT2WhqxMKS20nXX6wyX2iInBYpbN3GO7yjKwXMY4qvkdBRxak9IFwBLlFDESox+SwSvqMCZDfe1tqeg==" + }, "fast-glob": { "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", @@ -28333,7 +28353,8 @@ } }, "is-buffer": { - "version": "1.1.6" + "version": "1.1.6", + "dev": true }, "is-callable": { "version": "1.2.7", @@ -29842,14 +29863,6 @@ "css-mediaquery": "^0.1.2" } }, - "md5": { - "version": "2.3.0", - "requires": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, "mdn-data": { "version": "2.0.14", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", @@ -29935,14 +29948,12 @@ "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "requires": { "mime-db": "1.52.0" } @@ -30257,6 +30268,11 @@ "object-assign": { "version": "4.1.1" }, + "object-code": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/object-code/-/object-code-1.2.4.tgz", + "integrity": "sha512-uGq4ETUuWe+GA586NXEriiaozNuff+YNFXlpD8cVrM1GoiuTZpCABP+bZCWDrvQDoCiSTyiWAFHD/HF/iwhb2w==" + }, "object-copy": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", diff --git a/package.json b/package.json index d603f1f..98251b4 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@edx/brand": "npm:@edx/brand-openedx@1.2.0", "@edx/frontend-component-footer": "11.6.2", "@edx/frontend-component-header": "3.6.1", - "@edx/frontend-platform": "2.6.2", + "@edx/frontend-platform": "3.3.1", "@edx/paragon": "^20.20.0", "@fortawesome/fontawesome-svg-core": "1.2.36", "@fortawesome/free-brands-svg-icons": "5.15.4", From e9e48e4eb0469c56ae6cfe65a3e30308754ae6f4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 13:03:26 -0800 Subject: [PATCH 13/63] build(deps): bump json5 from 1.0.1 to 1.0.2 (#661) Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 6fa5681e91028ecc863cf5b7ef29471c68a378ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 13:07:48 -0800 Subject: [PATCH 14/63] build(deps): bump cookiejar from 2.1.3 to 2.1.4 (#674) Bumps [cookiejar](https://github.com/bmeck/node-cookiejar) from 2.1.3 to 2.1.4. - [Release notes](https://github.com/bmeck/node-cookiejar/releases) - [Commits](https://github.com/bmeck/node-cookiejar/commits) --- updated-dependencies: - dependency-name: cookiejar dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> From 83e2b66c777a3ab7190bf064d26965cd45e59e03 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Sun, 26 Feb 2023 20:35:19 +0000 Subject: [PATCH 15/63] chore(i18n): update translations --- src/i18n/messages/fr_CA.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/i18n/messages/fr_CA.json b/src/i18n/messages/fr_CA.json index b81f326..cc18b40 100644 --- a/src/i18n/messages/fr_CA.json +++ b/src/i18n/messages/fr_CA.json @@ -58,5 +58,5 @@ "skills.builder.header.subheading": "Laissez EDUlib être votre guide", "go.back.button": "Retour", "next.step.button": "Prochaine étape", - "exit.button": "Exit" + "exit.button": "Sortie" } \ No newline at end of file From b10b31860d0313de4004f955aeb8c38719f3888f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 05:26:05 +0000 Subject: [PATCH 16/63] chore(deps): update commitlint monorepo to v17.4.4 --- package-lock.json | 248 +++++++++++++++++++++++----------------------- package.json | 4 +- 2 files changed, 126 insertions(+), 126 deletions(-) diff --git a/package-lock.json b/package-lock.json index 15411a1..d3e1d12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,8 +43,8 @@ "universal-cookie": "4.0.4" }, "devDependencies": { - "@commitlint/cli": "17.4.2", - "@commitlint/config-angular": "17.4.2", + "@commitlint/cli": "17.4.4", + "@commitlint/config-angular": "17.4.4", "@edx/browserslist-config": "^1.1.1", "@edx/frontend-build": "12.4.19", "@edx/reactifex": "2.1.1", @@ -2160,16 +2160,16 @@ } }, "node_modules/@commitlint/cli": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.4.2.tgz", - "integrity": "sha512-0rPGJ2O1owhpxMIXL9YJ2CgPkdrFLKZElIZHXDN8L8+qWK1DGH7Q7IelBT1pchXTYTuDlqkOTdh//aTvT3bSUA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.4.4.tgz", + "integrity": "sha512-HwKlD7CPVMVGTAeFZylVNy14Vm5POVY0WxPkZr7EXLC/os0LH/obs6z4HRvJtH/nHCMYBvUBQhGwnufKfTjd5g==", "dev": true, "dependencies": { - "@commitlint/format": "^17.4.0", - "@commitlint/lint": "^17.4.2", - "@commitlint/load": "^17.4.2", - "@commitlint/read": "^17.4.2", - "@commitlint/types": "^17.4.0", + "@commitlint/format": "^17.4.4", + "@commitlint/lint": "^17.4.4", + "@commitlint/load": "^17.4.4", + "@commitlint/read": "^17.4.4", + "@commitlint/types": "^17.4.4", "execa": "^5.0.0", "lodash.isfunction": "^3.0.9", "resolve-from": "5.0.0", @@ -2184,9 +2184,9 @@ } }, "node_modules/@commitlint/config-angular": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-17.4.2.tgz", - "integrity": "sha512-14gEwTZ6wcpbdE0lNkJVeeafZd72occHwG9Fi6JEVQQ/nOi9XBiJRFWPRQObXlb8UZCh0q9xgIqeJTue6toypQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-17.4.4.tgz", + "integrity": "sha512-ulCgBc1sDWwwW0HKGQDurcfWbWw1PZjwOFzeL2PZq3jcOgPfOzEHqE3dIjycB5DKlWNx4kUMcgwMWaX/zUtBNg==", "dev": true, "dependencies": { "@commitlint/config-angular-type-enum": "^17.4.0" @@ -2205,12 +2205,12 @@ } }, "node_modules/@commitlint/config-validator": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.0.tgz", - "integrity": "sha512-Sa/+8KNpDXz4zT4bVbz2fpFjvgkPO6u2V2fP4TKgt6FjmOw2z3eEX859vtfeaTav/ukBw0/0jr+5ZTZp9zCBhA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz", + "integrity": "sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "ajv": "^8.11.0" }, "engines": { @@ -2240,12 +2240,12 @@ "dev": true }, "node_modules/@commitlint/ensure": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.0.tgz", - "integrity": "sha512-7oAxt25je0jeQ/E0O/M8L3ADb1Cvweu/5lc/kYF8g/kXatI0wxGE5La52onnAUAWeWlsuvBNar15WcrmDmr5Mw==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.4.tgz", + "integrity": "sha512-AHsFCNh8hbhJiuZ2qHv/m59W/GRE9UeOXbkOqxYMNNg9pJ7qELnFcwj5oYpa6vzTSHtPGKf3C2yUFNy1GGHq6g==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -2266,12 +2266,12 @@ } }, "node_modules/@commitlint/format": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.0.tgz", - "integrity": "sha512-Z2bWAU5+f1YZh9W76c84J8iLIWIvvm+mzqogTz0Nsc1x6EHW0Z2gI38g5HAjB0r0I3ZjR15IDEJKhsxyblcyhA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz", + "integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "chalk": "^4.1.0" }, "engines": { @@ -2279,12 +2279,12 @@ } }, "node_modules/@commitlint/is-ignored": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.4.2.tgz", - "integrity": "sha512-1b2Y2qJ6n7bHG9K6h8S4lBGUl6kc7mMhJN9gy1SQfUZqe92ToDjUTtgNWb6LbzR1X8Cq4SEus4VU8Z/riEa94Q==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.4.4.tgz", + "integrity": "sha512-Y3eo1SFJ2JQDik4rWkBC4tlRIxlXEFrRWxcyrzb1PUT2k3kZ/XGNuCDfk/u0bU2/yS0tOA/mTjFsV+C4qyACHw==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "semver": "7.3.8" }, "engines": { @@ -2292,30 +2292,30 @@ } }, "node_modules/@commitlint/lint": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.4.2.tgz", - "integrity": "sha512-HcymabrdBhsDMNzIv146+ZPNBPBK5gMNsVH+el2lCagnYgCi/4ixrHooeVyS64Fgce2K26+MC7OQ4vVH8wQWVw==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.4.4.tgz", + "integrity": "sha512-qgkCRRFjyhbMDWsti/5jRYVJkgYZj4r+ZmweZObnbYqPUl5UKLWMf9a/ZZisOI4JfiPmRktYRZ2JmqlSvg+ccw==", "dev": true, "dependencies": { - "@commitlint/is-ignored": "^17.4.2", - "@commitlint/parse": "^17.4.2", - "@commitlint/rules": "^17.4.2", - "@commitlint/types": "^17.4.0" + "@commitlint/is-ignored": "^17.4.4", + "@commitlint/parse": "^17.4.4", + "@commitlint/rules": "^17.4.4", + "@commitlint/types": "^17.4.4" }, "engines": { "node": ">=v14" } }, "node_modules/@commitlint/load": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.4.2.tgz", - "integrity": "sha512-Si++F85rJ9t4hw6JcOw1i2h0fdpdFQt0YKwjuK4bk9KhFjyFkRxvR3SB2dPaMs+EwWlDrDBGL+ygip1QD6gmPw==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.4.4.tgz", + "integrity": "sha512-z6uFIQ7wfKX5FGBe1AkOF4l/ShOQsaa1ml/nLMkbW7R/xF8galGS7Zh0yHvzVp/srtfS0brC+0bUfQfmpMPFVQ==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.4.0", + "@commitlint/config-validator": "^17.4.4", "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/resolve-extends": "^17.4.4", + "@commitlint/types": "^17.4.4", "@types/node": "*", "chalk": "^4.1.0", "cosmiconfig": "^8.0.0", @@ -2374,12 +2374,12 @@ } }, "node_modules/@commitlint/parse": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.4.2.tgz", - "integrity": "sha512-DK4EwqhxfXpyCA+UH8TBRIAXAfmmX4q9QRBz/2h9F9sI91yt6mltTrL6TKURMcjUVmgaB80wgS9QybNIyVBIJA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.4.4.tgz", + "integrity": "sha512-EKzz4f49d3/OU0Fplog7nwz/lAfXMaDxtriidyGF9PtR+SRbgv4FhsfF310tKxs6EPj8Y+aWWuX3beN5s+yqGg==", "dev": true, "dependencies": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "conventional-changelog-angular": "^5.0.11", "conventional-commits-parser": "^3.2.2" }, @@ -2388,13 +2388,13 @@ } }, "node_modules/@commitlint/read": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.4.2.tgz", - "integrity": "sha512-hasYOdbhEg+W4hi0InmXHxtD/1favB4WdwyFxs1eOy/DvMw6+2IZBmATgGOlqhahsypk4kChhxjAFJAZ2F+JBg==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.4.4.tgz", + "integrity": "sha512-B2TvUMJKK+Svzs6eji23WXsRJ8PAD+orI44lVuVNsm5zmI7O8RSGJMvdEZEikiA4Vohfb+HevaPoWZ7PiFZ3zA==", "dev": true, "dependencies": { "@commitlint/top-level": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "fs-extra": "^11.0.0", "git-raw-commits": "^2.0.0", "minimist": "^1.2.6" @@ -2404,13 +2404,13 @@ } }, "node_modules/@commitlint/resolve-extends": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.0.tgz", - "integrity": "sha512-3JsmwkrCzoK8sO22AzLBvNEvC1Pmdn/65RKXzEtQMy6oYMl0Snrq97a5bQQEFETF0VsvbtUuKttLqqgn99OXRQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz", + "integrity": "sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==", "dev": true, "dependencies": { - "@commitlint/config-validator": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/config-validator": "^17.4.4", + "@commitlint/types": "^17.4.4", "import-fresh": "^3.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0", @@ -2421,15 +2421,15 @@ } }, "node_modules/@commitlint/rules": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.4.2.tgz", - "integrity": "sha512-OGrPsMb9Fx3/bZ64/EzJehY9YDSGWzp81Pj+zJiY+r/NSgJI3nUYdlS37jykNIugzazdEXfMtQ10kmA+Kx2pZQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.4.4.tgz", + "integrity": "sha512-0tgvXnHi/mVcyR8Y8mjTFZIa/FEQXA4uEutXS/imH2v1UNkYDSEMsK/68wiXRpfW1euSgEdwRkvE1z23+yhNrQ==", "dev": true, "dependencies": { - "@commitlint/ensure": "^17.4.0", + "@commitlint/ensure": "^17.4.4", "@commitlint/message": "^17.4.2", "@commitlint/to-lines": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "execa": "^5.0.0" }, "engines": { @@ -2458,9 +2458,9 @@ } }, "node_modules/@commitlint/types": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.0.tgz", - "integrity": "sha512-2NjAnq5IcxY9kXtUeO2Ac0aPpvkuOmwbH/BxIm36XXK5LtWFObWJWjXOA+kcaABMrthjWu6la+FUpyYFMHRvbA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", + "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", "dev": true, "dependencies": { "chalk": "^4.1.0" @@ -21604,16 +21604,16 @@ } }, "@commitlint/cli": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.4.2.tgz", - "integrity": "sha512-0rPGJ2O1owhpxMIXL9YJ2CgPkdrFLKZElIZHXDN8L8+qWK1DGH7Q7IelBT1pchXTYTuDlqkOTdh//aTvT3bSUA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.4.4.tgz", + "integrity": "sha512-HwKlD7CPVMVGTAeFZylVNy14Vm5POVY0WxPkZr7EXLC/os0LH/obs6z4HRvJtH/nHCMYBvUBQhGwnufKfTjd5g==", "dev": true, "requires": { - "@commitlint/format": "^17.4.0", - "@commitlint/lint": "^17.4.2", - "@commitlint/load": "^17.4.2", - "@commitlint/read": "^17.4.2", - "@commitlint/types": "^17.4.0", + "@commitlint/format": "^17.4.4", + "@commitlint/lint": "^17.4.4", + "@commitlint/load": "^17.4.4", + "@commitlint/read": "^17.4.4", + "@commitlint/types": "^17.4.4", "execa": "^5.0.0", "lodash.isfunction": "^3.0.9", "resolve-from": "5.0.0", @@ -21622,9 +21622,9 @@ } }, "@commitlint/config-angular": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-17.4.2.tgz", - "integrity": "sha512-14gEwTZ6wcpbdE0lNkJVeeafZd72occHwG9Fi6JEVQQ/nOi9XBiJRFWPRQObXlb8UZCh0q9xgIqeJTue6toypQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-angular/-/config-angular-17.4.4.tgz", + "integrity": "sha512-ulCgBc1sDWwwW0HKGQDurcfWbWw1PZjwOFzeL2PZq3jcOgPfOzEHqE3dIjycB5DKlWNx4kUMcgwMWaX/zUtBNg==", "dev": true, "requires": { "@commitlint/config-angular-type-enum": "^17.4.0" @@ -21637,12 +21637,12 @@ "dev": true }, "@commitlint/config-validator": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.0.tgz", - "integrity": "sha512-Sa/+8KNpDXz4zT4bVbz2fpFjvgkPO6u2V2fP4TKgt6FjmOw2z3eEX859vtfeaTav/ukBw0/0jr+5ZTZp9zCBhA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-17.4.4.tgz", + "integrity": "sha512-bi0+TstqMiqoBAQDvdEP4AFh0GaKyLFlPPEObgI29utoKEYoPQTvF0EYqIwYYLEoJYhj5GfMIhPHJkTJhagfeg==", "dev": true, "requires": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "ajv": "^8.11.0" }, "dependencies": { @@ -21667,12 +21667,12 @@ } }, "@commitlint/ensure": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.0.tgz", - "integrity": "sha512-7oAxt25je0jeQ/E0O/M8L3ADb1Cvweu/5lc/kYF8g/kXatI0wxGE5La52onnAUAWeWlsuvBNar15WcrmDmr5Mw==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-17.4.4.tgz", + "integrity": "sha512-AHsFCNh8hbhJiuZ2qHv/m59W/GRE9UeOXbkOqxYMNNg9pJ7qELnFcwj5oYpa6vzTSHtPGKf3C2yUFNy1GGHq6g==", "dev": true, "requires": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", @@ -21687,47 +21687,47 @@ "dev": true }, "@commitlint/format": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.0.tgz", - "integrity": "sha512-Z2bWAU5+f1YZh9W76c84J8iLIWIvvm+mzqogTz0Nsc1x6EHW0Z2gI38g5HAjB0r0I3ZjR15IDEJKhsxyblcyhA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-17.4.4.tgz", + "integrity": "sha512-+IS7vpC4Gd/x+uyQPTAt3hXs5NxnkqAZ3aqrHd5Bx/R9skyCAWusNlNbw3InDbAK6j166D9asQM8fnmYIa+CXQ==", "dev": true, "requires": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "chalk": "^4.1.0" } }, "@commitlint/is-ignored": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.4.2.tgz", - "integrity": "sha512-1b2Y2qJ6n7bHG9K6h8S4lBGUl6kc7mMhJN9gy1SQfUZqe92ToDjUTtgNWb6LbzR1X8Cq4SEus4VU8Z/riEa94Q==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-17.4.4.tgz", + "integrity": "sha512-Y3eo1SFJ2JQDik4rWkBC4tlRIxlXEFrRWxcyrzb1PUT2k3kZ/XGNuCDfk/u0bU2/yS0tOA/mTjFsV+C4qyACHw==", "dev": true, "requires": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "semver": "7.3.8" } }, "@commitlint/lint": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.4.2.tgz", - "integrity": "sha512-HcymabrdBhsDMNzIv146+ZPNBPBK5gMNsVH+el2lCagnYgCi/4ixrHooeVyS64Fgce2K26+MC7OQ4vVH8wQWVw==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-17.4.4.tgz", + "integrity": "sha512-qgkCRRFjyhbMDWsti/5jRYVJkgYZj4r+ZmweZObnbYqPUl5UKLWMf9a/ZZisOI4JfiPmRktYRZ2JmqlSvg+ccw==", "dev": true, "requires": { - "@commitlint/is-ignored": "^17.4.2", - "@commitlint/parse": "^17.4.2", - "@commitlint/rules": "^17.4.2", - "@commitlint/types": "^17.4.0" + "@commitlint/is-ignored": "^17.4.4", + "@commitlint/parse": "^17.4.4", + "@commitlint/rules": "^17.4.4", + "@commitlint/types": "^17.4.4" } }, "@commitlint/load": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.4.2.tgz", - "integrity": "sha512-Si++F85rJ9t4hw6JcOw1i2h0fdpdFQt0YKwjuK4bk9KhFjyFkRxvR3SB2dPaMs+EwWlDrDBGL+ygip1QD6gmPw==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.4.4.tgz", + "integrity": "sha512-z6uFIQ7wfKX5FGBe1AkOF4l/ShOQsaa1ml/nLMkbW7R/xF8galGS7Zh0yHvzVp/srtfS0brC+0bUfQfmpMPFVQ==", "dev": true, "requires": { - "@commitlint/config-validator": "^17.4.0", + "@commitlint/config-validator": "^17.4.4", "@commitlint/execute-rule": "^17.4.0", - "@commitlint/resolve-extends": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/resolve-extends": "^17.4.4", + "@commitlint/types": "^17.4.4", "@types/node": "*", "chalk": "^4.1.0", "cosmiconfig": "^8.0.0", @@ -21776,37 +21776,37 @@ "dev": true }, "@commitlint/parse": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.4.2.tgz", - "integrity": "sha512-DK4EwqhxfXpyCA+UH8TBRIAXAfmmX4q9QRBz/2h9F9sI91yt6mltTrL6TKURMcjUVmgaB80wgS9QybNIyVBIJA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-17.4.4.tgz", + "integrity": "sha512-EKzz4f49d3/OU0Fplog7nwz/lAfXMaDxtriidyGF9PtR+SRbgv4FhsfF310tKxs6EPj8Y+aWWuX3beN5s+yqGg==", "dev": true, "requires": { - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "conventional-changelog-angular": "^5.0.11", "conventional-commits-parser": "^3.2.2" } }, "@commitlint/read": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.4.2.tgz", - "integrity": "sha512-hasYOdbhEg+W4hi0InmXHxtD/1favB4WdwyFxs1eOy/DvMw6+2IZBmATgGOlqhahsypk4kChhxjAFJAZ2F+JBg==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-17.4.4.tgz", + "integrity": "sha512-B2TvUMJKK+Svzs6eji23WXsRJ8PAD+orI44lVuVNsm5zmI7O8RSGJMvdEZEikiA4Vohfb+HevaPoWZ7PiFZ3zA==", "dev": true, "requires": { "@commitlint/top-level": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "fs-extra": "^11.0.0", "git-raw-commits": "^2.0.0", "minimist": "^1.2.6" } }, "@commitlint/resolve-extends": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.0.tgz", - "integrity": "sha512-3JsmwkrCzoK8sO22AzLBvNEvC1Pmdn/65RKXzEtQMy6oYMl0Snrq97a5bQQEFETF0VsvbtUuKttLqqgn99OXRQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-17.4.4.tgz", + "integrity": "sha512-znXr1S0Rr8adInptHw0JeLgumS11lWbk5xAWFVno+HUFVN45875kUtqjrI6AppmD3JI+4s0uZlqqlkepjJd99A==", "dev": true, "requires": { - "@commitlint/config-validator": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/config-validator": "^17.4.4", + "@commitlint/types": "^17.4.4", "import-fresh": "^3.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0", @@ -21814,15 +21814,15 @@ } }, "@commitlint/rules": { - "version": "17.4.2", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.4.2.tgz", - "integrity": "sha512-OGrPsMb9Fx3/bZ64/EzJehY9YDSGWzp81Pj+zJiY+r/NSgJI3nUYdlS37jykNIugzazdEXfMtQ10kmA+Kx2pZQ==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-17.4.4.tgz", + "integrity": "sha512-0tgvXnHi/mVcyR8Y8mjTFZIa/FEQXA4uEutXS/imH2v1UNkYDSEMsK/68wiXRpfW1euSgEdwRkvE1z23+yhNrQ==", "dev": true, "requires": { - "@commitlint/ensure": "^17.4.0", + "@commitlint/ensure": "^17.4.4", "@commitlint/message": "^17.4.2", "@commitlint/to-lines": "^17.4.0", - "@commitlint/types": "^17.4.0", + "@commitlint/types": "^17.4.4", "execa": "^5.0.0" } }, @@ -21842,9 +21842,9 @@ } }, "@commitlint/types": { - "version": "17.4.0", - "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.0.tgz", - "integrity": "sha512-2NjAnq5IcxY9kXtUeO2Ac0aPpvkuOmwbH/BxIm36XXK5LtWFObWJWjXOA+kcaABMrthjWu6la+FUpyYFMHRvbA==", + "version": "17.4.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-17.4.4.tgz", + "integrity": "sha512-amRN8tRLYOsxRr6mTnGGGvB5EmW/4DDjLMgiwK3CCVEmN6Sr/6xePGEpWaspKkckILuUORCwe6VfDBw6uj4axQ==", "dev": true, "requires": { "chalk": "^4.1.0" diff --git a/package.json b/package.json index 98251b4..16f546f 100644 --- a/package.json +++ b/package.json @@ -61,8 +61,8 @@ "universal-cookie": "4.0.4" }, "devDependencies": { - "@commitlint/cli": "17.4.2", - "@commitlint/config-angular": "17.4.2", + "@commitlint/cli": "17.4.4", + "@commitlint/config-angular": "17.4.4", "@edx/browserslist-config": "^1.1.1", "@edx/frontend-build": "12.4.19", "@edx/reactifex": "2.1.1", From 6b451a44370a06dc036b91813292c2d93adde7af Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 09:33:34 +0000 Subject: [PATCH 17/63] fix(deps): update dependency @edx/frontend-component-footer to v11.6.3 --- package-lock.json | 106 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3e1d12..946d558 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "AGPL-3.0", "dependencies": { "@edx/brand": "npm:@edx/brand-openedx@1.2.0", - "@edx/frontend-component-footer": "11.6.2", + "@edx/frontend-component-footer": "11.6.3", "@edx/frontend-component-header": "3.6.1", "@edx/frontend-platform": "3.3.1", "@edx/paragon": "^20.20.0", @@ -2600,14 +2600,14 @@ } }, "node_modules/@edx/frontend-component-footer": { - "version": "11.6.2", - "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-11.6.2.tgz", - "integrity": "sha512-inLPO4CCCvgcTsEebw80RC+HG6BUw3Qgz8ihqZgUEro14DU/ofvUXlFC5JBKturTTuEu2jpROW03cND2zxdxRQ==", + "version": "11.6.3", + "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-11.6.3.tgz", + "integrity": "sha512-5TSuPuQRrFx5m+BAHnZjxR5wrJNMTGM7wyYz8We6ae7IZCF4xZpwr7F17GVqdlKf15rUTNw64aC22nvqfKboiw==", "dependencies": { - "@fortawesome/fontawesome-svg-core": "6.2.1", - "@fortawesome/free-brands-svg-icons": "6.2.1", - "@fortawesome/free-regular-svg-icons": "6.2.1", - "@fortawesome/free-solid-svg-icons": "6.2.1", + "@fortawesome/fontawesome-svg-core": "6.3.0", + "@fortawesome/free-brands-svg-icons": "6.3.0", + "@fortawesome/free-regular-svg-icons": "6.3.0", + "@fortawesome/free-solid-svg-icons": "6.3.0", "@fortawesome/react-fontawesome": "0.2.0" }, "peerDependencies": { @@ -2618,57 +2618,57 @@ } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", - "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", + "integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==", "hasInstallScript": true, "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", - "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz", + "integrity": "sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" }, "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-brands-svg-icons": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.1.tgz", - "integrity": "sha512-L8l4MfdHPmZlJ72PvzdfwOwbwcCAL0vx48tJRnI6u1PJXh+j2f3yDoKyQgO3qjEsgD5Fr2tQV/cPP8F/k6aUig==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.3.0.tgz", + "integrity": "sha512-xI0c+a8xnKItAXCN8rZgCNCJQiVAd2Y7p9e2ND6zN3J3ekneu96qrePieJ7yA7073C1JxxoM3vH1RU7rYsaj8w==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" }, "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-regular-svg-icons": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz", - "integrity": "sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz", + "integrity": "sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" }, "engines": { "node": ">=6" } }, "node_modules/@edx/frontend-component-footer/node_modules/@fortawesome/free-solid-svg-icons": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz", - "integrity": "sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz", + "integrity": "sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" }, "engines": { "node": ">=6" @@ -21959,52 +21959,52 @@ } }, "@edx/frontend-component-footer": { - "version": "11.6.2", - "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-11.6.2.tgz", - "integrity": "sha512-inLPO4CCCvgcTsEebw80RC+HG6BUw3Qgz8ihqZgUEro14DU/ofvUXlFC5JBKturTTuEu2jpROW03cND2zxdxRQ==", + "version": "11.6.3", + "resolved": "https://registry.npmjs.org/@edx/frontend-component-footer/-/frontend-component-footer-11.6.3.tgz", + "integrity": "sha512-5TSuPuQRrFx5m+BAHnZjxR5wrJNMTGM7wyYz8We6ae7IZCF4xZpwr7F17GVqdlKf15rUTNw64aC22nvqfKboiw==", "requires": { - "@fortawesome/fontawesome-svg-core": "6.2.1", - "@fortawesome/free-brands-svg-icons": "6.2.1", - "@fortawesome/free-regular-svg-icons": "6.2.1", - "@fortawesome/free-solid-svg-icons": "6.2.1", + "@fortawesome/fontawesome-svg-core": "6.3.0", + "@fortawesome/free-brands-svg-icons": "6.3.0", + "@fortawesome/free-regular-svg-icons": "6.3.0", + "@fortawesome/free-solid-svg-icons": "6.3.0", "@fortawesome/react-fontawesome": "0.2.0" }, "dependencies": { "@fortawesome/fontawesome-common-types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", - "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", + "integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==" }, "@fortawesome/fontawesome-svg-core": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", - "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz", + "integrity": "sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" } }, "@fortawesome/free-brands-svg-icons": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.2.1.tgz", - "integrity": "sha512-L8l4MfdHPmZlJ72PvzdfwOwbwcCAL0vx48tJRnI6u1PJXh+j2f3yDoKyQgO3qjEsgD5Fr2tQV/cPP8F/k6aUig==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.3.0.tgz", + "integrity": "sha512-xI0c+a8xnKItAXCN8rZgCNCJQiVAd2Y7p9e2ND6zN3J3ekneu96qrePieJ7yA7073C1JxxoM3vH1RU7rYsaj8w==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" } }, "@fortawesome/free-regular-svg-icons": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz", - "integrity": "sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz", + "integrity": "sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" } }, "@fortawesome/free-solid-svg-icons": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz", - "integrity": "sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz", + "integrity": "sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" } } } diff --git a/package.json b/package.json index 16f546f..fa0b5a8 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ ], "dependencies": { "@edx/brand": "npm:@edx/brand-openedx@1.2.0", - "@edx/frontend-component-footer": "11.6.2", + "@edx/frontend-component-footer": "11.6.3", "@edx/frontend-component-header": "3.6.1", "@edx/frontend-platform": "3.3.1", "@edx/paragon": "^20.20.0", From f57f5c47253a01074fa06598324b33fee7791e4e Mon Sep 17 00:00:00 2001 From: David Joy Date: Tue, 28 Feb 2023 13:46:03 -0500 Subject: [PATCH 18/63] docs: update the maintaining group to openedx/2u-aperture (#703) The @edx/arch-fed group no longer exists - this repo is maintained by the @openedx/2u-aperture team. --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 1d0acab..ff7a924 100755 --- a/README.rst +++ b/README.rst @@ -3,7 +3,7 @@ frontend-app-profile ==================== -This is a micro-frontend application responsible for the display and updating of user profiles. Please tag **@edx/arch-fed** on any PRs or issues. +This is a micro-frontend application responsible for the display and updating of user profiles. Please tag **@openedx/2u-aperture** on any PRs or issues. When a user views their own profile, they're given fields to edit their full name, location, primary spoken language, education, social links, and bio. Each field also has a dropdown to select the visibility of that field - i.e., whether it can be viewed by other learners. From ddff5364ce463bbc34499b11f5422ffef671613c Mon Sep 17 00:00:00 2001 From: Maxwell Frank Date: Mon, 27 Feb 2023 20:03:25 +0000 Subject: [PATCH 19/63] feat: SkillsBuilder career interests selection --- src/skills-builder/data/actions.js | 4 +- src/skills-builder/data/constants.js | 2 +- src/skills-builder/data/reducer.js | 4 +- src/skills-builder/data/test/reducer.test.js | 4 +- .../SkillsBuilderModal.jsx | 2 +- .../select-preferences/CareerInterestCard.jsx | 35 +++++++++++ .../CareerInterestSelect.jsx | 52 ++++++++++++---- .../select-preferences/GoalSelect.jsx | 1 + .../JobTitleInstantSearch.jsx | 7 ++- .../select-preferences/JobTitleSelect.jsx | 8 ++- .../select-preferences/SelectPreferences.jsx | 23 +++---- .../select-preferences/messages.js | 4 ++ .../test/SkillsBuilder.test.jsx | 62 ++++++++++++++++++- 13 files changed, 171 insertions(+), 37 deletions(-) create mode 100644 src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx diff --git a/src/skills-builder/data/actions.js b/src/skills-builder/data/actions.js index b4df8c9..70839e5 100644 --- a/src/skills-builder/data/actions.js +++ b/src/skills-builder/data/actions.js @@ -2,7 +2,7 @@ import { SET_GOAL, SET_CURRENT_JOB_TITLE, ADD_CAREER_INTEREST, - REMOVE_CAREER_INTEREEST, + REMOVE_CAREER_INTEREST, } from './constants'; export const setGoal = (payload) => ({ @@ -21,6 +21,6 @@ export const addCareerInterest = (payload) => ({ }); export const removeCareerInterest = (payload) => ({ - type: REMOVE_CAREER_INTEREEST, + type: REMOVE_CAREER_INTEREST, payload, }); diff --git a/src/skills-builder/data/constants.js b/src/skills-builder/data/constants.js index 65847df..9bfe1ff 100644 --- a/src/skills-builder/data/constants.js +++ b/src/skills-builder/data/constants.js @@ -2,7 +2,7 @@ export const SET_GOAL = 'SET_GOAL'; export const SET_CURRENT_JOB_TITLE = 'SET_CURRENT_JOB_TITLE'; export const ADD_CAREER_INTEREST = 'ADD_CAREER_INTEREST'; -export const REMOVE_CAREER_INTEREEST = 'REMOVE_CAREER_INTEREEST'; +export const REMOVE_CAREER_INTEREST = 'REMOVE_CAREER_INTEREST'; // Stepper keys export const STEP1 = 'select-your-preferences'; diff --git a/src/skills-builder/data/reducer.js b/src/skills-builder/data/reducer.js index 6f6af67..e8876e0 100644 --- a/src/skills-builder/data/reducer.js +++ b/src/skills-builder/data/reducer.js @@ -2,7 +2,7 @@ import { SET_GOAL, SET_CURRENT_JOB_TITLE, ADD_CAREER_INTEREST, - REMOVE_CAREER_INTEREEST, + REMOVE_CAREER_INTEREST, } from './constants'; export function skillsReducer(state, action) { @@ -22,7 +22,7 @@ export function skillsReducer(state, action) { ...state, careerInterests: [...state.careerInterests, action.payload], }; - case REMOVE_CAREER_INTEREEST: + case REMOVE_CAREER_INTEREST: return { ...state, careerInterests: state.careerInterests.filter(interest => interest !== action.payload), diff --git a/src/skills-builder/data/test/reducer.test.js b/src/skills-builder/data/test/reducer.test.js index 0cfbb3c..07b11dd 100644 --- a/src/skills-builder/data/test/reducer.test.js +++ b/src/skills-builder/data/test/reducer.test.js @@ -3,7 +3,7 @@ import { SET_GOAL, SET_CURRENT_JOB_TITLE, ADD_CAREER_INTEREST, - REMOVE_CAREER_INTEREEST, + REMOVE_CAREER_INTEREST, } from '../constants'; describe('skillsReducer', () => { @@ -48,7 +48,7 @@ describe('skillsReducer', () => { }; const returnedState = skillsReducer( testStateWithInterest, - { type: REMOVE_CAREER_INTEREEST, payload: newCareerInterestPayload }, + { type: REMOVE_CAREER_INTEREST, payload: newCareerInterestPayload }, ); const finalState = { ...testStateWithInterest, diff --git a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx index 470618e..fb7df32 100644 --- a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx +++ b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx @@ -33,7 +33,7 @@ const SkillsBuilderModal = () => { diff --git a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx new file mode 100644 index 0000000..62b7a37 --- /dev/null +++ b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx @@ -0,0 +1,35 @@ +import React, { useContext } from 'react'; +import PropTypes from 'prop-types'; +import { + IconButton, Icon, +} from '@edx/paragon'; +import { useIntl } from '@edx/frontend-platform/i18n'; +import { Close } from '@edx/paragon/icons'; +import { SkillsBuilderContext } from '../../skills-builder-context'; +import { removeCareerInterest } from '../../data/actions'; +import messages from './messages'; + +const CareerInterestCard = ({ interest }) => { + const intl = useIntl(); + const { dispatch } = useContext(SkillsBuilderContext); + + return ( +
+

+ {interest} +

+ dispatch(removeCareerInterest(interest))} + /> +
+ ); +}; + +CareerInterestCard.propTypes = { + interest: PropTypes.string.isRequired, +}; + +export default CareerInterestCard; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx index 68f314f..892fb37 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx @@ -1,16 +1,46 @@ -import React from 'react'; +import React, { useContext } from 'react'; +import { getConfig } from '@edx/frontend-platform'; import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { Stack, Row, Col } from '@edx/paragon'; +import { InstantSearch } from 'react-instantsearch-hooks-web'; +import JobTitleInstantSearch from './JobTitleInstantSearch'; +import CareerInterestCard from './CareerInterestCard'; +import { addCareerInterest } from '../../data/actions'; +import { SkillsBuilderContext } from '../../skills-builder-context'; import messages from './messages'; -const CareerInterestSelect = () => ( -
-

- -

-

- JobTitleAutosuggest component can be reused here -

-
-); +const CareerInterestSelect = () => { + const { state, dispatch, algolia } = useContext(SkillsBuilderContext); + const { careerInterests } = state; + const { searchClient } = algolia; + + const handleCareerInterestSelect = (value) => { + // By checking for a value to exist, we avoid adding a null value to the careerInterests array + // The 'onSelected' function is fired during every 'onChange' event + // A null value was being passed to this function whenever the search box received input, resulting in empty cards + if (value && careerInterests.length < 3) { + dispatch(addCareerInterest(value)); + } + }; + + return ( + +

+ +

+ + + + + {careerInterests.map((interest, index) => ( + // eslint-disable-next-line react/no-array-index-key + + + + ))} + +
+ ); +}; export default CareerInterestSelect; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx index 2c2f5f6..30b1dc0 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx @@ -21,6 +21,7 @@ const GoalDropdown = () => { as="select" value={currentGoal} onChange={(e) => dispatch(setGoal(e.target.value))} + data-testid="goal-select-dropdown" > diff --git a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx index e147d5d..5b60665 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import { Form, @@ -13,9 +13,12 @@ const JobTitleInstantSearch = (props) => { const handleAutosuggestChange = (value) => { setJobInput(value); - refine(value); }; + useEffect(() => { + refine(jobInput); + }, [jobInput, refine]); + return ( { const { dispatch, algolia } = useContext(SkillsBuilderContext); const { searchClient } = algolia; + const handleCurrentJobTitleSelect = (value) => { + dispatch(setCurrentJobTitle(value)); + }; + // Below implementation sets the job title to "student" or "looking_for_work" — this overwrites any previous selection // This will need to be revisited when we decide what to do with this data const handleCheckboxChange = (e) => dispatch(setCurrentJobTitle(e.target.value)); @@ -24,7 +28,7 @@ const JobTitleSelect = () => { - dispatch(setCurrentJobTitle(value))} /> + { const { currentGoal, currentJobTitle } = state; return ( - -

+ <> +

+ - + - {currentGoal && ( - - )} + {currentGoal && ( + + )} - {currentJobTitle && ( - - )} - + {currentJobTitle && ( + + )} +
+ ); }; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/messages.js b/src/skills-builder/skills-builder-modal/select-preferences/messages.js index 76e124a..53e1551 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/messages.js +++ b/src/skills-builder/skills-builder-modal/select-preferences/messages.js @@ -61,6 +61,10 @@ const messages = defineMessages({ defaultMessage: 'What careers are you interested in?', description: 'Prompts the user to select careers they are interested in pursuing.', }, + removeCareerInterestButtonAltText: { + id: 'career.interest.remove.button.alt.text', + defaultMessage: 'Remove career interest: ', + }, }); export default messages; diff --git a/src/skills-builder/test/SkillsBuilder.test.jsx b/src/skills-builder/test/SkillsBuilder.test.jsx index 0925b15..b9b8b7b 100644 --- a/src/skills-builder/test/SkillsBuilder.test.jsx +++ b/src/skills-builder/test/SkillsBuilder.test.jsx @@ -71,14 +71,27 @@ describe('skills-builder', () => { }, ), ); - expect(screen.getByText('Next, search and select your current job title')).toBeTruthy(); + const expectedGoal = { + payload: 'I want to advance my career', + type: 'SET_GOAL', + }; + const expectedJobTitle = { + payload: 'student', + type: 'SET_CURRENT_JOB_TITLE', + }; + + const goalSelect = screen.getByTestId('goal-select-dropdown'); + fireEvent.change(goalSelect, { target: { value: 'I want to advance my career' } }); const checkbox = screen.getByRole('checkbox', { name: 'I\'m a student' }); fireEvent.click(checkbox); - expect(dispatchMock).toHaveBeenCalled(); + + expect(screen.getByText('Next, search and select your current job title')).toBeTruthy(); + expect(dispatchMock).toHaveBeenCalledWith(expectedGoal); + expect(dispatchMock).toHaveBeenCalledWith(expectedJobTitle); }); - it('should render the third prompt if a goal is selected', () => { + it('should render the third prompt if a current job title is selected', () => { render( SkillsBuilderWrapperWithContext( { @@ -93,4 +106,47 @@ describe('skills-builder', () => { ); expect(screen.getByText('What careers are you interested in?')).toBeTruthy(); }); + + it('should render a for each career interest', () => { + render( + SkillsBuilderWrapperWithContext( + { + ...contextValue, + state: { + ...contextValue.state, + currentGoal: 'I want to start my career', + currentJobTitle: 'Goblin Lackey', + careerInterests: ['Prospector', 'Mirror Breaker', 'Bombardment'], + }, + }, + ), + ); + expect(screen.getByText('Prospector')).toBeTruthy(); + expect(screen.getByText('Mirror Breaker')).toBeTruthy(); + expect(screen.getByText('Bombardment')).toBeTruthy(); + }); + + it('should remove a when the corresponding close button is selected', () => { + render( + SkillsBuilderWrapperWithContext( + { + ...contextValue, + state: { + ...contextValue.state, + currentGoal: 'I want to start my career', + currentJobTitle: 'Goblin Lackey', + careerInterests: ['Prospector', 'Mirror Breaker', 'Bombardment'], + }, + }, + ), + ); + + const expected = { + payload: 'Prospector', + type: 'REMOVE_CAREER_INTEREST', + }; + + fireEvent.click(screen.getByLabelText('Remove career interest: Prospector')); + expect(dispatchMock).toHaveBeenCalledWith(expected); + }); }); From 40225d7db385043367fe0929286cd8b0480f5049 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Sun, 5 Mar 2023 20:35:17 +0000 Subject: [PATCH 20/63] chore(i18n): update translations --- src/i18n/messages/ar.json | 17 ++++++++++++++++- src/i18n/messages/de.json | 17 ++++++++++++++++- src/i18n/messages/es_419.json | 17 ++++++++++++++++- src/i18n/messages/fr.json | 17 ++++++++++++++++- src/i18n/messages/fr_CA.json | 17 ++++++++++++++++- src/i18n/messages/hi.json | 17 ++++++++++++++++- src/i18n/messages/it.json | 17 ++++++++++++++++- src/i18n/messages/pt.json | 17 ++++++++++++++++- src/i18n/messages/ru.json | 17 ++++++++++++++++- src/i18n/messages/uk.json | 17 ++++++++++++++++- src/i18n/messages/zh_CN.json | 17 ++++++++++++++++- 11 files changed, 176 insertions(+), 11 deletions(-) diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index b2364e8..013160d 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index 4d3f107..aad2d16 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/es_419.json b/src/i18n/messages/es_419.json index a92f302..23a60f4 100644 --- a/src/i18n/messages/es_419.json +++ b/src/i18n/messages/es_419.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Dejanos ser tu guía", "go.back.button": "Volver Atrás", "next.step.button": "Próximo paso", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index 0010d52..43f91b9 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/fr_CA.json b/src/i18n/messages/fr_CA.json index cc18b40..be69aa7 100644 --- a/src/i18n/messages/fr_CA.json +++ b/src/i18n/messages/fr_CA.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Laissez EDUlib être votre guide", "go.back.button": "Retour", "next.step.button": "Prochaine étape", - "exit.button": "Sortie" + "exit.button": "Sortie", + "select.preferences": "Sélectionnez les préférences", + "review.results": "Examiner les résultats", + "skills.builder.description": "Trouvez les bons cours et programmes qui vous aideront à atteindre vos objectifs.", + "learning.goal.prompt": "Tout d'abord, dites-nous ce que vous voulez réaliser", + "select.learning.goal": "Sélectionnez un objectif", + "learning.goal.start_career": "Je veux commencer ma carrière", + "learning.goal.advance_career": "Je veux faire progresser ma carrière", + "learning.goal.change_career": "Je veux changer de métier", + "learning.goal.something.new": "Je veux apprendre quelque chose de nouveau", + "learning.goal.something.else": "Autre chose", + "job.title.prompt": "Ensuite, recherchez et sélectionnez votre titre de poste actuel", + "student.checkbox.prompt": "Je suis étudiant.e", + "currently.looking.checkbox.prompt": "Je suis actuellement à la recherche d'un emploi", + "career.interest.prompt": "Quels métiers vous intéressent ?", + "career.interest.remove.button.alt.text": "Supprimer l'intérêt professionnel :" } \ No newline at end of file diff --git a/src/i18n/messages/hi.json b/src/i18n/messages/hi.json index 4d3f107..aad2d16 100644 --- a/src/i18n/messages/hi.json +++ b/src/i18n/messages/hi.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/it.json b/src/i18n/messages/it.json index 4d3f107..aad2d16 100644 --- a/src/i18n/messages/it.json +++ b/src/i18n/messages/it.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index 4d3f107..aad2d16 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index 4d3f107..aad2d16 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/uk.json b/src/i18n/messages/uk.json index 4d3f107..aad2d16 100644 --- a/src/i18n/messages/uk.json +++ b/src/i18n/messages/uk.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file diff --git a/src/i18n/messages/zh_CN.json b/src/i18n/messages/zh_CN.json index 4d3f107..aad2d16 100644 --- a/src/i18n/messages/zh_CN.json +++ b/src/i18n/messages/zh_CN.json @@ -58,5 +58,20 @@ "skills.builder.header.subheading": "Let edX be your guide", "go.back.button": "Go Back", "next.step.button": "Next Step", - "exit.button": "Exit" + "exit.button": "Exit", + "select.preferences": "Select preferences", + "review.results": "Review results", + "skills.builder.description": "Find the right courses and programs that help you reach your goals.", + "learning.goal.prompt": "First, tell us what you want to achieve", + "select.learning.goal": "Select a goal", + "learning.goal.start_career": "I want to start my career", + "learning.goal.advance_career": "I want to advance my career", + "learning.goal.change_career": "I want to change careers", + "learning.goal.something.new": "I want to learn something new", + "learning.goal.something.else": "Something else", + "job.title.prompt": "Next, search and select your current job title", + "student.checkbox.prompt": "I'm a student", + "currently.looking.checkbox.prompt": "I'm currently looking for work", + "career.interest.prompt": "What careers are you interested in?", + "career.interest.remove.button.alt.text": "Remove career interest: " } \ No newline at end of file From b1fe21cdedf2caaa0b629bc7e07451b99292a947 Mon Sep 17 00:00:00 2001 From: Maxwell Frank Date: Mon, 27 Feb 2023 20:03:25 +0000 Subject: [PATCH 21/63] feat: SkillsBuilder jobs with related skills --- .../SkillsBuilderModal.jsx | 18 ++-- .../select-preferences/CareerInterestCard.jsx | 4 +- .../CareerInterestSelect.jsx | 10 ++- .../select-preferences/GoalSelect.jsx | 20 +++-- .../JobTitleInstantSearch.jsx | 7 ++ .../select-preferences/JobTitleSelect.jsx | 23 +++-- .../select-preferences/SelectPreferences.jsx | 11 +-- .../select-preferences/messages.js | 5 ++ .../RelatedSkillsSelectableBoxSet.jsx | 57 +++++++++++++ .../view-results/ViewResults.jsx | 83 ++++++++++++++++++- .../view-results/messages.js | 21 +++++ .../test/SkillsBuilder.test.jsx | 47 ++++++++++- .../test/__mocks__/jobSkills.mockData.js | 40 +++++++++ 13 files changed, 302 insertions(+), 44 deletions(-) create mode 100644 src/skills-builder/skills-builder-modal/view-results/RelatedSkillsSelectableBoxSet.jsx create mode 100644 src/skills-builder/skills-builder-modal/view-results/messages.js create mode 100644 src/skills-builder/test/__mocks__/jobSkills.mockData.js diff --git a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx index fb7df32..3c08231 100644 --- a/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx +++ b/src/skills-builder/skills-builder-modal/SkillsBuilderModal.jsx @@ -2,7 +2,7 @@ import React, { useState, useContext } from 'react'; import { Button, Container, Stepper, ModalDialog, } from '@edx/paragon'; -import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { useHistory } from 'react-router'; import { STEP1, STEP2, @@ -17,7 +17,7 @@ import ViewResults from './view-results/ViewResults'; import headerImage from '../images/headerImage.png'; const SkillsBuilderModal = () => { - const intl = useIntl(); + const { formatMessage } = useIntl(); const { state } = useContext(SkillsBuilderContext); const { careerInterests } = state; const [currentStep, setCurrentStep] = useState(STEP1); @@ -49,12 +49,12 @@ const SkillsBuilderModal = () => { - - + + - + @@ -63,14 +63,14 @@ const SkillsBuilderModal = () => { @@ -78,11 +78,11 @@ const SkillsBuilderModal = () => { variant="outline-primary" onClick={() => setCurrentStep(STEP1)} > - + {formatMessage(messages.goBackButton)} diff --git a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx index 62b7a37..a0d250b 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestCard.jsx @@ -10,7 +10,7 @@ import { removeCareerInterest } from '../../data/actions'; import messages from './messages'; const CareerInterestCard = ({ interest }) => { - const intl = useIntl(); + const { formatMessage } = useIntl(); const { dispatch } = useContext(SkillsBuilderContext); return ( @@ -21,7 +21,7 @@ const CareerInterestCard = ({ interest }) => { dispatch(removeCareerInterest(interest))} /> diff --git a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx index 892fb37..74fbd1f 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/CareerInterestSelect.jsx @@ -1,6 +1,6 @@ import React, { useContext } from 'react'; import { getConfig } from '@edx/frontend-platform'; -import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { Stack, Row, Col } from '@edx/paragon'; import { InstantSearch } from 'react-instantsearch-hooks-web'; import JobTitleInstantSearch from './JobTitleInstantSearch'; @@ -10,6 +10,7 @@ import { SkillsBuilderContext } from '../../skills-builder-context'; import messages from './messages'; const CareerInterestSelect = () => { + const { formatMessage } = useIntl(); const { state, dispatch, algolia } = useContext(SkillsBuilderContext); const { careerInterests } = state; const { searchClient } = algolia; @@ -26,10 +27,13 @@ const CareerInterestSelect = () => { return (

- + {formatMessage(messages.careerInterestPrompt)}

- + {careerInterests.map((interest, index) => ( diff --git a/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx index 30b1dc0..77f5fb0 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/GoalSelect.jsx @@ -3,19 +3,21 @@ import { Form, Stack, } from '@edx/paragon'; -import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { setGoal } from '../../data/actions'; import { SkillsBuilderContext } from '../../skills-builder-context'; import messages from './messages'; const GoalDropdown = () => { - const intl = useIntl(); + const { formatMessage } = useIntl(); const { state, dispatch } = useContext(SkillsBuilderContext); const { currentGoal } = state; return ( -

+

+ {formatMessage(messages.learningGoalPrompt)} +

{ onChange={(e) => dispatch(setGoal(e.target.value))} data-testid="goal-select-dropdown" > - - - - - - + + + + + +
diff --git a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx index 5b60665..5c29d7b 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleInstantSearch.jsx @@ -25,6 +25,8 @@ const JobTitleInstantSearch = (props) => { onChange={handleAutosuggestChange} name="job-title-suggest" onSelected={props.onSelected} + autoComplete="off" + placeholder={props.placeholder} > {hits.map(job => ( @@ -35,8 +37,13 @@ const JobTitleInstantSearch = (props) => { ); }; +JobTitleInstantSearch.defaultProps = { + placeholder: '', +}; + JobTitleInstantSearch.propTypes = { onSelected: PropTypes.func.isRequired, + placeholder: PropTypes.string, }; export default JobTitleInstantSearch; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx index 3f625f6..35552ff 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/JobTitleSelect.jsx @@ -3,7 +3,7 @@ import { getConfig } from '@edx/frontend-platform'; import { Form, Stack, } from '@edx/paragon'; -import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { InstantSearch } from 'react-instantsearch-hooks-web'; import { setCurrentJobTitle } from '../../data/actions'; import { SkillsBuilderContext } from '../../skills-builder-context'; @@ -11,35 +11,40 @@ import JobTitleInstantSearch from './JobTitleInstantSearch'; import messages from './messages'; const JobTitleSelect = () => { - const { dispatch, algolia } = useContext(SkillsBuilderContext); + const { formatMessage } = useIntl(); + const { state, dispatch, algolia } = useContext(SkillsBuilderContext); const { searchClient } = algolia; + const { currentJobTitle } = state; const handleCurrentJobTitleSelect = (value) => { dispatch(setCurrentJobTitle(value)); }; - // Below implementation sets the job title to "student" or "looking_for_work" — this overwrites any previous selection + // Below implementation sets the job title to "Student" or "Looking for work" — this overwrites any previous selection // This will need to be revisited when we decide what to do with this data const handleCheckboxChange = (e) => dispatch(setCurrentJobTitle(e.target.value)); return (

- + {formatMessage(messages.jobTitlePrompt)}

- + - - + + {formatMessage(messages.studentCheckboxPrompt)} - - + + {formatMessage(messages.currentlyLookingCheckboxPrompt)} diff --git a/src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx b/src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx index 7eee9a6..90f65a5 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx +++ b/src/skills-builder/skills-builder-modal/select-preferences/SelectPreferences.jsx @@ -2,7 +2,7 @@ import React, { useContext } from 'react'; import { Stack, } from '@edx/paragon'; -import { FormattedMessage } from '@edx/frontend-platform/i18n'; +import { useIntl } from '@edx/frontend-platform/i18n'; import { SkillsBuilderContext } from '../../skills-builder-context'; import GoalSelect from './GoalSelect'; import JobTitleSelect from './JobTitleSelect'; @@ -10,13 +10,14 @@ import CareerInterestSelect from './CareerInterestSelect'; import messages from './messages'; const SelectPreferences = () => { + const { formatMessage } = useIntl(); const { state } = useContext(SkillsBuilderContext); const { currentGoal, currentJobTitle } = state; return ( - <> -

- + +

+ {formatMessage(messages.skillsBuilderDescription)}

@@ -30,7 +31,7 @@ const SelectPreferences = () => { )} - +
); }; diff --git a/src/skills-builder/skills-builder-modal/select-preferences/messages.js b/src/skills-builder/skills-builder-modal/select-preferences/messages.js index 53e1551..5efbb80 100644 --- a/src/skills-builder/skills-builder-modal/select-preferences/messages.js +++ b/src/skills-builder/skills-builder-modal/select-preferences/messages.js @@ -61,6 +61,11 @@ const messages = defineMessages({ defaultMessage: 'What careers are you interested in?', description: 'Prompts the user to select careers they are interested in pursuing.', }, + careerInterestInputPlaceholder: { + id: 'career.interest.input.placeholder', + defaultMessage: 'Select up to 3 new job titles', + description: 'Placeholder text for the career interest input control.', + }, removeCareerInterestButtonAltText: { id: 'career.interest.remove.button.alt.text', defaultMessage: 'Remove career interest: ', diff --git a/src/skills-builder/skills-builder-modal/view-results/RelatedSkillsSelectableBoxSet.jsx b/src/skills-builder/skills-builder-modal/view-results/RelatedSkillsSelectableBoxSet.jsx new file mode 100644 index 0000000..1da521c --- /dev/null +++ b/src/skills-builder/skills-builder-modal/view-results/RelatedSkillsSelectableBoxSet.jsx @@ -0,0 +1,57 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { + SelectableBox, Chip, Stack, useMediaQuery, breakpoints, +} from '@edx/paragon'; +import { useIntl } from '@edx/frontend-platform/i18n'; +import messages from './messages'; + +const RelatedSkillsSelectableBoxSet = ({ jobSkillsList, selectedJobTitle, onChange }) => { + const { formatMessage } = useIntl(); + const isExtraSmall = useMediaQuery({ maxWidth: breakpoints.extraSmall.maxWidth }); + + const renderTopFiveSkills = (skills) => { + const topFiveSkills = skills.sort((a, b) => b.significance - a.significance).slice(0, 5); + return ( + topFiveSkills.map(skill => ( + + {skill.name} + + )) + ); + }; + + return ( + + {jobSkillsList.map(job => ( + +

{job.name}

+ +

{formatMessage(messages.relatedSkillsHeading)}

+ {renderTopFiveSkills(job.skills)} +
+
+ ))} +
+ ); +}; + +RelatedSkillsSelectableBoxSet.propTypes = { + jobSkillsList: PropTypes.arrayOf(PropTypes.shape({})).isRequired, + selectedJobTitle: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, +}; + +export default RelatedSkillsSelectableBoxSet; diff --git a/src/skills-builder/skills-builder-modal/view-results/ViewResults.jsx b/src/skills-builder/skills-builder-modal/view-results/ViewResults.jsx index 3477aeb..3879fda 100644 --- a/src/skills-builder/skills-builder-modal/view-results/ViewResults.jsx +++ b/src/skills-builder/skills-builder-modal/view-results/ViewResults.jsx @@ -1,7 +1,82 @@ -import React from 'react'; +import React, { useContext, useEffect, useState } from 'react'; +import { + Stack, Row, Alert, Spinner, +} from '@edx/paragon'; +import { useIntl } from '@edx/frontend-platform/i18n'; +import { CheckCircle } from '@edx/paragon/icons'; +import { SkillsBuilderContext } from '../../skills-builder-context'; +import RelatedSkillsSelectableBoxSet from './RelatedSkillsSelectableBoxSet'; +import { searchJobs, getProductRecommendations } from '../../utils/search'; +import messages from './messages'; -const ViewResults = () => ( -

Results will render on this step

-); +const ViewResults = () => { + const { formatMessage } = useIntl(); + const { algolia, state } = useContext(SkillsBuilderContext); + const { jobSearchIndex, productSearchIndex } = algolia; + const { careerInterests } = state; + + const [selectedJobTitle, setSelectedJobTitle] = useState(''); + const [jobSkillsList, setJobSkillsList] = useState([]); + // eslint-disable-next-line no-unused-vars + const [courseRecommendations, setCourseRecommendations] = useState([]); + const [isLoading, setIsLoading] = useState(true); + + useEffect(() => { + const getJobs = async () => { + // fetch list of jobs with related skills + const jobInfo = await searchJobs(jobSearchIndex, careerInterests); + + // fetch course recommendations based on related skills for each job + const results = await Promise.all(jobInfo.map(async (job) => { + const formattedSkills = job.skills.map(skill => skill.name); + + const recommendations = await getProductRecommendations(productSearchIndex, 'course', formattedSkills); + + const data = { + id: job.id, + name: job.name, + recommendations, + }; + + return data; + })); + + setJobSkillsList(jobInfo); + setSelectedJobTitle(jobInfo[0].name); + setCourseRecommendations(results); + setIsLoading(false); + }; + getJobs(); + }, [careerInterests, jobSearchIndex, productSearchIndex]); + + return ( + isLoading ? ( + + + + ) : ( + + + + {formatMessage(messages.matchesFoundSuccessAlert)} + + + + setSelectedJobTitle(e.target.value)} + /> + + ) + ); +}; export default ViewResults; diff --git a/src/skills-builder/skills-builder-modal/view-results/messages.js b/src/skills-builder/skills-builder-modal/view-results/messages.js new file mode 100644 index 0000000..0fc53ce --- /dev/null +++ b/src/skills-builder/skills-builder-modal/view-results/messages.js @@ -0,0 +1,21 @@ +import { defineMessages } from '@edx/frontend-platform/i18n'; + +const messages = defineMessages({ + matchesFoundSuccessAlert: { + id: 'matches.found.success.alert', + defaultMessage: 'We found skills and courses that match your preferences!', + description: 'Success alert message to display when recommendations are presented to the learner.', + }, + relatedSkillsHeading: { + id: 'related.skills.heading', + defaultMessage: 'Related Skills', + description: 'Heading text for a selectable box that displays related skills for a corresponding selected job title.', + }, + relatedSkillsSelectableBoxLabelText: { + id: 'related.skills.selectable.box.label.text', + defaultMessage: 'Related skills:', + description: 'Label text for a selectable box that displays related skills for a corresponding selected job title.', + }, +}); + +export default messages; diff --git a/src/skills-builder/test/SkillsBuilder.test.jsx b/src/skills-builder/test/SkillsBuilder.test.jsx index b9b8b7b..30ddd4f 100644 --- a/src/skills-builder/test/SkillsBuilder.test.jsx +++ b/src/skills-builder/test/SkillsBuilder.test.jsx @@ -8,15 +8,29 @@ import { SkillsBuilder } from '..'; import { SkillsBuilderModal } from '../skills-builder-modal'; import { SkillsBuilderProvider, SkillsBuilderContext } from '../skills-builder-context'; import { skillsInitialState } from '../data/reducer'; +import { mockData } from './__mocks__/jobSkills.mockData'; +import { getProductRecommendations, searchJobs, useAlgoliaSearch } from '../utils/search'; + +const dispatchMock = jest.fn(); + +jest.mock('@edx/frontend-platform/logging'); jest.mock('react-instantsearch-hooks-web', () => ({ // eslint-disable-next-line react/prop-types InstantSearch: ({ children }) => (
{children}
), useSearchBox: jest.fn(() => ({ refine: jest.fn() })), - useHits: jest.fn(() => ({ hits: [{ name: 'Text File Engineer' }, { name: 'Screen Viewer' }] })), + useHits: jest.fn(() => ({ hits: mockData.hits })), })); -const dispatchMock = jest.fn(); +jest.mock('../utils/search', () => ({ + searchJobs: jest.fn(), + getProductRecommendations: jest.fn(), + useAlgoliaSearch: jest.fn(), +})); + +searchJobs.mockReturnValue(mockData.searchJobs); +getProductRecommendations.mockReturnValue(mockData.productRecommendations); +useAlgoliaSearch.mockReturnValue(mockData.useAlgoliaSearch); const contextValue = { state: { @@ -26,6 +40,8 @@ const contextValue = { algolia: { // Without this, tests would fail to destructure `searchClient` in the component searchClient: {}, + productSearchIndex: {}, + jobSearchIndex: {}, }, }; @@ -76,7 +92,7 @@ describe('skills-builder', () => { type: 'SET_GOAL', }; const expectedJobTitle = { - payload: 'student', + payload: 'Student', type: 'SET_CURRENT_JOB_TITLE', }; @@ -149,4 +165,29 @@ describe('skills-builder', () => { fireEvent.click(screen.getByLabelText('Remove career interest: Prospector')); expect(dispatchMock).toHaveBeenCalledWith(expected); }); + + it('should render a for each career interest the learner has submitted', async () => { + render( + SkillsBuilderWrapperWithContext( + { + ...contextValue, + state: { + ...contextValue.state, + currentGoal: 'I want to start my career', + currentJobTitle: 'Goblin Lackey', + careerInterests: ['Prospector'], + }, + }, + ), + ); + await act(async () => { + fireEvent.click(screen.getByRole('button', { name: 'Next Step' })); + }); + + const chipComponents = document.querySelectorAll('.pgn__chip'); + expect(chipComponents[0].textContent).toEqual('finding shiny things'); + expect(chipComponents[1].textContent).toEqual('mining'); + + expect(screen.getByText('Prospector')).toBeTruthy(); + }); }); diff --git a/src/skills-builder/test/__mocks__/jobSkills.mockData.js b/src/skills-builder/test/__mocks__/jobSkills.mockData.js new file mode 100644 index 0000000..5150dec --- /dev/null +++ b/src/skills-builder/test/__mocks__/jobSkills.mockData.js @@ -0,0 +1,40 @@ +export const mockData = { + hits: [ + { + id: 0, + name: 'Text File Engineer' + }, + { + id: 1, + name: 'Screen Viewer' + }, + ], + searchJobs: [ + { + id: 0, + name: 'Prospector', + skills: [ + { id: 0, + name: 'mining', + significance: 50, + }, + { id: 1, + name: 'finding shiny things', + significance: 100, + }], + }, + ], + productRecommendations: [ + { + id: 0, + name: 'Prospector', + recommendations: [{ name: 'Mining with the Mons' }, { name: 'The Art of Warren Upkeep' }], + }, + { + id: 1, + name: 'Mirror Breaker', + recommendations: [{ name: 'Mirror Breaking 101' }], + }, + ], + useAlgoliaSearch: [{}, {}, {}], +}; From 65971820d4a585b6e337dcc7c3d8387971831bd4 Mon Sep 17 00:00:00 2001 From: Jenkins Date: Sun, 12 Mar 2023 20:35:18 +0000 Subject: [PATCH 22/63] chore(i18n): update translations --- src/i18n/messages/ar.json | 6 +++++- src/i18n/messages/de.json | 6 +++++- src/i18n/messages/es_419.json | 36 +++++++++++++++++++---------------- src/i18n/messages/fr.json | 6 +++++- src/i18n/messages/fr_CA.json | 6 +++++- src/i18n/messages/hi.json | 6 +++++- src/i18n/messages/it.json | 6 +++++- src/i18n/messages/pt.json | 6 +++++- src/i18n/messages/ru.json | 6 +++++- src/i18n/messages/uk.json | 6 +++++- src/i18n/messages/zh_CN.json | 6 +++++- 11 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index 013160d..de850e0 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index aad2d16..f1a771f 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/es_419.json b/src/i18n/messages/es_419.json index 23a60f4..09a47b0 100644 --- a/src/i18n/messages/es_419.json +++ b/src/i18n/messages/es_419.json @@ -58,20 +58,24 @@ "skills.builder.header.subheading": "Dejanos ser tu guía", "go.back.button": "Volver Atrás", "next.step.button": "Próximo paso", - "exit.button": "Exit", - "select.preferences": "Select preferences", - "review.results": "Review results", - "skills.builder.description": "Find the right courses and programs that help you reach your goals.", - "learning.goal.prompt": "First, tell us what you want to achieve", - "select.learning.goal": "Select a goal", - "learning.goal.start_career": "I want to start my career", - "learning.goal.advance_career": "I want to advance my career", - "learning.goal.change_career": "I want to change careers", - "learning.goal.something.new": "I want to learn something new", - "learning.goal.something.else": "Something else", - "job.title.prompt": "Next, search and select your current job title", - "student.checkbox.prompt": "I'm a student", - "currently.looking.checkbox.prompt": "I'm currently looking for work", - "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "exit.button": "Salida", + "select.preferences": "Seleccionar preferencias", + "review.results": "Revisar resultados", + "skills.builder.description": "Encontrar los cursos y programas adecuados que lo ayuden a alcanzar sus metas.", + "learning.goal.prompt": "Primero, contar qué quieres lograr", + "select.learning.goal": "Seleccionar una meta", + "learning.goal.start_career": "Quiero empezar mi carrera", + "learning.goal.advance_career": "Quiero avanzar en mi carrera", + "learning.goal.change_career": "Quiero cambiar de carrera", + "learning.goal.something.new": "Quiero aprender algo nuevo", + "learning.goal.something.else": "Algo más", + "job.title.prompt": "A continuación, busque y seleccione su título de trabajo actual", + "student.checkbox.prompt": "Soy un estudiante", + "currently.looking.checkbox.prompt": "Actualmente estoy buscando trabajo", + "career.interest.prompt": "¿Qué carreras te interesan?", + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Eliminar interés profesional:", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index 43f91b9..f5bbe7d 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/fr_CA.json b/src/i18n/messages/fr_CA.json index be69aa7..5af0dac 100644 --- a/src/i18n/messages/fr_CA.json +++ b/src/i18n/messages/fr_CA.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "Je suis étudiant.e", "currently.looking.checkbox.prompt": "Je suis actuellement à la recherche d'un emploi", "career.interest.prompt": "Quels métiers vous intéressent ?", - "career.interest.remove.button.alt.text": "Supprimer l'intérêt professionnel :" + "career.interest.input.placeholder": "Sélectionnez jusqu'à 3 nouveaux intitulés de poste", + "career.interest.remove.button.alt.text": "Supprimer l'intérêt professionnel :", + "matches.found.success.alert": "Nous avons trouvé des compétences et des cours qui correspondent à vos préférences !", + "related.skills.heading": "Compétences connexes", + "related.skills.selectable.box.label.text": "Compétences connexes:" } \ No newline at end of file diff --git a/src/i18n/messages/hi.json b/src/i18n/messages/hi.json index aad2d16..f1a771f 100644 --- a/src/i18n/messages/hi.json +++ b/src/i18n/messages/hi.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/it.json b/src/i18n/messages/it.json index aad2d16..f1a771f 100644 --- a/src/i18n/messages/it.json +++ b/src/i18n/messages/it.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index aad2d16..f1a771f 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index aad2d16..f1a771f 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/uk.json b/src/i18n/messages/uk.json index aad2d16..f1a771f 100644 --- a/src/i18n/messages/uk.json +++ b/src/i18n/messages/uk.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file diff --git a/src/i18n/messages/zh_CN.json b/src/i18n/messages/zh_CN.json index aad2d16..f1a771f 100644 --- a/src/i18n/messages/zh_CN.json +++ b/src/i18n/messages/zh_CN.json @@ -73,5 +73,9 @@ "student.checkbox.prompt": "I'm a student", "currently.looking.checkbox.prompt": "I'm currently looking for work", "career.interest.prompt": "What careers are you interested in?", - "career.interest.remove.button.alt.text": "Remove career interest: " + "career.interest.input.placeholder": "Select up to 3 new job titles", + "career.interest.remove.button.alt.text": "Remove career interest: ", + "matches.found.success.alert": "We found skills and courses that match your preferences!", + "related.skills.heading": "Related Skills", + "related.skills.selectable.box.label.text": "Related skills:" } \ No newline at end of file From f55b304732c09af0dd6fcced557ff4bebfe9d7c3 Mon Sep 17 00:00:00 2001 From: Mashal Malik <107556986+Mashal-m@users.noreply.github.com> Date: Mon, 13 Mar 2023 10:45:28 +0500 Subject: [PATCH 23/63] refactor: remove unused tranisfex v2 url (#704) --- Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/Makefile b/Makefile index fa21000..1ca691e 100644 --- a/Makefile +++ b/Makefile @@ -5,9 +5,6 @@ transifex_langs = "ar,fr,es_419,zh_CN,pt,it,de,uk,ru,hi,fr_CA" transifex_utils = ./node_modules/.bin/transifex-utils.js i18n = ./src/i18n transifex_input = $(i18n)/transifex_input.json -tx_url1 = https://www.transifex.com/api/2/project/edx-platform/resource/$(transifex_resource)/translation/en/strings/ -tx_url2 = https://www.transifex.com/api/2/project/edx-platform/resource/$(transifex_resource)/source/ - # This directory must match .babelrc . transifex_temp = ./temp/babel-plugin-react-intl From ab80fd7671f03a12d17002e1f2cb707472c908b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Mar 2023 10:03:03 +0000 Subject: [PATCH 24/63] fix(deps): update dependency @edx/frontend-component-header to v3.6.4 --- package-lock.json | 142 ++++++++++++++++++++++++++++++++++++++-------- package.json | 2 +- 2 files changed, 120 insertions(+), 24 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9400d6a..fe4e5af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "@edx/brand": "npm:@edx/brand-openedx@1.2.0", "@edx/frontend-component-footer": "11.6.3", - "@edx/frontend-component-header": "3.6.1", + "@edx/frontend-component-header": "3.6.4", "@edx/frontend-platform": "3.3.1", "@edx/paragon": "^20.20.0", "@fortawesome/fontawesome-svg-core": "1.2.36", @@ -2695,15 +2695,15 @@ } }, "node_modules/@edx/frontend-component-header": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-3.6.1.tgz", - "integrity": "sha512-32PBbt9UPIw0rP5X8g1UOmJ8Nl5ncCkXzPgu6GpEsXVs8YQfekFyL7iQVnzwsuNnI/T3M7Ru/GQR9lXXEoXrHA==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-3.6.4.tgz", + "integrity": "sha512-PXQm/tt8SF0xbQjZUjGROwexzH0IOLA55mMIa8A/87CKqx6IgXtg9zB7RcJchsRHFevkkH6loOJo02bOb081aw==", "dependencies": { - "@edx/paragon": "20.27.0", - "@fortawesome/fontawesome-svg-core": "1.2.36", - "@fortawesome/free-brands-svg-icons": "5.15.4", - "@fortawesome/free-regular-svg-icons": "5.15.4", - "@fortawesome/free-solid-svg-icons": "5.15.4", + "@edx/paragon": "20.28.4", + "@fortawesome/fontawesome-svg-core": "6.3.0", + "@fortawesome/free-brands-svg-icons": "6.3.0", + "@fortawesome/free-regular-svg-icons": "6.3.0", + "@fortawesome/free-solid-svg-icons": "6.3.0", "@fortawesome/react-fontawesome": "^0.2.0", "babel-polyfill": "6.26.0", "react-responsive": "8.2.0", @@ -2716,6 +2716,63 @@ "react-dom": "^16.9.0" } }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", + "integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==", + "hasInstallScript": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz", + "integrity": "sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-brands-svg-icons": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.3.0.tgz", + "integrity": "sha512-xI0c+a8xnKItAXCN8rZgCNCJQiVAd2Y7p9e2ND6zN3J3ekneu96qrePieJ7yA7073C1JxxoM3vH1RU7rYsaj8w==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-regular-svg-icons": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz", + "integrity": "sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz", + "integrity": "sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA==", + "hasInstallScript": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.3.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/@edx/frontend-platform": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-3.3.1.tgz", @@ -2805,9 +2862,9 @@ } }, "node_modules/@edx/paragon": { - "version": "20.27.0", - "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.27.0.tgz", - "integrity": "sha512-jy62ZEBdAVlsP6tAm1/YDyMtc9fiD47H00whoW+y2Z+lLZqPsv6D5boIPQIcdBeg0W4f2gCU4TEy2+b2q8mYGA==", + "version": "20.28.4", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.4.tgz", + "integrity": "sha512-JiEAUaEuOnHB/zC8h9d5f3AwchREiHFKbXFm7JpXNcvXpkTj0TTKTCS6zcfwZeDl77q/+Rx6Js7SpSE2EzAtDg==", "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", @@ -22208,19 +22265,58 @@ } }, "@edx/frontend-component-header": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-3.6.1.tgz", - "integrity": "sha512-32PBbt9UPIw0rP5X8g1UOmJ8Nl5ncCkXzPgu6GpEsXVs8YQfekFyL7iQVnzwsuNnI/T3M7Ru/GQR9lXXEoXrHA==", + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/@edx/frontend-component-header/-/frontend-component-header-3.6.4.tgz", + "integrity": "sha512-PXQm/tt8SF0xbQjZUjGROwexzH0IOLA55mMIa8A/87CKqx6IgXtg9zB7RcJchsRHFevkkH6loOJo02bOb081aw==", "requires": { - "@edx/paragon": "20.27.0", - "@fortawesome/fontawesome-svg-core": "1.2.36", - "@fortawesome/free-brands-svg-icons": "5.15.4", - "@fortawesome/free-regular-svg-icons": "5.15.4", - "@fortawesome/free-solid-svg-icons": "5.15.4", + "@edx/paragon": "20.28.4", + "@fortawesome/fontawesome-svg-core": "6.3.0", + "@fortawesome/free-brands-svg-icons": "6.3.0", + "@fortawesome/free-regular-svg-icons": "6.3.0", + "@fortawesome/free-solid-svg-icons": "6.3.0", "@fortawesome/react-fontawesome": "^0.2.0", "babel-polyfill": "6.26.0", "react-responsive": "8.2.0", "react-transition-group": "4.4.5" + }, + "dependencies": { + "@fortawesome/fontawesome-common-types": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", + "integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==" + }, + "@fortawesome/fontawesome-svg-core": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz", + "integrity": "sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.3.0" + } + }, + "@fortawesome/free-brands-svg-icons": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.3.0.tgz", + "integrity": "sha512-xI0c+a8xnKItAXCN8rZgCNCJQiVAd2Y7p9e2ND6zN3J3ekneu96qrePieJ7yA7073C1JxxoM3vH1RU7rYsaj8w==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.3.0" + } + }, + "@fortawesome/free-regular-svg-icons": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz", + "integrity": "sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.3.0" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz", + "integrity": "sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA==", + "requires": { + "@fortawesome/fontawesome-common-types": "6.3.0" + } + } } }, "@edx/frontend-platform": { @@ -22293,9 +22389,9 @@ } }, "@edx/paragon": { - "version": "20.27.0", - "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.27.0.tgz", - "integrity": "sha512-jy62ZEBdAVlsP6tAm1/YDyMtc9fiD47H00whoW+y2Z+lLZqPsv6D5boIPQIcdBeg0W4f2gCU4TEy2+b2q8mYGA==", + "version": "20.28.4", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.4.tgz", + "integrity": "sha512-JiEAUaEuOnHB/zC8h9d5f3AwchREiHFKbXFm7JpXNcvXpkTj0TTKTCS6zcfwZeDl77q/+Rx6Js7SpSE2EzAtDg==", "requires": { "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", diff --git a/package.json b/package.json index 9baf809..beb1c93 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "dependencies": { "@edx/brand": "npm:@edx/brand-openedx@1.2.0", "@edx/frontend-component-footer": "11.6.3", - "@edx/frontend-component-header": "3.6.1", + "@edx/frontend-component-header": "3.6.4", "@edx/frontend-platform": "3.3.1", "@edx/paragon": "^20.20.0", "@fortawesome/fontawesome-svg-core": "1.2.36", From 650d3d469f946ff59faa39552b846f347acc9be2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 05:35:26 +0000 Subject: [PATCH 25/63] fix(deps): update dependency @edx/paragon to v20.28.5 --- package-lock.json | 142 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe4e5af..511f38a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2716,6 +2716,54 @@ "react-dom": "^16.9.0" } }, + "node_modules/@edx/frontend-component-header/node_modules/@edx/paragon": { + "version": "20.28.4", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.4.tgz", + "integrity": "sha512-JiEAUaEuOnHB/zC8h9d5f3AwchREiHFKbXFm7JpXNcvXpkTj0TTKTCS6zcfwZeDl77q/+Rx6Js7SpSE2EzAtDg==", + "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.1.1", + "@fortawesome/react-fontawesome": "^0.1.18", + "@popperjs/core": "^2.11.4", + "bootstrap": "^4.6.2", + "classnames": "^2.3.1", + "email-prop-type": "^3.0.0", + "file-selector": "^0.6.0", + "font-awesome": "^4.7.0", + "glob": "^8.0.3", + "lodash.uniqby": "^4.7.0", + "mailto-link": "^2.0.0", + "prop-types": "^15.8.1", + "react-bootstrap": "^1.6.5", + "react-dropzone": "^14.2.1", + "react-focus-on": "^3.5.4", + "react-loading-skeleton": "^3.1.0", + "react-popper": "^2.2.5", + "react-proptype-conditional-require": "^1.0.4", + "react-responsive": "^8.2.0", + "react-table": "^7.7.0", + "react-transition-group": "^4.4.2", + "tabbable": "^5.3.3", + "uncontrollable": "^7.2.1", + "uuid": "^9.0.0" + }, + "peerDependencies": { + "react": "^16.8.6 || ^17.0.0", + "react-dom": "^16.8.6 || ^17.0.0", + "react-intl": "^5.25.1" + } + }, + "node_modules/@edx/frontend-component-header/node_modules/@edx/paragon/node_modules/@fortawesome/react-fontawesome": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz", + "integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.x" + } + }, "node_modules/@edx/frontend-component-header/node_modules/@fortawesome/fontawesome-common-types": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", @@ -2773,6 +2821,14 @@ "node": ">=6" } }, + "node_modules/@edx/frontend-component-header/node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@edx/frontend-platform": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@edx/frontend-platform/-/frontend-platform-3.3.1.tgz", @@ -2862,9 +2918,9 @@ } }, "node_modules/@edx/paragon": { - "version": "20.28.4", - "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.4.tgz", - "integrity": "sha512-JiEAUaEuOnHB/zC8h9d5f3AwchREiHFKbXFm7JpXNcvXpkTj0TTKTCS6zcfwZeDl77q/+Rx6Js7SpSE2EzAtDg==", + "version": "20.28.5", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.5.tgz", + "integrity": "sha512-6cW9Pl1hojOGfGatLjeojzr0qNfil6rlwB3APKZlgomscDxVzYbaQYyZNOx/k2dFaO8EKCpiApXhHW+WihQipg==", "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", @@ -2898,21 +2954,21 @@ } }, "node_modules/@edx/paragon/node_modules/@fortawesome/fontawesome-common-types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", - "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", + "integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==", "hasInstallScript": true, "engines": { "node": ">=6" } }, "node_modules/@edx/paragon/node_modules/@fortawesome/fontawesome-svg-core": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", - "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz", + "integrity": "sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==", "hasInstallScript": true, "dependencies": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" }, "engines": { "node": ">=6" @@ -22280,6 +22336,47 @@ "react-transition-group": "4.4.5" }, "dependencies": { + "@edx/paragon": { + "version": "20.28.4", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.4.tgz", + "integrity": "sha512-JiEAUaEuOnHB/zC8h9d5f3AwchREiHFKbXFm7JpXNcvXpkTj0TTKTCS6zcfwZeDl77q/+Rx6Js7SpSE2EzAtDg==", + "requires": { + "@fortawesome/fontawesome-svg-core": "^6.1.1", + "@fortawesome/react-fontawesome": "^0.1.18", + "@popperjs/core": "^2.11.4", + "bootstrap": "^4.6.2", + "classnames": "^2.3.1", + "email-prop-type": "^3.0.0", + "file-selector": "^0.6.0", + "font-awesome": "^4.7.0", + "glob": "^8.0.3", + "lodash.uniqby": "^4.7.0", + "mailto-link": "^2.0.0", + "prop-types": "^15.8.1", + "react-bootstrap": "^1.6.5", + "react-dropzone": "^14.2.1", + "react-focus-on": "^3.5.4", + "react-loading-skeleton": "^3.1.0", + "react-popper": "^2.2.5", + "react-proptype-conditional-require": "^1.0.4", + "react-responsive": "^8.2.0", + "react-table": "^7.7.0", + "react-transition-group": "^4.4.2", + "tabbable": "^5.3.3", + "uncontrollable": "^7.2.1", + "uuid": "^9.0.0" + }, + "dependencies": { + "@fortawesome/react-fontawesome": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.19.tgz", + "integrity": "sha512-Hyb+lB8T18cvLNX0S3llz7PcSOAJMLwiVKBuuzwM/nI5uoBw+gQjnf9il0fR1C3DKOI5Kc79pkJ4/xB0Uw9aFQ==", + "requires": { + "prop-types": "^15.8.1" + } + } + } + }, "@fortawesome/fontawesome-common-types": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", @@ -22316,6 +22413,11 @@ "requires": { "@fortawesome/fontawesome-common-types": "6.3.0" } + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" } } }, @@ -22389,9 +22491,9 @@ } }, "@edx/paragon": { - "version": "20.28.4", - "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.4.tgz", - "integrity": "sha512-JiEAUaEuOnHB/zC8h9d5f3AwchREiHFKbXFm7JpXNcvXpkTj0TTKTCS6zcfwZeDl77q/+Rx6Js7SpSE2EzAtDg==", + "version": "20.28.5", + "resolved": "https://registry.npmjs.org/@edx/paragon/-/paragon-20.28.5.tgz", + "integrity": "sha512-6cW9Pl1hojOGfGatLjeojzr0qNfil6rlwB3APKZlgomscDxVzYbaQYyZNOx/k2dFaO8EKCpiApXhHW+WihQipg==", "requires": { "@fortawesome/fontawesome-svg-core": "^6.1.1", "@fortawesome/react-fontawesome": "^0.1.18", @@ -22420,16 +22522,16 @@ }, "dependencies": { "@fortawesome/fontawesome-common-types": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz", - "integrity": "sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz", + "integrity": "sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg==" }, "@fortawesome/fontawesome-svg-core": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz", - "integrity": "sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz", + "integrity": "sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw==", "requires": { - "@fortawesome/fontawesome-common-types": "6.2.1" + "@fortawesome/fontawesome-common-types": "6.3.0" } }, "@fortawesome/react-fontawesome": { From ccc62a0e4869699cb66ca8dee8a3a953c58e4fe8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 20 Mar 2023 08:08:01 +0000 Subject: [PATCH 26/63] fix(deps): update dependency redux-saga to v1.2.3 --- package-lock.json | 30 +++++++++++++++--------------- package.json | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index 511f38a..4d92555 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "redux": "4.2.1", "redux-devtools-extension": "2.13.9", "redux-logger": "3.0.6", - "redux-saga": "1.2.2", + "redux-saga": "1.2.3", "redux-thunk": "2.4.2", "regenerator-runtime": "0.13.11", "reselect": "4.1.7", @@ -4059,9 +4059,9 @@ } }, "node_modules/@redux-saga/core": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.2.tgz", - "integrity": "sha512-0qr5oleOAmI5WoZLRA6FEa30M4qKZcvx+ZQOQw+RqFeH8t20bvhE329XSPsNfTVP8C6qyDsXOSjuoV+g3+8zkg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.3.tgz", + "integrity": "sha512-U1JO6ncFBAklFTwoQ3mjAeQZ6QGutsJzwNBjgVLSWDpZTRhobUzuVDS1qH3SKGJD8fvqoaYOjp6XJ3gCmeZWgA==", "dependencies": { "@babel/runtime": "^7.6.3", "@redux-saga/deferred": "^1.2.1", @@ -16287,11 +16287,11 @@ } }, "node_modules/redux-saga": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-1.2.2.tgz", - "integrity": "sha512-6xAHWgOqRP75MFuLq88waKK9/+6dCdMQjii2TohDMARVHeQ6HZrZoJ9HZ3dLqMWCZ9kj4iuS6CDsujgnovn11A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-1.2.3.tgz", + "integrity": "sha512-HDe0wTR5nhd8Xr5xjGzoyTbdAw6rjy1GDplFt3JKtKN8/MnkQSRqK/n6aQQhpw5NI4ekDVOaW+w4sdxPBaCoTQ==", "dependencies": { - "@redux-saga/core": "^1.2.2" + "@redux-saga/core": "^1.2.3" } }, "node_modules/redux-thunk": { @@ -23395,9 +23395,9 @@ "version": "2.11.5" }, "@redux-saga/core": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.2.tgz", - "integrity": "sha512-0qr5oleOAmI5WoZLRA6FEa30M4qKZcvx+ZQOQw+RqFeH8t20bvhE329XSPsNfTVP8C6qyDsXOSjuoV+g3+8zkg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@redux-saga/core/-/core-1.2.3.tgz", + "integrity": "sha512-U1JO6ncFBAklFTwoQ3mjAeQZ6QGutsJzwNBjgVLSWDpZTRhobUzuVDS1qH3SKGJD8fvqoaYOjp6XJ3gCmeZWgA==", "requires": { "@babel/runtime": "^7.6.3", "@redux-saga/deferred": "^1.2.1", @@ -32423,11 +32423,11 @@ } }, "redux-saga": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-1.2.2.tgz", - "integrity": "sha512-6xAHWgOqRP75MFuLq88waKK9/+6dCdMQjii2TohDMARVHeQ6HZrZoJ9HZ3dLqMWCZ9kj4iuS6CDsujgnovn11A==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/redux-saga/-/redux-saga-1.2.3.tgz", + "integrity": "sha512-HDe0wTR5nhd8Xr5xjGzoyTbdAw6rjy1GDplFt3JKtKN8/MnkQSRqK/n6aQQhpw5NI4ekDVOaW+w4sdxPBaCoTQ==", "requires": { - "@redux-saga/core": "^1.2.2" + "@redux-saga/core": "^1.2.3" } }, "redux-thunk": { diff --git a/package.json b/package.json index beb1c93..79a4e1b 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "redux": "4.2.1", "redux-devtools-extension": "2.13.9", "redux-logger": "3.0.6", - "redux-saga": "1.2.2", + "redux-saga": "1.2.3", "redux-thunk": "2.4.2", "regenerator-runtime": "0.13.11", "reselect": "4.1.7", From abf9860f626b813020c01cdf8da7d844c5c38285 Mon Sep 17 00:00:00 2001 From: Maxwell Frank Date: Wed, 15 Mar 2023 17:59:43 +0000 Subject: [PATCH 27/63] fix: authenticated page route --- .env.test | 1 + package-lock.json | 6 ++- package.json | 1 + src/index.jsx | 16 ++----- src/routes/AppRoutes.jsx | 22 +++++++++ src/routes/routes.test.jsx | 91 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 123 insertions(+), 14 deletions(-) create mode 100644 src/routes/AppRoutes.jsx create mode 100644 src/routes/routes.test.jsx diff --git a/.env.test b/.env.test index 6f8232c..0b6574a 100644 --- a/.env.test +++ b/.env.test @@ -18,6 +18,7 @@ LOGO_TRADEMARK_URL=https://edx-cdn.org/v3/default/logo-trademark.svg LOGO_WHITE_URL=https://edx-cdn.org/v3/default/logo-white.svg FAVICON_URL=https://edx-cdn.org/v3/default/favicon.ico ENABLE_LEARNER_RECORD_MFE='' +ENABLE_SKILLS_BUILDER='true' ENABLE_SKILLS_BUILDER_PROFILE='' LEARNER_RECORD_MFE_BASE_URL='http://localhost:1990' COLLECT_YEAR_OF_BIRTH=true diff --git a/package-lock.json b/package-lock.json index 4d92555..bfb96cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "algoliasearch": "4.6.0", "classnames": "2.3.2", "core-js": "3.27.2", + "history": "4.10.1", "lodash.camelcase": "4.3.0", "lodash.get": "4.4.2", "lodash.pick": "4.4.0", @@ -10495,7 +10496,8 @@ }, "node_modules/history": { "version": "4.10.1", - "license": "MIT", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", "dependencies": { "@babel/runtime": "^7.1.2", "loose-envify": "^1.2.0", @@ -28272,6 +28274,8 @@ }, "history": { "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", "requires": { "@babel/runtime": "^7.1.2", "loose-envify": "^1.2.0", diff --git a/package.json b/package.json index 79a4e1b..4ab3e2c 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "algoliasearch": "4.6.0", "classnames": "2.3.2", "core-js": "3.27.2", + "history": "4.10.1", "lodash.camelcase": "4.3.0", "lodash.get": "4.4.2", "lodash.pick": "4.4.0", diff --git a/src/index.jsx b/src/index.jsx index 7705089..680c0a0 100755 --- a/src/index.jsx +++ b/src/index.jsx @@ -4,7 +4,6 @@ import 'regenerator-runtime/runtime'; import { APP_INIT_ERROR, APP_READY, - getConfig, initialize, mergeConfig, subscribe, @@ -16,33 +15,25 @@ import { import React from 'react'; import ReactDOM from 'react-dom'; -import { Route, Switch } from 'react-router-dom'; import Header, { messages as headerMessages } from '@edx/frontend-component-header'; import Footer, { messages as footerMessages } from '@edx/frontend-component-footer'; import appMessages from './i18n'; -import { ProfilePage, NotFoundPage } from './profile'; -import { SkillsBuilder } from './skills-builder'; import configureStore from './data/configureStore'; import './index.scss'; import Head from './head/Head'; +import AppRoutes from './routes/AppRoutes'; + subscribe(APP_READY, () => { ReactDOM.render(
- - {getConfig().ENABLE_SKILLS_BUILDER && ( - - )} - - - - +