From da6c42ed1af0326e430ba9bbad3c15a82cad1e00 Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Mon, 9 Oct 2017 15:12:39 +0530 Subject: [PATCH 1/4] =?UTF-8?q?Github=20issue#1240,=20SEO=20friendly=20URL?= =?UTF-8?q?s=20for=20deep=20links=20(without=20database=20and=20ES=20updat?= =?UTF-8?q?e)=20=E2=80=94=20Supported=20aliases=20field=20for=20each=20pro?= =?UTF-8?q?ject=20category=20and=20product=20=E2=80=94=20These=20aliases?= =?UTF-8?q?=20would=20be=20used=20to=20construct=20the=20wizard=20step=20U?= =?UTF-8?q?RLs=20=E2=80=94=20They=20can=20be=20used=20for=20SEO=20friendly?= =?UTF-8?q?=20deep=20links=20as=20well?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/projectQuestions/app_dev.v1.0.js | 2 +- src/config/projectQuestions/avd.v1.0.js | 2 +- .../projectQuestions/generic_chatbot.v1.0.js | 2 +- .../projectQuestions/ibm_chatbot.v1.0.js | 2 +- .../real_world_testing.v1.0.js | 2 +- .../projectQuestions/visual_design.v1.0.js | 2 +- .../projectQuestions/wireframes.v1.0.js | 2 +- .../typeToSpecification.json | 2 +- src/config/projectWizard/index.js | 110 +++++++++++++----- .../create/components/ProjectWizard.jsx | 10 +- .../create/containers/CreateContainer.jsx | 21 +++- .../list/components/Projects/ProjectsView.jsx | 2 +- src/routes.jsx | 4 +- 13 files changed, 114 insertions(+), 49 deletions(-) diff --git a/src/config/projectQuestions/app_dev.v1.0.js b/src/config/projectQuestions/app_dev.v1.0.js index 2bbca66d2..35bc051ac 100644 --- a/src/config/projectQuestions/app_dev.v1.0.js +++ b/src/config/projectQuestions/app_dev.v1.0.js @@ -20,7 +20,7 @@ const sections = [ const product = _.get(project, 'details.products[0]') if (showProduct && product) { const prd = findProduct(product) - if (prd) return prd + if (prd) return prd.name } return 'Definition' }, diff --git a/src/config/projectQuestions/avd.v1.0.js b/src/config/projectQuestions/avd.v1.0.js index 1200b92b0..335e702b7 100644 --- a/src/config/projectQuestions/avd.v1.0.js +++ b/src/config/projectQuestions/avd.v1.0.js @@ -22,7 +22,7 @@ const sections = [ const product = _.get(project, 'details.products[0]') if (showProduct && product) { const prd = findProduct(product) - if (prd) return prd + if (prd) return prd.name } return 'Definition' }, diff --git a/src/config/projectQuestions/generic_chatbot.v1.0.js b/src/config/projectQuestions/generic_chatbot.v1.0.js index f3758c37b..92259488c 100644 --- a/src/config/projectQuestions/generic_chatbot.v1.0.js +++ b/src/config/projectQuestions/generic_chatbot.v1.0.js @@ -20,7 +20,7 @@ const sections = [ const product = _.get(project, 'details.products[0]') if (showProduct && product) { const prd = findProduct(product) - if (prd) return prd + if (prd) return prd.name } return 'Definition' }, diff --git a/src/config/projectQuestions/ibm_chatbot.v1.0.js b/src/config/projectQuestions/ibm_chatbot.v1.0.js index bfaf6f73c..b0269210e 100644 --- a/src/config/projectQuestions/ibm_chatbot.v1.0.js +++ b/src/config/projectQuestions/ibm_chatbot.v1.0.js @@ -20,7 +20,7 @@ const sections = [ const product = _.get(project, 'details.products[0]') if (showProduct && product) { const prd = findProduct(product) - if (prd) return prd + if (prd) return prd.name } return 'Definition' }, diff --git a/src/config/projectQuestions/real_world_testing.v1.0.js b/src/config/projectQuestions/real_world_testing.v1.0.js index 51eb32c4a..dfdd6a3db 100644 --- a/src/config/projectQuestions/real_world_testing.v1.0.js +++ b/src/config/projectQuestions/real_world_testing.v1.0.js @@ -23,7 +23,7 @@ const sections = [ const product = _.get(project, 'details.products[0]') if (showProduct && product) { const prd = findProduct(product) - if (prd) return prd + if (prd) return prd.name } return 'Definition' }, diff --git a/src/config/projectQuestions/visual_design.v1.0.js b/src/config/projectQuestions/visual_design.v1.0.js index bd8e53c97..86114a5d5 100644 --- a/src/config/projectQuestions/visual_design.v1.0.js +++ b/src/config/projectQuestions/visual_design.v1.0.js @@ -22,7 +22,7 @@ const sections = [ const product = _.get(project, 'details.products[0]') if (showProduct && product) { const prd = findProduct(product) - if (prd) return prd + if (prd) return prd.name } return 'Definition' }, diff --git a/src/config/projectQuestions/wireframes.v1.0.js b/src/config/projectQuestions/wireframes.v1.0.js index e85420950..cdf319688 100644 --- a/src/config/projectQuestions/wireframes.v1.0.js +++ b/src/config/projectQuestions/wireframes.v1.0.js @@ -22,7 +22,7 @@ const sections = [ const product = _.get(project, 'details.products[0]') if (showProduct && product) { const prd = findProduct(product) - if (prd) return prd + if (prd) return prd.name } return 'Definition' }, diff --git a/src/config/projectSpecification/typeToSpecification.json b/src/config/projectSpecification/typeToSpecification.json index 6e9cfe7b6..70f10e0bc 100644 --- a/src/config/projectSpecification/typeToSpecification.json +++ b/src/config/projectSpecification/typeToSpecification.json @@ -8,7 +8,7 @@ "website_development": "app_dev.v1.0", "application_development": "app_dev.v1.0", "watson_chatbot": "ibm_chatbot.v1.0", - "chatbot": "generic_chatbot.v1.0", + "generic_chatbot": "generic_chatbot.v1.0", "generic_dev": "app_dev.v1.0", "real_world_testing": "real_world_testing.v1.0", "mobility_testing": "app_dev.v1.0", diff --git a/src/config/projectWizard/index.js b/src/config/projectWizard/index.js index 53590115d..242b21247 100644 --- a/src/config/projectWizard/index.js +++ b/src/config/projectWizard/index.js @@ -7,12 +7,14 @@ const products = { info: 'Build a phone, tablet, wearable, or desktop app', question: 'What do you need to develop?', id: 'app', + aliases: ['all-apps'], subtypes: { App: { brief: 'Apps', details: 'Build apps for mobile, web, or wearables', icon: 'product-app-app', - id: 'application_development' + id: 'application_development', + aliases: ['app'] } } }, @@ -21,12 +23,14 @@ const products = { info: 'Design and build the high-impact pages for your blog, online store, or company', question: 'What do you need to develop?', id: 'website', + aliases: ['all-websites'], subtypes: { Website: { brief: 'Websites', details: 'Build responsive or regular websites', icon: 'product-website-website', - id: 'website_development' + id: 'website_development', + aliases: ['website'] } } }, @@ -34,7 +38,8 @@ const products = { icon: 'product-cat-chatbot', info: 'Build, train and test a custom conversation for your chatbot', question: 'What do you need to develop?', - id: 'all-chatbots', + id: 'chatbot', + aliases: ['all-chatbots'], subtypes: { 'Watson Chatbot': { brief: 'Watson Chatbot', @@ -47,7 +52,8 @@ const products = { brief: 'Chatbot', details: 'Build, train and test a custom conversation for your chat bot', icon: 'product-chatbot-chatbot', - id: 'chatbot' + id: 'generic_chatbot', + aliases: ['chatbot'] } } }, @@ -56,38 +62,44 @@ const products = { info: 'Pick the right design project for your needs - wireframes, visual, or other', question: 'What kind of design do you need?', id: 'visual_design', + aliases: ['all-designs'], subtypes: { Wireframes: { brief: '10-15 screens', details: 'Plan and explore the navigation and structure of your app', icon: 'product-design-wireframes', - id: 'wireframes' + id: 'wireframes', + aliases: ['wireframes'] }, 'App Visual Design - Concepts': { brief: '1-15 screens', details: 'Visualize and test your app requirements and ideas', icon: 'product-design-app-visual', id: 'visual_design_concepts', + aliases: ['visual_design_concepts'], disabled: true }, 'Visual Design': { brief: '1-15 screens', details: 'Create development-ready designs', icon: 'product-design-app-visual', - id: 'visual_design_prod' + id: 'visual_design_prod', + aliases: ['visual-design'] }, Infographic: { brief: 'Infographic', details: 'Present your data in an easy-to-understand and interesting way', icon: 'product-design-infographic', id: 'infographic', + aliases: ['infographic'], disabled: true }, 'Other Design': { brief: 'other designs', details: 'Get help with other types of design', icon: 'product-design-other', - id: 'generic_design' + id: 'generic_design', + aliases: ['generic_design'] } } }, @@ -96,31 +108,36 @@ const products = { info: 'Get help with any part of your development lifecycle', question: 'What kind of development do you need?', id: 'app_dev', + aliases: ['all-development'], subtypes: { 'Front-end Prototype': { brief: '3-20 screens', details: 'Translate designs to a web (HTML/CSS/JavaScript) or mobile prototype', icon: 'product-dev-prototype', id: 'visual_prototype', + aliases: ['visual-prototype'], disabled: true }, 'Front-end': { brief: '', details: 'Translate your designs into Web or Mobile front-end', icon: 'product-dev-front-end-dev', - id: 'frontend_dev' + id: 'frontend_dev', + aliases: ['frontend-development'] }, 'Back-end & API': { brief: '', details: 'Build the server, DB, and API for your app', icon: 'product-dev-integration', - id: 'api_dev' + id: 'api_dev', + aliases: ['api-development'] }, 'Development Integration': { brief: 'Tasks or adhoc', details: 'Get help with any part of your app or software', icon: 'product-dev-other', - id: 'generic_dev' + id: 'generic_dev', + aliases: ['generic-development'] } } }, @@ -129,18 +146,21 @@ const products = { info: 'Exploratory Testing, Cross browser-device Testing', question: 'What kind of quality assurance (QA) do you need?', id: 'quality_assurance', + aliases: ['all-quality-assurance'], subtypes: { 'Real World Testing': { brief: 'TBD', details: 'Exploratory Testing, Cross browser-device Testing', icon: 'product-qa-crowd-testing', - id: 'real_world_testing' + id: 'real_world_testing', + aliases: ['real-world-testing'] }, 'Mobility Testing': { brief: 'TBD', details: 'App Certification, Lab on Hire, User Sentiment Analysis', icon: 'product-qa-mobility-testing', id: 'mobility_testing', + aliases: ['mobility-testing'], disabled: true }, 'Website Performance': { @@ -148,6 +168,7 @@ const products = { details: 'Webpage rendering effiency, Load, Stress and Endurance Test', icon: 'product-qa-website-performance', id: 'website_performance', + aliases: ['website-performance'], disabled: true }, 'Digital Accessability': { @@ -155,6 +176,7 @@ const products = { details: 'Make sure you app or website conforms to all rules and regulations', icon: 'product-qa-digital-accessability', id: 'digital_accessability', + aliases: ['digital-accessability'], disabled: true }, 'Open Source Automation': { @@ -162,6 +184,7 @@ const products = { details: 'Exploratory testing, cross browser testing', icon: 'product-qa-os-automation', id: 'open_source_automation', + aliases: ['open-source-automation'], disabled: true }, 'Consulting & Adivisory': { @@ -169,6 +192,7 @@ const products = { details: 'Expert services to get your project covered end-to-end', icon: 'product-qa-consulting', id: 'consulting_adivisory', + aliases: ['consulting-adivisory'], disabled: true } } @@ -180,34 +204,54 @@ export default products // exports all project types as an array export const projectTypes = _.mapValues(products, (p, key) => ({...p, name: key }) ) -export function findProduct(product) { - if (product === 'generic_dev') { - return 'Development' - } - if (product === 'generic_design') { - return 'Design' - } +/** + * Finds product for the given product id. It compares the given value against product id and aliases. + * + * @param {string} productId id of the product. + * @param {boolean} aliasesOnly flag to limit the search to aliases only + * + * @return {object} product object from the catalouge + */ +export function findProduct(productId, aliasesOnly = false) { for(const pType in products) { for(const prd in products[pType].subtypes) { - if (products[pType].subtypes[prd].id === product) { - return prd + const subType = products[pType].subtypes[prd] + if ((subType.id === productId && !aliasesOnly) || (subType.aliases && subType.aliases.indexOf(productId) !== -1)) { + return { ...subType, name: prd} } } } } -export function findCategory(categoryId) { +/** + * Finds project category for the given category id. It compares the given value against id and aliases. + * + * @param {string} categoryId id of the category. + * @param {boolean} aliasesOnly flag to limit the search to aliases only + * + * @return {object} project category object from the catalouge + */ +export function findCategory(categoryId, aliasesOnly = false) { for(const key in products) { - if (products[key].id === categoryId && !products[key].disabled) { - return { ...products[key], name: key} + const product = products[key] + if (!product.disabled && ((product.id === categoryId && !aliasesOnly) || (product.aliases && product.aliases.indexOf(categoryId) !== -1))) { + return { ...product, name: key} } } return null } -export function findProductsOfCategory(category, fetchHidden = true) { +/** + * Finds products of the given category id. Never returns disabled products + * + * @param {string} categoryId id of the category. + * @param {boolean} fetchHidden flag to limit the hidden products + * + * @return {Array} non disabled products of the given category from the catalouge + */ +export function findProductsOfCategory(categoryId, fetchHidden = true) { for(const pType in products) { - if (products[pType].id === category) { + if (products[pType].id === categoryId) { const ret = [] for(const prd in products[pType].subtypes) { const product = products[pType].subtypes[prd] @@ -220,17 +264,25 @@ export function findProductsOfCategory(category, fetchHidden = true) { } } -export function findProductCategory(product) { - if (product === 'generic_dev') { +/** + * Finds project category for the given product id. It compares the given value against id and aliases. + * + * @param {string} productId id of the category. + * @param {boolean} aliasesOnly flag to limit the search to aliases only + * + * @return {object} project category object, from the catalouge, for the given product + */ +export function findProductCategory(productId, aliasesOnly = false) { + if (productId === 'generic_dev') { return 'Development' } - if (product === 'generic_design') { + if (productId === 'generic_design') { return 'Design' } for(const pType in products) { for(const prd in products[pType].subtypes) { const subType = products[pType].subtypes[prd] - if (subType.id === product && !subType.disabled) { + if (!subType.disabled && ((subType.id === productId && !aliasesOnly) || (subType.aliases && subType.aliases.indexOf(productId) !== -1))) { return { ...products[pType], name: pType} } } diff --git a/src/projects/create/components/ProjectWizard.jsx b/src/projects/create/components/ProjectWizard.jsx index 2151432ce..c0a157df9 100644 --- a/src/projects/create/components/ProjectWizard.jsx +++ b/src/projects/create/components/ProjectWizard.jsx @@ -2,7 +2,7 @@ import _ from 'lodash' import { unflatten } from 'flat' import React, { Component, PropTypes } from 'react' -import { findCategory, findProductCategory, findProductsOfCategory, getProjectCreationTemplateField } from '../../../config/projectWizard' +import { findProduct, findCategory, findProductCategory, findProductsOfCategory, getProjectCreationTemplateField } from '../../../config/projectWizard' import Wizard from '../../../components/Wizard' import SelectProjectType from './SelectProjectType' import SelectProduct from './SelectProduct' @@ -62,15 +62,17 @@ class ProjectWizard extends Component { let wizardStep = WZ_STEP_SELECT_PROJ_TYPE if (params && params.product) { // first try the path param to be a project category - let projectType = findCategory(params.product) + let projectType = findCategory(params.product, true) if (projectType) {// if its a category updateQuery['type'] = { $set : projectType.id } wizardStep = WZ_STEP_SELECT_PROD_TYPE } else { // if it is not a category, it should be a product and we should be able to find a category for it - projectType = findProductCategory(params.product) + projectType = findProductCategory(params.product, true) + // finds product object from product alias + const product = findProduct(params.product, true) updateQuery['type'] = { $set : projectType.id } - updateQuery['details'] = { products : { $set: [params.product] } } + updateQuery['details'] = { products : { $set: [product.id] } } wizardStep = WZ_STEP_FILL_PROJ_DETAILS } } diff --git a/src/projects/create/containers/CreateContainer.jsx b/src/projects/create/containers/CreateContainer.jsx index a14443d1e..187f56d5c 100644 --- a/src/projects/create/containers/CreateContainer.jsx +++ b/src/projects/create/containers/CreateContainer.jsx @@ -7,6 +7,7 @@ import { createProjectWithStatus as createProjectAction, fireProjectDirty, fireP import CoderBot from '../../../components/CoderBot/CoderBot' import spinnerWhileLoading from '../../../components/LoadingSpinner' import ProjectWizard from '../components/ProjectWizard' +import { findProduct, findCategory } from '../../../config/projectWizard' import { CREATE_PROJECT_FAILURE, LS_INCOMPLETE_PROJECT, @@ -145,8 +146,18 @@ class CreateConainer extends React.Component { createProject={ this.createProject } processing={ this.state.creatingProject } onStepChange={ (wizardStep, updatedProject) => { - const projectType = _.get(updatedProject, 'type', null) - const product = _.get(updatedProject, 'details.products[0]', null) + // type of the project + let projectType = _.get(updatedProject, 'type', null) + // finds project category object from the catalogue + const projectCategory = findCategory(projectType) + // updates the projectType variable to use first alias to create SEO friendly URL + projectType = _.get(projectCategory, 'aliases[0]', projectType) + // product of the project + let productType = _.get(updatedProject, 'details.products[0]', null) + // finds product object from the catalogue + const product = findProduct(productType) + // updates the productType variable to use first alias to create SEO friendly URL + productType = _.get(product, 'aliases[0]', productType) if (wizardStep === ProjectWizard.Steps.WZ_STEP_INCOMP_PROJ_CONF) { browserHistory.push(NEW_PROJECT_PATH + '/incomplete') } @@ -156,8 +167,8 @@ class CreateConainer extends React.Component { if (projectType && wizardStep === ProjectWizard.Steps.WZ_STEP_SELECT_PROD_TYPE) { browserHistory.push(NEW_PROJECT_PATH + '/' + projectType + window.location.search) } - if (projectType && product && wizardStep === ProjectWizard.Steps.WZ_STEP_FILL_PROJ_DETAILS) { - browserHistory.push(NEW_PROJECT_PATH + '/' + product + window.location.search) + if (projectType && productType && wizardStep === ProjectWizard.Steps.WZ_STEP_FILL_PROJ_DETAILS) { + browserHistory.push(NEW_PROJECT_PATH + '/' + productType + window.location.search) } this.setState({ wizardStep @@ -171,7 +182,7 @@ class CreateConainer extends React.Component { // compares updated product with previous product to know if user has updated the product if (prevProduct !== product) { if (product) { - browserHistory.push(NEW_PROJECT_PATH + '/' + product + window.location.search) + // browserHistory.push(NEW_PROJECT_PATH + '/' + product + window.location.search) } } this.setState({ diff --git a/src/projects/list/components/Projects/ProjectsView.jsx b/src/projects/list/components/Projects/ProjectsView.jsx index 5ebad9432..fd27f4556 100644 --- a/src/projects/list/components/Projects/ProjectsView.jsx +++ b/src/projects/list/components/Projects/ProjectsView.jsx @@ -40,7 +40,7 @@ const projectTypeClassMap = { 'app_dev' : 'green-block', 'app' : 'green-block', 'website' : 'green-block', - 'all-chatbots' : 'green-block', + 'chatbot' : 'green-block', 'quality_assurance' : 'green-block' } /*eslint-enable */ diff --git a/src/routes.jsx b/src/routes.jsx index 1d0c76ab2..b12262b26 100644 --- a/src/routes.jsx +++ b/src/routes.jsx @@ -86,9 +86,9 @@ const redirectToProject = (nextState, replace, callback) => { const validateCreateProjectParams = (nextState, replace, callback) => { const product = nextState.params.product // first try the path param to be a project category - let productCategory = findCategory(product) + let productCategory = findCategory(product, true) // if it is not a category, it should be a product and we should be able to find a category for it - productCategory = !productCategory ? findProductCategory(product) : productCategory + productCategory = !productCategory ? findProductCategory(product, true) : productCategory if (product && product.trim().length > 0 && !productCategory) { // workaround to add URL for incomplete project confirmation step // ideally we should have better URL naming which resolves each route with distinct patterns From 371e01c78af04c858e368324010791f13789ba3b Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Mon, 9 Oct 2017 15:16:55 +0530 Subject: [PATCH 2/4] =?UTF-8?q?Github=20issue#1240,=20SEO=20friendly=20URL?= =?UTF-8?q?s=20for=20deep=20links=20(without=20database=20and=20ES=20updat?= =?UTF-8?q?e)=20=E2=80=94=20Added=20backward=20compatibility=20to=20suppor?= =?UTF-8?q?t=20existing=20deep=20links=20which=20uses=20ids=20instead=20of?= =?UTF-8?q?=20aliases.=20This=20support=20can=20be=20taken=20off=20in=20fu?= =?UTF-8?q?ture=20releases=20after=20updating=20all=20marketing=20URLs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/config/projectWizard/index.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/config/projectWizard/index.js b/src/config/projectWizard/index.js index 242b21247..59977b28b 100644 --- a/src/config/projectWizard/index.js +++ b/src/config/projectWizard/index.js @@ -14,7 +14,7 @@ const products = { details: 'Build apps for mobile, web, or wearables', icon: 'product-app-app', id: 'application_development', - aliases: ['app'] + aliases: ['app', 'application_development'] } } }, @@ -30,7 +30,7 @@ const products = { details: 'Build responsive or regular websites', icon: 'product-website-website', id: 'website_development', - aliases: ['website'] + aliases: ['website', 'website_development'] } } }, @@ -46,6 +46,7 @@ const products = { details: 'Build Chatbot using IBM Watson', icon: 'product-chatbot-watson', id: 'watson_chatbot', + aliases: ['watson_chatbot'], hidden: true }, Chatbot: { @@ -53,7 +54,7 @@ const products = { details: 'Build, train and test a custom conversation for your chat bot', icon: 'product-chatbot-chatbot', id: 'generic_chatbot', - aliases: ['chatbot'] + aliases: ['chatbot', 'generic_chatbot'] } } }, @@ -84,7 +85,7 @@ const products = { details: 'Create development-ready designs', icon: 'product-design-app-visual', id: 'visual_design_prod', - aliases: ['visual-design'] + aliases: ['visual-design', 'visual_design_prod'] }, Infographic: { brief: 'Infographic', @@ -99,7 +100,7 @@ const products = { details: 'Get help with other types of design', icon: 'product-design-other', id: 'generic_design', - aliases: ['generic_design'] + aliases: ['generic-design', 'generic_design'] } } }, @@ -115,7 +116,7 @@ const products = { details: 'Translate designs to a web (HTML/CSS/JavaScript) or mobile prototype', icon: 'product-dev-prototype', id: 'visual_prototype', - aliases: ['visual-prototype'], + aliases: ['visual-prototype','visual_prototype'], disabled: true }, 'Front-end': { @@ -123,21 +124,21 @@ const products = { details: 'Translate your designs into Web or Mobile front-end', icon: 'product-dev-front-end-dev', id: 'frontend_dev', - aliases: ['frontend-development'] + aliases: ['frontend-development', 'frontend_dev'] }, 'Back-end & API': { brief: '', details: 'Build the server, DB, and API for your app', icon: 'product-dev-integration', id: 'api_dev', - aliases: ['api-development'] + aliases: ['api-development', 'api_dev'] }, 'Development Integration': { brief: 'Tasks or adhoc', details: 'Get help with any part of your app or software', icon: 'product-dev-other', id: 'generic_dev', - aliases: ['generic-development'] + aliases: ['generic-development', 'generic_dev'] } } }, @@ -153,14 +154,14 @@ const products = { details: 'Exploratory Testing, Cross browser-device Testing', icon: 'product-qa-crowd-testing', id: 'real_world_testing', - aliases: ['real-world-testing'] + aliases: ['real-world-testing', 'real_world_testing'] }, 'Mobility Testing': { brief: 'TBD', details: 'App Certification, Lab on Hire, User Sentiment Analysis', icon: 'product-qa-mobility-testing', id: 'mobility_testing', - aliases: ['mobility-testing'], + aliases: ['mobility-testing', 'mobility_testing'], disabled: true }, 'Website Performance': { @@ -168,7 +169,7 @@ const products = { details: 'Webpage rendering effiency, Load, Stress and Endurance Test', icon: 'product-qa-website-performance', id: 'website_performance', - aliases: ['website-performance'], + aliases: ['website-performance', 'website_performance'], disabled: true }, 'Digital Accessability': { @@ -176,7 +177,7 @@ const products = { details: 'Make sure you app or website conforms to all rules and regulations', icon: 'product-qa-digital-accessability', id: 'digital_accessability', - aliases: ['digital-accessability'], + aliases: ['digital-accessability', 'digital_accessability'], disabled: true }, 'Open Source Automation': { @@ -184,7 +185,7 @@ const products = { details: 'Exploratory testing, cross browser testing', icon: 'product-qa-os-automation', id: 'open_source_automation', - aliases: ['open-source-automation'], + aliases: ['open-source-automation', 'open_source_automation'], disabled: true }, 'Consulting & Adivisory': { @@ -192,7 +193,7 @@ const products = { details: 'Expert services to get your project covered end-to-end', icon: 'product-qa-consulting', id: 'consulting_adivisory', - aliases: ['consulting-adivisory'], + aliases: ['consulting-adivisory', 'consulting_adivisory'], disabled: true } } From c81cd9ffd6d2cccbcff5ec6d09217936cf55f667 Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Mon, 9 Oct 2017 15:52:43 +0530 Subject: [PATCH 3/4] =?UTF-8?q?Github=20issue#1240,=20SEO=20friendly=20URL?= =?UTF-8?q?s=20for=20deep=20links=20(without=20database=20and=20ES=20updat?= =?UTF-8?q?e)=20=E2=80=94=20Fixed=20merge=20issue=20which=20was=20preventi?= =?UTF-8?q?ng=20to=20open=20the=20project=20details=20forms=20directly=20f?= =?UTF-8?q?rom=20the=20category=20page=20for=20categories=20which=20have?= =?UTF-8?q?=20only=20one=20product.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/projects/create/components/ProjectWizard.jsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/projects/create/components/ProjectWizard.jsx b/src/projects/create/components/ProjectWizard.jsx index 21a225bdf..db5f264c0 100644 --- a/src/projects/create/components/ProjectWizard.jsx +++ b/src/projects/create/components/ProjectWizard.jsx @@ -107,16 +107,18 @@ class ProjectWizard extends Component { const updateQuery = {} if (params && params.product) { // if there exists product path param // first try the path param to be a project category - let projectType = findCategory(params.product) + let projectType = findCategory(params.product, true) if (projectType) {// if its a category updateQuery['type'] = { $set : projectType.id } wizardStep = WZ_STEP_SELECT_PROD_TYPE } else { // if it is not a category, it should be a product and we should be able to find a category for it - projectType = findProductCategory(params.product) + projectType = findProductCategory(params.product, true) + // finds product object from product alias + const product = findProduct(params.product, true) if (projectType) {// we can have `incomplete` as params.product updateQuery['type'] = { $set : projectType.id } - updateQuery['details'] = { products : { $set: [params.product] } } + updateQuery['details'] = { products : { $set: [product.id] } } wizardStep = WZ_STEP_FILL_PROJ_DETAILS } } From 41d1537fc7272a4147ea79eff9fafac6e520f16b Mon Sep 17 00:00:00 2001 From: Vikas Agarwal Date: Mon, 9 Oct 2017 15:54:59 +0530 Subject: [PATCH 4/4] =?UTF-8?q?Github=20issue#1240,=20SEO=20friendly=20URL?= =?UTF-8?q?s=20for=20deep=20links=20(without=20database=20and=20ES=20updat?= =?UTF-8?q?e)=20=E2=80=94=20Documentation=20for=20commenting=20existing=20?= =?UTF-8?q?code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/projects/create/containers/CreateContainer.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/projects/create/containers/CreateContainer.jsx b/src/projects/create/containers/CreateContainer.jsx index 187f56d5c..718607789 100644 --- a/src/projects/create/containers/CreateContainer.jsx +++ b/src/projects/create/containers/CreateContainer.jsx @@ -182,6 +182,9 @@ class CreateConainer extends React.Component { // compares updated product with previous product to know if user has updated the product if (prevProduct !== product) { if (product) { + // intentionally commented because now it should not be require as we handling all URL changes in onStepChange + // earlier we were not getting updated project in onStepChange handler, hence it was required here + // still leaving it here for next few release, in case we find any issue because of commenting this line // browserHistory.push(NEW_PROJECT_PATH + '/' + product + window.location.search) } }