From 402b1c40d5c8c804d0bf2ed046c383073040e4a1 Mon Sep 17 00:00:00 2001 From: amansinghbais Date: Tue, 2 Apr 2024 18:29:13 +0530 Subject: [PATCH 1/6] Implemented: logic for dynamic support for product features (#166) --- src/views/catalog-product-details.vue | 212 +++++++++++++++++++------- 1 file changed, 158 insertions(+), 54 deletions(-) diff --git a/src/views/catalog-product-details.vue b/src/views/catalog-product-details.vue index 363b7ad5..cc4b4953 100644 --- a/src/views/catalog-product-details.vue +++ b/src/views/catalog-product-details.vue @@ -22,23 +22,12 @@
- - {{ $t("Colors") }} + + {{ feature }} - - {{ colorFeature }} - - - - - - - {{ $t("Sizes") }} - - - - {{ sizeFeature }} + + {{ option }} @@ -442,8 +431,6 @@ export default defineComponent({ return { variantId: '', productId: '', - selectedColor: '', - selectedSize: '', features: [] as any, currentVariant: {} as any, poAndAtpDetails: {} as any, @@ -455,7 +442,8 @@ export default defineComponent({ listingJobRunTime: 0, backorderCategoryId: '', preOrderCategoryId: '', - isCtgryAndBrkrngJobsLoaded: false + isCtgryAndBrkrngJobsLoaded: false, + selectedFeatures: {} as any } }, computed: { @@ -491,57 +479,123 @@ export default defineComponent({ async getVariantDetails() { await this.store.dispatch('product/setCurrentCatalogProduct', { productId: this.productId}) if (this.product.variants) { + this.getVariant() this.getFeatures() await this.updateVariant() } }, - applyFeature(feature: string, type: string) { - if (type === 'color') this.selectedColor = feature - else if (type === 'size') this.selectedSize = feature + applyFeature(option: string, feature: string) { + const selectedFeatures = this.selectedFeatures + selectedFeatures[feature] = option + + const variant = this.product.variants.find((variant: any) => { + let isVariantAvailable = true + Object.entries(this.selectedFeatures).map((currentFeature, currentFeatureIndex) => { + if(getFeature(variant.featureHierarchy, `1/${currentFeature[0]}`) != currentFeature[1]){ + isVariantAvailable = false + } + }) + return isVariantAvailable + }) + + + if(!variant) { + const index = Object.keys(selectedFeatures).indexOf(feature) + + const availableVariants = this.product.variants.filter((variant: any) => { + let isVariantAvailable = true + Object.entries(selectedFeatures).map((currentFeature, currentFeatureIndex) => { + if(currentFeatureIndex <= index && getFeature(variant.featureHierarchy, `1/${currentFeature[0]}`) != currentFeature[1]){ + isVariantAvailable = false + } + }) + return isVariantAvailable + }) + + availableVariants[0].featureHierarchy.map((featureItem: any) => { + if(featureItem.startsWith('1/')){ + const featureItemSplitted = featureItem.split("/") + selectedFeatures[featureItemSplitted[1]] = featureItemSplitted[2] + } + }) + this.currentVariant = availableVariants[0] + this.selectedFeatures = selectedFeatures + showToast(translate("Selected variant not available. Reseting to first variant.")) + } + + this.getFeatures() this.updateVariant(); }, + getVariant() { + let selectedVariant = this.product.variants.find((variant: any) => variant.productId === this.variantId) + let selectedFeatures = {} as any; + + if(!selectedVariant) { + selectedVariant = this.product.variants[0] + showToast(translate("Selected variant not available. Reseting to first variant.")) + this.$route.query.variantId !== selectedVariant.productId && (this.router.replace({path: this.$route.path, query: { variantId: selectedVariant.productId } })); + } + + selectedVariant.featureHierarchy.map((featureItem: any) => { + if(featureItem.startsWith('1/')){ + const featureItemSplitted = featureItem.split("/") + selectedFeatures[featureItemSplitted[1]] = featureItemSplitted[2] + } + }) + + selectedFeatures = Object.keys(selectedFeatures).sort().reduce((result:any, key) => { + result[key] = selectedFeatures[key]; + return result; + }, {}); + + this.selectedFeatures = selectedFeatures + this.currentVariant = selectedVariant + }, getFeatures() { - const features = {} as any + const selectedFeatures = this.selectedFeatures + const firstFeature = Object.keys(selectedFeatures)[0] + + const features = {} as any; + this.product.variants.map((variant: any) => { - const size = getFeature(variant.featureHierarchy, '1/SIZE/') - const color = getFeature(variant.featureHierarchy, '1/COLOR/') - if (!features[color]) features[color] = [size] - else if (!features[color].includes(size)) features[color].push(size) + const featureOption = getFeature(variant.featureHierarchy, `1/${firstFeature}`) + if(!features[firstFeature]){ + features[firstFeature] = [featureOption] + } else{ + if(!features[firstFeature].includes(featureOption)) features[firstFeature].push(featureOption) + } }) - Object.keys(features).forEach((color) => this.features[color] = sortSizes(features[color])) + Object.entries(selectedFeatures).map((feature, featureIndex) => { + const nextFeature = Object.entries(selectedFeatures).find((currentFeature, currentFeatureIndex) => currentFeatureIndex === featureIndex + 1) - let selectedVariant = this.product.variants.find((variant: any) => variant.productId === this.variantId) + if(nextFeature) { + const nextFeatureCategory = nextFeature[0] - if (!selectedVariant) { - // if the variant does not have color or size as features - selectedVariant = this.product.variants[0] - showToast(translate("Selected variant not available. Reseting to first variant.")) - } + const availableVariants = this.product.variants.filter((variant: any) => { + let isVariantAvailable = true + Object.entries(this.selectedFeatures).map((currentFeature, currentFeatureIndex) => { + if(currentFeatureIndex <= featureIndex && getFeature(variant.featureHierarchy, `1/${currentFeature[0]}`) != currentFeature[1]){ + isVariantAvailable = false + } + }) + return isVariantAvailable + }) + + const nextFeatureOptions = [] as any + availableVariants.map((variant: any) => { + if(!nextFeatureOptions.includes(getFeature(variant.featureHierarchy , `1/${nextFeatureCategory}`))){ + nextFeatureOptions.push(getFeature(variant.featureHierarchy , `1/${nextFeatureCategory}`)) + } + }) - if (selectedVariant) { - this.selectedColor = getFeature(selectedVariant.featureHierarchy, '1/COLOR/') - this.selectedSize = getFeature(selectedVariant.featureHierarchy, '1/SIZE/') - } + features[nextFeatureCategory] = nextFeatureCategory === 'SIZE' ? sortSizes(nextFeatureOptions) : nextFeatureOptions + } + }) + + this.features = features }, async updateVariant() { - let variant - if (this.selectedColor || this.selectedSize) { - variant = this.product.variants.find((variant: any) => { - const hasSize = !this.selectedSize || (this.selectedSize && getFeature(variant.featureHierarchy, '1/SIZE/') === this.selectedSize) - const hasColor = !this.selectedColor || (this.selectedColor && getFeature(variant.featureHierarchy, '1/COLOR/') === this.selectedColor) - return hasSize && hasColor - }) - - // if the selected size is not available for that color, default it to the first size available - if (!variant) { - this.selectedSize = this.features[this.selectedColor][0]; - variant = this.product.variants.find((variant: any) => getFeature(variant.featureHierarchy, '1/SIZE/') === this.selectedSize) - showToast(translate("Selected variant not available")) - } - } - // if the variant does not have color or size as features - this.currentVariant = variant || this.product.variants[0] this.variantId = this.currentVariant.variantId this.$route.query.variantId !== this.currentVariant.productId && (this.router.replace({path: this.$route.path, query: { variantId: this.currentVariant.productId } })); await this.getPoDetails() @@ -550,6 +604,56 @@ export default defineComponent({ await this.prepareShopListings() await this.preparePoSummary() }, + // getFeatures() { + // const features = {} as any + // this.product.variants.map((variant: any) => { + // const size = getFeature(variant.featureHierarchy, '1/SIZE/') + // const color = getFeature(variant.featureHierarchy, '1/COLOR/') + // if (!features[color]) features[color] = [size] + // else if (!features[color].includes(size)) features[color].push(size) + // }) + + // Object.keys(features).forEach((color) => this.features[color] = sortSizes(features[color])) + + // let selectedVariant = this.product.variants.find((variant: any) => variant.productId === this.variantId) + + // if (!selectedVariant) { + // // if the variant does not have color or size as features + // selectedVariant = this.product.variants[0] + // showToast(translate("Selected variant not available. Reseting to first variant.")) + // } + + // if (selectedVariant) { + // this.selectedColor = getFeature(selectedVariant.featureHierarchy, '1/COLOR/') + // this.selectedSize = getFeature(selectedVariant.featureHierarchy, '1/SIZE/') + // } + // }, + // async updateVariant() { + // let variant + // if (this.selectedColor || this.selectedSize) { + // variant = this.product.variants.find((variant: any) => { + // const hasSize = !this.selectedSize || (this.selectedSize && getFeature(variant.featureHierarchy, '1/SIZE/') === this.selectedSize) + // const hasColor = !this.selectedColor || (this.selectedColor && getFeature(variant.featureHierarchy, '1/COLOR/') === this.selectedColor) + // return hasSize && hasColor + // }) + + // // if the selected size is not available for that color, default it to the first size available + // if (!variant) { + // this.selectedSize = this.features[this.selectedColor][0]; + // variant = this.product.variants.find((variant: any) => getFeature(variant.featureHierarchy, '1/SIZE/') === this.selectedSize) + // showToast(translate("Selected variant not available")) + // } + // } + // // if the variant does not have color or size as features + // this.currentVariant = variant || this.product.variants[0] + // this.variantId = this.currentVariant.variantId + // this.$route.query.variantId !== this.currentVariant.productId && (this.router.replace({path: this.$route.path, query: { variantId: this.currentVariant.productId } })); + // await this.getPoDetails() + // await this.getAtpCalcDetails() + // await this.prepareInvConfig() + // await this.prepareShopListings() + // await this.preparePoSummary() + // }, async getCtgryAndBrkrngJobs() { const systemJobEnumIds = JSON.parse(process.env.VUE_APP_CTGRY_AND_BRKRNG_JOB) this.store.dispatch('job/fetchCtgryAndBrkrngJobs', { systemJobEnumIds }).then(() => { From a5d39ce31bcd7ac1ce7ba753f79e8d267e88c243 Mon Sep 17 00:00:00 2001 From: amansinghbais Date: Wed, 3 Apr 2024 10:29:53 +0530 Subject: [PATCH 2/6] Improved: removed unused parameters and code (#166) --- src/views/catalog-product-details.vue | 52 +-------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/src/views/catalog-product-details.vue b/src/views/catalog-product-details.vue index cc4b4953..4b66ae63 100644 --- a/src/views/catalog-product-details.vue +++ b/src/views/catalog-product-details.vue @@ -490,7 +490,7 @@ export default defineComponent({ const variant = this.product.variants.find((variant: any) => { let isVariantAvailable = true - Object.entries(this.selectedFeatures).map((currentFeature, currentFeatureIndex) => { + Object.entries(this.selectedFeatures).map((currentFeature) => { if(getFeature(variant.featureHierarchy, `1/${currentFeature[0]}`) != currentFeature[1]){ isVariantAvailable = false } @@ -604,56 +604,6 @@ export default defineComponent({ await this.prepareShopListings() await this.preparePoSummary() }, - // getFeatures() { - // const features = {} as any - // this.product.variants.map((variant: any) => { - // const size = getFeature(variant.featureHierarchy, '1/SIZE/') - // const color = getFeature(variant.featureHierarchy, '1/COLOR/') - // if (!features[color]) features[color] = [size] - // else if (!features[color].includes(size)) features[color].push(size) - // }) - - // Object.keys(features).forEach((color) => this.features[color] = sortSizes(features[color])) - - // let selectedVariant = this.product.variants.find((variant: any) => variant.productId === this.variantId) - - // if (!selectedVariant) { - // // if the variant does not have color or size as features - // selectedVariant = this.product.variants[0] - // showToast(translate("Selected variant not available. Reseting to first variant.")) - // } - - // if (selectedVariant) { - // this.selectedColor = getFeature(selectedVariant.featureHierarchy, '1/COLOR/') - // this.selectedSize = getFeature(selectedVariant.featureHierarchy, '1/SIZE/') - // } - // }, - // async updateVariant() { - // let variant - // if (this.selectedColor || this.selectedSize) { - // variant = this.product.variants.find((variant: any) => { - // const hasSize = !this.selectedSize || (this.selectedSize && getFeature(variant.featureHierarchy, '1/SIZE/') === this.selectedSize) - // const hasColor = !this.selectedColor || (this.selectedColor && getFeature(variant.featureHierarchy, '1/COLOR/') === this.selectedColor) - // return hasSize && hasColor - // }) - - // // if the selected size is not available for that color, default it to the first size available - // if (!variant) { - // this.selectedSize = this.features[this.selectedColor][0]; - // variant = this.product.variants.find((variant: any) => getFeature(variant.featureHierarchy, '1/SIZE/') === this.selectedSize) - // showToast(translate("Selected variant not available")) - // } - // } - // // if the variant does not have color or size as features - // this.currentVariant = variant || this.product.variants[0] - // this.variantId = this.currentVariant.variantId - // this.$route.query.variantId !== this.currentVariant.productId && (this.router.replace({path: this.$route.path, query: { variantId: this.currentVariant.productId } })); - // await this.getPoDetails() - // await this.getAtpCalcDetails() - // await this.prepareInvConfig() - // await this.prepareShopListings() - // await this.preparePoSummary() - // }, async getCtgryAndBrkrngJobs() { const systemJobEnumIds = JSON.parse(process.env.VUE_APP_CTGRY_AND_BRKRNG_JOB) this.store.dispatch('job/fetchCtgryAndBrkrngJobs', { systemJobEnumIds }).then(() => { From a48fde6646e7f68aec1863bb9691f8e010c901d6 Mon Sep 17 00:00:00 2001 From: amansinghbais Date: Wed, 3 Apr 2024 11:55:14 +0530 Subject: [PATCH 3/6] Improved: simplified logic to update selected features (#166) --- src/views/catalog-product-details.vue | 41 +++++++++++++-------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/views/catalog-product-details.vue b/src/views/catalog-product-details.vue index 4b66ae63..8f310779 100644 --- a/src/views/catalog-product-details.vue +++ b/src/views/catalog-product-details.vue @@ -511,15 +511,9 @@ export default defineComponent({ }) return isVariantAvailable }) - - availableVariants[0].featureHierarchy.map((featureItem: any) => { - if(featureItem.startsWith('1/')){ - const featureItemSplitted = featureItem.split("/") - selectedFeatures[featureItemSplitted[1]] = featureItemSplitted[2] - } - }) + + this.updateSeletedFeatures(availableVariants[0]) this.currentVariant = availableVariants[0] - this.selectedFeatures = selectedFeatures showToast(translate("Selected variant not available. Reseting to first variant.")) } @@ -528,7 +522,6 @@ export default defineComponent({ }, getVariant() { let selectedVariant = this.product.variants.find((variant: any) => variant.productId === this.variantId) - let selectedFeatures = {} as any; if(!selectedVariant) { selectedVariant = this.product.variants[0] @@ -536,19 +529,7 @@ export default defineComponent({ this.$route.query.variantId !== selectedVariant.productId && (this.router.replace({path: this.$route.path, query: { variantId: selectedVariant.productId } })); } - selectedVariant.featureHierarchy.map((featureItem: any) => { - if(featureItem.startsWith('1/')){ - const featureItemSplitted = featureItem.split("/") - selectedFeatures[featureItemSplitted[1]] = featureItemSplitted[2] - } - }) - - selectedFeatures = Object.keys(selectedFeatures).sort().reduce((result:any, key) => { - result[key] = selectedFeatures[key]; - return result; - }, {}); - - this.selectedFeatures = selectedFeatures + this.updateSeletedFeatures(selectedVariant) this.currentVariant = selectedVariant }, getFeatures() { @@ -595,6 +576,22 @@ export default defineComponent({ this.features = features }, + updateSeletedFeatures(variant: any) { + let selectedFeatures = {} as any; + variant.featureHierarchy.map((featureItem: any) => { + if(featureItem.startsWith('1/')){ + const featureItemSplitted = featureItem.split("/") + selectedFeatures[featureItemSplitted[1]] = featureItemSplitted[2] + } + }) + + selectedFeatures = Object.keys(selectedFeatures).sort().reduce((result:any, key) => { + result[key] = selectedFeatures[key]; + return result; + }, {}); + + this.selectedFeatures = selectedFeatures + }, async updateVariant() { this.variantId = this.currentVariant.variantId this.$route.query.variantId !== this.currentVariant.productId && (this.router.replace({path: this.$route.path, query: { variantId: this.currentVariant.productId } })); From 691c63506bfa84d5c3145437adc92f2236562ac6 Mon Sep 17 00:00:00 2001 From: amansinghbais Date: Wed, 3 Apr 2024 12:18:48 +0530 Subject: [PATCH 4/6] Improved: logic for fetching features for the first time (#166) --- src/views/catalog-product-details.vue | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/views/catalog-product-details.vue b/src/views/catalog-product-details.vue index 8f310779..e91e6075 100644 --- a/src/views/catalog-product-details.vue +++ b/src/views/catalog-product-details.vue @@ -534,22 +534,22 @@ export default defineComponent({ }, getFeatures() { const selectedFeatures = this.selectedFeatures - const firstFeature = Object.keys(selectedFeatures)[0] - const features = {} as any; - this.product.variants.map((variant: any) => { - const featureOption = getFeature(variant.featureHierarchy, `1/${firstFeature}`) - if(!features[firstFeature]){ - features[firstFeature] = [featureOption] - } else{ - if(!features[firstFeature].includes(featureOption)) features[firstFeature].push(featureOption) + Object.entries(selectedFeatures).map((feature, featureIndex) => { + if(featureIndex === 0) { + const firstFeature = feature[0] + this.product.variants.map((variant: any) => { + const featureOption = getFeature(variant.featureHierarchy, `1/${firstFeature}`) + if(!features[firstFeature]){ + features[firstFeature] = [featureOption] + } else{ + if(!features[firstFeature].includes(featureOption)) features[firstFeature].push(featureOption) + } + }) } - }) - Object.entries(selectedFeatures).map((feature, featureIndex) => { const nextFeature = Object.entries(selectedFeatures).find((currentFeature, currentFeatureIndex) => currentFeatureIndex === featureIndex + 1) - if(nextFeature) { const nextFeatureCategory = nextFeature[0] From 51e11e850a8e1bfdd894311b51b294b7e7e0670b Mon Sep 17 00:00:00 2001 From: amansinghbais Date: Wed, 3 Apr 2024 12:36:10 +0530 Subject: [PATCH 5/6] Improved: logic to update variantId in url on changing (#166) --- src/views/catalog-product-details.vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/views/catalog-product-details.vue b/src/views/catalog-product-details.vue index e91e6075..1a592f73 100644 --- a/src/views/catalog-product-details.vue +++ b/src/views/catalog-product-details.vue @@ -488,7 +488,7 @@ export default defineComponent({ const selectedFeatures = this.selectedFeatures selectedFeatures[feature] = option - const variant = this.product.variants.find((variant: any) => { + let variant = this.product.variants.find((variant: any) => { let isVariantAvailable = true Object.entries(this.selectedFeatures).map((currentFeature) => { if(getFeature(variant.featureHierarchy, `1/${currentFeature[0]}`) != currentFeature[1]){ @@ -513,10 +513,11 @@ export default defineComponent({ }) this.updateSeletedFeatures(availableVariants[0]) - this.currentVariant = availableVariants[0] + variant = availableVariants[0] showToast(translate("Selected variant not available. Reseting to first variant.")) } + this.currentVariant = variant; this.getFeatures() this.updateVariant(); }, From dc5df8e40969db2fd3ef3a2bcdce941affcb82d3 Mon Sep 17 00:00:00 2001 From: amansinghbais Date: Wed, 27 Nov 2024 15:50:49 +0530 Subject: [PATCH 6/6] Improved: optmized the if-else condition on audit details page (#166) --- src/views/audit-product-details.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/audit-product-details.vue b/src/views/audit-product-details.vue index ceb15307..982fdd50 100644 --- a/src/views/audit-product-details.vue +++ b/src/views/audit-product-details.vue @@ -542,8 +542,8 @@ export default defineComponent({ const featureOption = getFeature(variant.featureHierarchy, `1/${firstFeature}`) if(!features[firstFeature]){ features[firstFeature] = [featureOption] - } else{ - if(!features[firstFeature].includes(featureOption)) features[firstFeature].push(featureOption) + } else if(!features[firstFeature].includes(featureOption)){ + features[firstFeature].push(featureOption) } }) }