Skip to content

Commit

Permalink
Merge pull request #157 from amansinghbais/facilities/#152
Browse files Browse the repository at this point in the history
Implemented: functionality to associate and remove facilities to group from find groups page (#152)
  • Loading branch information
ymaheshwari1 authored Jan 9, 2024
2 parents 0cde687 + 7b44125 commit 14f4fa5
Show file tree
Hide file tree
Showing 5 changed files with 351 additions and 10 deletions.
240 changes: 240 additions & 0 deletions src/components/AddFacilityToGroupModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
<template>
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-button @click="closeModal">
<ion-icon slot="icon-only" :icon="close" />
</ion-button>
</ion-buttons>
<ion-title>{{ translate("Select facilities") }}</ion-title>
</ion-toolbar>
</ion-header>

<ion-content class="ion-padding">
<ion-searchbar v-model="queryString" @keyup.enter="queryString = $event.target.value; fetchFacilities()" />
<ion-chip outline>
{{ translate("Facilities:", { count: selectedFacilityValues.length }) }}
</ion-chip>

<ion-list>
<div class="ion-padding" v-if="!facilities.length">
{{ translate("No facility found") }}
</div>
<div v-else>
<ion-item v-for="(facility, index) in facilities" :key="index" @click="updateSelectedFacilities(facility.facilityId)" lines="none">
<ion-label>
{{ facility.facilityName }}
<p>{{ facility.facilityId }}</p>
</ion-label>
<ion-checkbox :checked="isFacilitySelected(facility.facilityId)" />
</ion-item>
</div>
</ion-list>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button @click="confirmSave()">
<ion-icon :icon="saveOutline" />
</ion-fab-button>
</ion-fab>
</ion-content>
</template>

<script lang="ts">
import {
IonButton,
IonButtons,
IonCheckbox,
IonChip,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonSearchbar,
IonTitle,
IonToolbar,
modalController
} from "@ionic/vue";
import { defineComponent } from "vue";
import { close, closeCircle, saveOutline } from "ionicons/icons";
import { useStore } from "vuex";
import { hasError } from "@/adapter";
import logger from "@/logger"
import { translate } from '@hotwax/dxp-components'
import { FacilityService } from "@/services/FacilityService";
import { DateTime } from "luxon";
import { showToast } from "@/utils";
export default defineComponent({
name: "AddFacilityToGroupModal",
components: {
IonButtons,
IonButton,
IonCheckbox,
IonChip,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
IonLabel,
IonList,
IonSearchbar,
IonTitle,
IonToolbar,
},
data() {
return {
queryString: '',
facilities: [] as any,
selectedFacilities: [] as any,
selectedFacilityValues: [] as any
}
},
props: ['facilityGroupId'],
mounted() {
Promise.all([this.fetchFacilities(), this.fetchAssociatedFacilities()])
},
methods: {
closeModal() {
modalController.dismiss()
},
async fetchFacilities() {
this.facilities = []
let filters = {} as any;
if(this.queryString) {
filters["facilityId_value"] = this.queryString
filters["facilityId_op"] = "contains"
filters["facilityId_ic"] = "Y"
filters["facilityId_grp"] = "1"
filters["facilityName_value"] = this.queryString
filters["facilityName_op"] = "contains"
filters["facilityName_ic"] = "Y"
filters["facilityName_grp"] = "1"
filters["grp_op_1"] = "OR"
}
const params = {
"inputFields": {
...filters
},
"entityName": "FacilityView",
"noConditionFind": "Y",
"distinct": "Y",
"fromDateName": "facilityGroupFromDate",
"thruDateName": "facilityGroupThruDate",
"filterByDate": "Y",
"fieldList": ["facilityId", "facilityName", "fromDate"],
// By default we show only 20 facilities, others get rendered on search query.
"viewSize": 20
}
try {
const resp = await FacilityService.fetchFacilities(params)
if (!hasError(resp) && resp.data.count) {
this.facilities = resp.data.docs
} else {
throw resp.data
}
} catch (error) {
logger.error(error)
}
},
async fetchAssociatedFacilities() {
try {
const resp = await FacilityService.fetchAssociatedFacilitiesToGroup({
"inputFields": {
"facilityGroupId": this.facilityGroupId
},
"viewSize": 250, // maximum view size
"entityName": 'FacilityGroupAndMember',
"noConditionFind": "Y",
"filterByDate": 'Y',
"fieldList": ['facilityId', 'fromDate']
})
if(!hasError(resp)) {
this.selectedFacilities = resp.data.docs
this.selectedFacilityValues = JSON.parse(JSON.stringify(resp.data.docs))
} else {
throw resp.data
}
} catch(err) {
logger.error(err)
}
},
updateSelectedFacilities(id: string) {
const facility = this.isFacilitySelected(id)
if (facility) {
// if facility is already selected then removing that facility from the list on click
this.selectedFacilityValues = this.selectedFacilityValues.filter((facility: any) => facility.facilityId !== id)
} else {
this.selectedFacilityValues.push(this.facilities.find((facility: any) => facility.facilityId == id))
}
},
isFacilitySelected(facilityId: any) {
return this.selectedFacilityValues.some((facility: any) => facility.facilityId === facilityId)
},
async confirmSave() {
const facilitiesToAdd = this.selectedFacilityValues.filter((selectedFacility: any) => !this.selectedFacilities.some((facility: any) => facility.facilityId === selectedFacility.facilityId))
const facilitiesToRemove = this.selectedFacilities.filter((facility: any) => !this.selectedFacilityValues.some((selectedFacility: any) => facility.facilityId === selectedFacility.facilityId))
const removeResponses = await Promise.allSettled(facilitiesToRemove
.map(async (facility: any) => await FacilityService.updateFacilityToGroup({
"facilityId": facility.facilityId,
"facilityGroupId": this.facilityGroupId,
"fromDate": facility.fromDate,
"thruDate": DateTime.now().toMillis()
}))
)
const addResponses = await Promise.allSettled(facilitiesToAdd
.map(async (facility: any) => await FacilityService.addFacilityToGroup({
"facilityId": facility.facilityId,
"facilityGroupId": this.facilityGroupId
}))
)
const hasFailedResponse = [...removeResponses, ...addResponses].some((response: any) => response.status === 'rejected')
if (hasFailedResponse) {
showToast(translate("Failed to associate some facilites to group."))
} else {
showToast(translate("Facilities associated to group successfully."))
}
this.fetchGroups()
modalController.dismiss()
},
async fetchGroups(vSize?: any, vIndex?: any) {
const viewSize = vSize ? vSize : process.env.VUE_APP_VIEW_SIZE;
const viewIndex = vIndex ? vIndex : 0;
const payload = {
viewSize,
viewIndex
};
await this.store.dispatch('facility/fetchFacilityGroups', payload)
},
},
setup() {
const store = useStore();
return {
close,
saveOutline,
closeCircle,
store,
translate
};
}
});
</script>

<style scoped>
ion-content {
--padding-bottom: 80px;
}
</style>
78 changes: 78 additions & 0 deletions src/components/GroupActionsPopover.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<template>
<ion-content>
<ion-list>
<ion-list-header>
{{ group.facilityGroupName }}
</ion-list-header>
<ion-item button @click="viewFacilities(group.facilityGroupId)">
{{ translate("View facilities") }}
<ion-icon :icon="openOutline" color="primary" slot="end" />
</ion-item>
<ion-item button lines="none" @click="openAddFacilityToGroupsModal(group.facilityGroupId)">
{{ translate("Quick edit") }}
</ion-item>
</ion-list>
</ion-content>
</template>

<script lang="ts">
import {
IonContent,
IonIcon,
IonItem,
IonList,
IonListHeader,
modalController,
popoverController
} from "@ionic/vue";
import { defineComponent } from "vue";
import { translate } from '@hotwax/dxp-components'
import { mapGetters, useStore } from "vuex";
import { openOutline } from 'ionicons/icons'
import AddFacilityToGroupsModal from '@/components/AddFacilityToGroupModal.vue'
export default defineComponent({
name: "GroupActionsPopover",
components: {
IonContent,
IonIcon,
IonItem,
IonList,
IonListHeader
},
computed: {
...mapGetters({
groups: 'facility/getFacilityGroups',
facilityQuery: "facility/getFacilityQuery",
})
},
props: ['group'],
methods: {
async viewFacilities(facilityGroupId: string) {
await this.store.dispatch('facility/updateFacilityQuery', { ...this.facilityQuery, facilityGroupId })
this.$router.push({ path: `/find-facilities` })
popoverController.dismiss()
},
async openAddFacilityToGroupsModal(facilityGroupId: any) {
const modal = await modalController.create({
component: AddFacilityToGroupsModal,
componentProps: { facilityGroupId }
})
modal.onDidDismiss().then(() =>{
popoverController.dismiss()
})
modal.present()
},
},
setup() {
const store = useStore();
return {
openOutline,
store,
translate
}
},
});
</script>
8 changes: 8 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
"Description": "Description",
"Dismiss": "Dismiss",
"Distribution Center": "Distribution Center",
"Edit description": "Edit description",
"Failed to associate calendar to the facility.": "Failed to associate calendar to the facility.",
"Filters": "Filters",
"Edit": "Edit",
Expand All @@ -78,6 +79,8 @@
"External mapping updated successfully": "External mapping updated successfully",
"External mappings": "External mappings",
"Facilities": "Facilities",
"Facilities:": "Facilities: {count}",
"Facilities associated to group successfully.": "Facilities associated to group successfully.",
"Facility": "Facility",
"Facility address created successfully.": "Facility address created successfully.",
"Facility address updated successfully.": "Facility address updated successfully.",
Expand Down Expand Up @@ -105,6 +108,7 @@
"Failed to add some product stores to the facility.": "Failed to add some product stores to the facility.",
"Failed to archive parking.": "Failed to archive parking.",
"Failed to associate group with system group types.": "Failed to associate group with system group types.",
"Failed to associate some facilites to group.": "Failed to associate some facilites to group.",
"Failed to create calendar to the facility.": "Failed to create calendar to the facility.",
"Failed to create external mapping": "Failed to create external mapping",
"Failed to create facility.": "Failed to create facility.",
Expand Down Expand Up @@ -207,6 +211,7 @@
"No capacity": "No capacity",
"No capacity sets the fulfillment capacity to 0, preventing any new orders from being allocated to this facility. Use the \"Reject all orders\" option in the fulfillment pages to clear your facilities fulfillment queue. To add a fulfillment capacity to this facility, use the custom option.": "No capacity sets the fulfillment capacity to 0, preventing any new orders from being allocated to this facility. Use the \"Reject all orders\" option in the fulfillment pages to clear your facilities fulfillment queue. To add a fulfillment capacity to this facility, use the custom option.",
"No facilities found": "No facilities found",
"No facility found": "No facility found",
"No fulfillment capacity": "No fulfillment capacity",
"No groups found": "No groups found",
"no longer sells on": "{facilityName} no longer sells on {facilityGroupId}.",
Expand Down Expand Up @@ -258,6 +263,7 @@
"Product Store": "Product Store",
"Product Stores": "Product Stores",
"Product stores updated successfully.": "Product stores updated successfully.",
"Quick edit": "Quick edit",
"Reason:": "Reason:",
"Regenerate": "Regenerate",
"Remove": "Remove",
Expand Down Expand Up @@ -288,6 +294,7 @@
"Select country": "Select country",
"Select state": "Select state",
"Search facilities": "Search facilities",
"Select facilities": "Select facilities",
"Search groups": "Search groups",
"Search time zones": "Search time zones",
"Select time zone": "Select time zone",
Expand Down Expand Up @@ -354,6 +361,7 @@
"Uses native fulfillment app": "Uses native fulfillment app",
"Version: ": "Version: { appVersion }",
"View details": "View details",
"View facilities": "View facilities",
"View order count history": "View order count history",
"View other schedules": "View other schedules",
"Warehouses": "Warehouses",
Expand Down
Loading

0 comments on commit 14f4fa5

Please sign in to comment.