Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented: functionality to product store card on facility details page (#10) #14

Merged
merged 25 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7b8ee92
Implemented: service and actions for fetching all product Stores and …
amansinghbais Nov 17, 2023
1450c40
Implemented: api and code for adding and removing product stores from…
amansinghbais Nov 17, 2023
7ce2c03
Improved: code for unlink functionality, and translation entries (#10)
amansinghbais Nov 17, 2023
d4eed57
Improved: method name, props entry order (#10)
amansinghbais Nov 17, 2023
7f39d25
Merge branch 'main' of https://github.com/hotwax/facilities into faci…
amansinghbais Nov 17, 2023
aada1d4
Improved: popover component name, conditions in getProductStores acti…
amansinghbais Nov 17, 2023
6a35e72
Merge branch 'main' of https://github.com/hotwax/facilities into faci…
amansinghbais Nov 17, 2023
d0e9a70
Merge branch 'main' of https://github.com/hotwax/facilities into faci…
amansinghbais Nov 21, 2023
eb969c2
Improved: code for adding support for make primary functionality (#10)
amansinghbais Nov 21, 2023
12aea73
Implemented: make primary functionality (#10)
amansinghbais Nov 22, 2023
ebf0d9f
Improved: api payload for createFacilityGroup (#10)
amansinghbais Nov 23, 2023
094ffde
Improved: make primary functionality based on productStoreId and resp…
amansinghbais Nov 23, 2023
66d4e9a
Improved: code for refetching primaryMember on unlink event, disabled…
amansinghbais Nov 23, 2023
d7844a1
Improved: reverted unuseful changes (#10)
amansinghbais Nov 23, 2023
c8af8b5
Improved: code for correct argument type, alphabetical ordering (#10)
amansinghbais Nov 23, 2023
6d2b474
Improved: save action for selectProductStoreModal to be performed fro…
amansinghbais Nov 23, 2023
0ab2d61
Improved: code to get store detail from util getter (#10)
amansinghbais Nov 23, 2023
ff26676
Reverted: unwanted space in getter (#10)
amansinghbais Nov 23, 2023
719b0e4
Implemented: feature to toggle functionality from popover (#10)
amansinghbais Nov 23, 2023
05f582c
Merge branch 'main' of https://github.com/hotwax/facilities into faci…
amansinghbais Nov 23, 2023
b40fc29
Merge branch 'main' of https://github.com/hotwax/facilities into faci…
amansinghbais Nov 23, 2023
349912f
Improved: code to disable selectProductStore modal when nothing selec…
amansinghbais Nov 23, 2023
057e4b6
Improved: variable name, toast message and api error handling (#10)
amansinghbais Nov 24, 2023
68819c3
Improved: alphabetical ordering in imports (#10)
amansinghbais Nov 27, 2023
c301ab1
Improved: method name for removing primary status, and added comments…
amansinghbais Nov 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 0 additions & 46 deletions src/components/OpenStorePopover.vue

This file was deleted.

195 changes: 195 additions & 0 deletions src/components/ProductStorePopover.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
<template>
<ion-content>
<ion-list>
<ion-list-header>{{ getProductStore(currentProductStore.productStoreId).storeName }}</ion-list-header>
<ion-item button @click="makePrimary()">
{{ translate("Primary") }}
<ion-icon slot="end" :color="primaryMember.facilityGroupId === currentProductStore.productStoreId ? 'warning' : ''" :icon="primaryMember.facilityGroupId === currentProductStore.productStoreId ? star : starOutline" />
</ion-item>
<ion-item button lines="none" @click="removeStoreFromFacility()">
{{ translate("Unlink") }}
<ion-icon slot="end" :icon="removeCircleOutline" />
</ion-item>
</ion-list>
</ion-content>
</template>

<script lang="ts">
import {
IonContent,
IonList,
IonListHeader,
IonIcon,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arrange imports in alphabetical order.

IonItem,
popoverController
} from "@ionic/vue";
import { defineComponent } from "vue";
import { removeCircleOutline, star, starOutline } from "ionicons/icons";
import { translate } from "@hotwax/dxp-components";
import { mapGetters, useStore } from "vuex";
import { FacilityService } from "@/services/FacilityService";
import { DateTime } from "luxon";
import { hasError } from "@/adapter";
import { showToast } from "@/utils";
import logger from "@/logger";

export default defineComponent({
name: "ProductStorePopover",
components: {
IonContent,
IonList,
IonListHeader,
IonIcon,
IonItem
},
props: ['currentProductStore', 'facilityId', 'primaryMember'],
computed: {
...mapGetters({
facilityProductStores: 'facility/getFacilityProductStores',
productStores: 'util/getProductStores',
getProductStore: 'util/getProductStore'
})
},
methods: {
async removeStoreFromFacility() {
try {
const resp = await FacilityService.updateProductStoreFacility({
facilityId: this.facilityId,
productStoreId: this.currentProductStore.productStoreId,
fromDate: this.currentProductStore.fromDate,
thruDate: DateTime.now().toMillis()
})

if(!hasError(resp)) {
showToast(translate('Store unlinked successfully.'))

// Removing store from primary Member group if primary.
if(this.currentProductStore.productStoreId === this.primaryMember.facilityGroupId){
await this.removeProductFromPrimaryMember()
}

// refetching product stores with updated roles
await this.store.dispatch('facility/getFacilityProductStores', { facilityId: this.facilityId })
} else {
throw resp.data
}
} catch(err) {
logger.error(err)
showToast(translate('Store unlink failed.'))
}
popoverController.dismiss()
},
async makePrimary() {
const productStoreId = this.currentProductStore.productStoreId
if(this.primaryMember.facilityGroupId === productStoreId) {
this.removeProductFromPrimaryMember()
popoverController.dismiss()
return;
}

let resp;
let facilityGroupId;

facilityGroupId = await this.fetchFacilityGroup(productStoreId)

if(!facilityGroupId) {
facilityGroupId = await this.createFacilityGroup(productStoreId)
}

if(facilityGroupId) {
try {
resp = await FacilityService.addFacilityToGroup({
facilityId: this.facilityId,
facilityGroupId: facilityGroupId
})

if(!hasError(resp)) {
// Remove old primary store
if(this.primaryMember.facilityGroupId) {
await this.removeProductFromPrimaryMember()
}
} else {
throw resp.data
}
} catch(err) {
showToast(translate("Failed to make product store primary."))
logger.error(err)
}
} else {
showToast(translate("Failed to make product store primary."))
}
popoverController.dismiss()
},
async fetchFacilityGroup(productStoreId: string) {
let facilityGroupId;
let resp;
try {
resp = await FacilityService.fetchFacilityGroup({
inputFields: {
facilityGroupId: productStoreId
},
entityName: 'FacilityGroup',
viewSize: 100
})

if(!hasError(resp)) {
facilityGroupId = resp.data.docs[0].facilityGroupId
} else {
throw resp.data
}
} catch(err) {
logger.error(err)
}
return facilityGroupId
},
async createFacilityGroup(productStoreId: string) {
let facilityGroupId;
try {
const resp = await FacilityService.createFacilityGroup({
facilityGroupTypeId: 'FEATURING',
facilityGroupName: this.getProductStore(productStoreId).storeName,
facilityGroupId: productStoreId
})

if(!hasError(resp)) {
facilityGroupId = resp.data.facilityGroupId
} else {
throw resp.data
}
} catch(err) {
logger.error(err)
}

return facilityGroupId
},
async removeProductFromPrimaryMember() {
let resp;
try {
resp = await FacilityService.updateFacilityToGroup({
"facilityId": this.facilityId,
"facilityGroupId": this.primaryMember.facilityGroupId,
"fromDate": this.primaryMember.fromDate,
"thruDate": DateTime.now().toMillis()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle case when having error in the resp.

})

if(hasError(resp)) {
throw resp.data
}
} catch (err) {
logger.error(err)
}
}
},
setup() {
const store = useStore();

return {
removeCircleOutline,
star,
starOutline,
store,
translate
};
}
});
</script>
56 changes: 50 additions & 6 deletions src/components/SelectProductStoreModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,16 @@

<ion-content>
<ion-list>
<ion-item>
<ion-item v-for="productStore in productStores" :key="productStore.productStoreId">
<ion-label>
{{ "Demo Store" }}
<p>{{ "STORE_ID" }}</p>
{{ productStore.storeName }}
<p>{{ productStore.productStoreId }}</p>
</ion-label>
<ion-checkbox slot="end" :checked="true" />
<ion-checkbox slot="end" :checked="isSelected(productStore.productStoreId)" @ionChange="toggleProductStoreSelection(productStore)" />
</ion-item>
</ion-list>

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button>
<ion-fab-button :disabled="isProductStoreUpdated()" @click="saveProductStores()">
<ion-icon :icon="saveOutline" />
</ion-fab-button>
</ion-fab>
Expand All @@ -49,6 +48,7 @@ import {
import { defineComponent } from "vue";
import { closeOutline, saveOutline } from "ionicons/icons";
import { translate } from '@hotwax/dxp-components'
import { mapGetters, useStore } from "vuex";

export default defineComponent({
name: "SelectProductStoreModal",
Expand All @@ -67,15 +67,59 @@ export default defineComponent({
IonTitle,
IonToolbar
},
computed: {
...mapGetters({
productStores: 'util/getProductStores',
facilityProductStores: 'facility/getFacilityProductStores',
})
},
props: ["facilityId", "selectedProductStores"],
data() {
return {
selectedProductStoreValues: JSON.parse(JSON.stringify(this.selectedProductStores)),
}
},
methods: {
closeModal() {
modalController.dismiss({ dismissed: true});
},
async saveProductStores() {
const productStoresToCreate = this.selectedProductStoreValues.filter((selectedFacility: any) => !this.selectedProductStores.some((facility: any) => facility.facilityId === selectedFacility.facilityId))
const productStoresToRemove = this.selectedProductStores.filter((facility: any) => !this.selectedProductStoreValues.some((selectedFacility: any) => facility.facilityId === selectedFacility.facilityId))

modalController.dismiss({
dismissed: true,
value: {
selectedProductStores: this.selectedProductStoreValues,
productStoresToCreate,
productStoresToRemove
}
});

modalController.dismiss()
},
toggleProductStoreSelection(updatedStore: any) {
let selectedStore = this.selectedProductStoreValues.some((store: any) => store.productStoreId === updatedStore.productStoreId);
if(selectedStore) {
this.selectedProductStoreValues = this.selectedProductStoreValues.filter((store: any) => store.productStoreId !== updatedStore.productStoreId);
} else {
this.selectedProductStoreValues.push(updatedStore);
}
},
isSelected(productStoreId: string) {
return this.selectedProductStoreValues.some((productStore: any) => productStore.productStoreId === productStoreId);
},
isProductStoreUpdated() {
return this.selectedProductStoreValues.some((selectedStore: any) => this.selectedProductStores.some((store: any) => store.productStoreId === selectedStore.productStoreId));
}
},
setup() {
const store = useStore()

return {
closeOutline,
saveOutline,
store,
translate
};
},
Expand Down
8 changes: 7 additions & 1 deletion src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"Failed to create shopify mapping": "Failed to create shopify mapping",
"Failed to fetch facility information": "Failed to fetch facility information",
"Failed to find the facility locations": "Failed to find the facility locations",
"Failed to make product store primary.": "Failed to make product store primary.",
"Failed to remove facility location": "Failed to remove facility location",
"Failed to remove facility mapping": "Failed to remove facility mapping",
"Failed to remove party from facility.": "Failed to remove party from facility.",
Expand All @@ -64,6 +65,7 @@
"Failed to update fulfillment capacity for ": "Failed to update fulfillment capacity for {facilityName}",
"Failed to update fulfillment setting": "Failed to update fulfillment setting",
"Failed to update shopify mapping": "Failed to update shopify mapping",
"Failed to update some product stores": "Failed to update some product stores",
"Failed to update some role(s).": "Failed to update some role(s).",
"Fetching TimeZones": "Fetching TimeZones",
"Find Facilities": "Find Facilities",
Expand Down Expand Up @@ -95,7 +97,6 @@
"Login failed": "Login failed",
"Logout": "Logout",
"Longitude": "Longitude",
"Make primary": "Make primary",
"Mapping ID": "Mapping ID",
"Mapping Name": "Mapping Name",
"Map facility to an external system": "Map facility to an external system",
Expand Down Expand Up @@ -126,9 +127,11 @@
"Please contact the administrator.": "Please contact the administrator.",
"Please enter a valid value": "Please enter a valid value",
"Please fill all the required fields": "Please fill all the required fields",
"Primary": "Primary",
"primary store": "primary store",
"Product Store": "Product Store",
"Product Stores": "Product Stores",
"Product stores updated successfully.": "Product stores updated successfully.",
"Reason:": "Reason:",
"Remove": "Remove",
"Remove location": "Remove location",
Expand Down Expand Up @@ -166,7 +169,10 @@
"Sorry, your username or password is incorrect. Please try again.": "Sorry, your username or password is incorrect. Please try again.",
"Staff": "Staff",
"State": "State",
"Store": "Store",
"store name": "store name",
"Store unlink failed.": "Store unlink failed.",
"Store unlinked successfully.": "Store unlinked successfully.",
"Sunday": "Sunday",
"The timezone you select is used to ensure automations you schedule are always accurate to the time you select.": "The timezone you select is used to ensure automations you schedule are always accurate to the time you select.",
"These values are used to help customers lookup how close they are to your stores when they are finding nearby stores.": "These values are used to help customers lookup how close they are to your stores when they are finding nearby stores.",
Expand Down
Loading
Loading