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: Clean up UI for BOPIS inventory lookup (#470) #509

Open
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

ashutosh7i
Copy link
Collaborator

Related Issues

#470

Short Description and Why It's Useful

  1. Removed ion padding on content
  2. Moved searchbar into toolbar
  3. Displayed distance to facility if lat long is available
  4. Displayed operating hours if available
  5. When the option to hide out of stock stores is disabled, all locations will be shown with their available details

Screenshots of Visual Changes before/after (If There Are Any)

  1. Implemented Mockup-
    image

  2. Accordion dropdown shows calendar-
    image

  3. Hide facilities without stock, alphabetically sorted-
    image

  4. Hide facilities without stock, sorted by distance-
    image

  5. Sorting by distance only-
    image

  6. Searchbar testing-
    image

Contribution and Currently Important Rules Acceptance

@ashutosh7i ashutosh7i changed the title Improved: created a new branch with issue-number (470), added internalization texts in locales/ files and code improvements. Implemented: Clean up UI for BOPIS inventory lookup (#470) Feb 10, 2025
async fetchCurrentFacilityLatLon({ commit }, facilityId) {
const payload = {
inputFields: {
facilityId: facilityId
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
facilityId: facilityId
facilityId

}
},

async fetchStoreLookupByLatLon({ commit }, point) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
async fetchStoreLookupByLatLon({ commit }, point) {
async fetchStoresInformation({ commit }, point) {

Copy link
Contributor

Choose a reason for hiding this comment

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

Also update the service name, state and mutation name accordingly.

throw resp.data
}
} catch (err) {
console.error("Failed to fetch stores by lat/lon information", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
console.error("Failed to fetch stores by lat/lon information", err)
logger.error("Failed to fetch stores information by lat/lon", err)

if (this.hideEmptyStores) {
filteredInventory = filteredInventory.filter((store: any) => store.stock > 0);
}
this.atpMappedStoresInventory = filteredInventory;
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
this.atpMappedStoresInventory = filteredInventory;
this.storesWithInventory = filteredInventory;

<ion-note v-if="hasWeekCalendar(inventory)" :color="inventory.isOpen ? '' : 'danger'">
{{ inventory.hoursDisplay }}
</ion-note>
<p v-if="typeof inventory.dist === 'number'">{{ Math.round(inventory.dist) }} miles</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we have added typeof check here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My logic behind adding this typeof check here is to filter out rendering of invalid stores,
while exploring the api (storeLookup) i found out certain stores had a string value "Infinity" in this dist field
This check omits the non number results from being rendered.

image

do i need to include these stores too?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, this stores should be included without displaying any distance and should be displayed at last.

</ion-item>
</ion-list>
<ion-accordion-group v-if="atpMappedStoresInventory.length">
<ion-accordion v-for="inventory in atpMappedStoresInventory" :key="inventory.storeCode"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
<ion-accordion v-for="inventory in atpMappedStoresInventory" :key="inventory.storeCode"
<ion-accordion v-for="store in storesWithInventory" :key="inventory.storeCode"

</ion-item>
</ion-list>
<ion-accordion-group v-if="atpMappedStoresInventory.length">
<ion-accordion v-for="inventory in atpMappedStoresInventory" :key="inventory.storeCode"
:value="String(inventory.storeCode)" :toggle-icon="hasWeekCalendar(inventory) ? chevronDownOutline : false"
Copy link
Contributor

@ymaheshwari1 ymaheshwari1 Feb 10, 2025

Choose a reason for hiding this comment

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

I think we do not need this String conversion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

right, it can be safely removed.

</ion-note>
<p v-if="typeof inventory.dist === 'number'">{{ Math.round(inventory.dist) }} miles</p>
</ion-label>
<ion-button fill="clear" slot="end">
Copy link
Contributor

Choose a reason for hiding this comment

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

We do not need an ion-button here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

ok, replacing button with a div.

</ion-item>
</ion-list>
<ion-accordion-group v-if="storesWithInventory.length">
<ion-accordion v-for="store in storesWithInventory" :key="store.storeCode" :value="store.storeCode"
:toggle-icon="hasWeekCalendar(store) ? chevronDownOutline : false" :readonly="!hasWeekCalendar(store)">
Copy link
Contributor

Choose a reason for hiding this comment

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

We can't use false as a value for toggle icon, please update this.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also instead of handling accordion for displaying stores without calendar we can directly use ion-item, because using accordion will reserve some space for toggle-icon that will result in an empty space at the end.

<ion-list>
<ion-item>
<ion-label>{{ translate("Hide facilities without stock") }}</ion-label>
<ion-toggle @click="toggleHideEmptyStock" />
Copy link
Contributor

Choose a reason for hiding this comment

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

For some specific components, ionic always require a label, so check the ion-toggle doc for defining label and update the UI accordingly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i assume we are referring to this warning from console-
Screenshot 2025-02-12 144139

When i added an "aria-label" to the ion-toggle component it suppressed the warning but the ui got spoilt.
Screenshot 2025-02-12 143720

to overcome this, when i explored docs, i found another way of using ion-toggle component with inline label-placement property, that allows label to be directly passed inside of ion-toggle

This solved issue

Screenshot 2025-02-12 143819

docs referances-
Migrating from Legacy Toggle Syntax

const openTime = DateTime.fromFormat(store[openKey], 'HH:mm:ss');
const closeTime = DateTime.fromFormat(store[closeKey], 'HH:mm:ss');

const openDisplay = openTime.toFormat('ha').toLowerCase();
Copy link
Contributor

Choose a reason for hiding this comment

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

Display store timing with hours and minutes.

const isOpen = now >= openTime && now <= closeTime;

return {
display: isOpen ? `Open: ${openDisplay} - ${closeDisplay}` : 'Closed',
Copy link
Contributor

Choose a reason for hiding this comment

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

Need to translate Open and Closed static labels

mounted() {
computed: {
...mapGetters({
FacilityInformation: 'util/getCurrentFacilityInformation',
Copy link
Contributor

@ymaheshwari1 ymaheshwari1 Feb 11, 2025

Choose a reason for hiding this comment

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

Suggested change
FacilityInformation: 'util/getCurrentFacilityInformation',
currentFacilityLatLon: 'util/getCurrentFacilityInformation',

return state.currentFacilityInformation ? state.currentFacilityInformation : {}
},
getStoresInformation: (state) => {
return state.storesInformation ? state.storesInformation : {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return state.storesInformation ? state.storesInformation : {}
return state.storesInformation ? state.storesInformation : []

FacilityInformation: 'util/getCurrentFacilityInformation',
storesInformation: 'util/getStoresInformation'
}),
currentFacilityCoords() {
Copy link
Contributor

Choose a reason for hiding this comment

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

This method is not required, we can directly use the getter wherever required.

Comment on lines 149 to 154
await this.store.dispatch("util/fetchCurrentFacilityInformation", this.currentFacilityId);
if (this.currentFacilityCoords?.latitude && this.currentFacilityCoords?.longitude) {
await this.store.dispatch("util/fetchStoresInformation", {
latitude: this.currentFacilityCoords.latitude,
longitude: this.currentFacilityCoords.longitude
});
Copy link
Contributor

Choose a reason for hiding this comment

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

We should not fetch facility latLng and stores information on every mounted hook call, as this information is not changed frequently.
We should only call this apis if the state does not have data for these store states, and clear this data whenever facility changes from settings page.

Comment on lines 30 to 35
[types.UTIL_CURRENT_FACILITY_INFORMATION_UPDATED] (state, payload) {
state.currentFacilityInformation = payload
},
[types.UTIL_STORES_INFORMATION_UPDATED] (state, payload) {
state.storesInformation = payload
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Clear the state on logout.

@@ -15,7 +15,9 @@ const utilModule: Module<UtilState, RootState> = {
partyNames: {},
cancelReasons: [],
facilities: {},
enumerations: {}
enumerations: {},
currentFacilityInformation: {},
Copy link
Contributor

Choose a reason for hiding this comment

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

We can rename it to facilitiesLatLng and store multiple facility latLng in the format:

facilitiesLatLng: {
  facilityId: { latitude: value, longitude: value }
}

So when fetching the facility latLng from action we can first check in the state that if the latLng information is available, and only make api call if the information is not available in state.

Making this change will require all the related getter and mutation changes as well.

…toggle label warning fix, internationalization of static texts and calendar and store open time minutes display added.
…CurrentFacilityLatLon and related state changes, cleared state on logout and facility change.
// Create a copy of otherStoresInventory on mount
this.storesInventory = this.otherStoresInventory.slice();

try {
console.log(this.storesInventory);
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove unwanted console log statement.

Comment on lines 30 to 32
getCurrentFacilityLatLon: (state) => {
return state.facilitiesLatLng ? state.facilitiesLatLng : {}
},
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
getCurrentFacilityLatLon: (state) => {
return state.facilitiesLatLng ? state.facilitiesLatLng : {}
},
getFacilityLatLon: (state) => (facilityId: string) => {
return state.facilitiesLatLng[facilityId] ? state.facilitiesLatLng[facilityId] : {}
},

@@ -7,3 +7,5 @@ export const UTIL_PARTY_NAMES_UPDATED = SN_UTIL + '/PARTY_NAMES_UPDATED'
export const UTIL_CANCEL_REASONS_UPDATED = SN_UTIL + '/CANCEL_REASONS_UPDATED'
export const UTIL_FACILITIES_UPDATED = SN_UTIL + '/FACILITIES_UPDATED'
export const UTIL_ENUMERATIONS_UPDATED = SN_UTIL + '/ENUMERATIONS_UPDATED'
export const UTIL_CURRENT_FACILITY_LAT_LON_UPDATED = SN_UTIL + '/CURRENT_FACILITY_LAT_LON_UPDATED'
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
export const UTIL_CURRENT_FACILITY_LAT_LON_UPDATED = SN_UTIL + '/CURRENT_FACILITY_LAT_LON_UPDATED'
export const UTIL_FACILITY_LAT_LON_UPDATED = SN_UTIL + '/FACILITY_LAT_LON_UPDATED'

)

if (validCoords) {
commit(types.UTIL_CURRENT_FACILITY_LAT_LON_UPDATED, validCoords)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
commit(types.UTIL_CURRENT_FACILITY_LAT_LON_UPDATED, validCoords)
commit(types.UTIL_CURRENT_FACILITY_LAT_LON_UPDATED, { facilityId, validCoords })

@@ -27,5 +27,11 @@ const mutations: MutationTree <UtilState> = {
[types.UTIL_ENUMERATIONS_UPDATED] (state, payload) {
state.enumerations = payload
},
[types.UTIL_CURRENT_FACILITY_LAT_LON_UPDATED] (state, payload) {
state.facilitiesLatLng = payload
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
state.facilitiesLatLng = payload
state.facilitiesLatLng[payload.facilityId] = payload.validCoords

mounted() {
computed: {
...mapGetters({
FacilityInformation: 'util/getCurrentFacilityLatLon',
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
FacilityInformation: 'util/getCurrentFacilityLatLon',
facilityLatLon: 'util/getCurrentFacilityLatLon',

@@ -314,7 +314,7 @@ export default defineComponent({
async getOtherStoresInventoryDetails() {
const otherStoresInventoryModal = await modalController.create({
component: OtherStoresInventoryModal,
componentProps: { otherStoresInventory: this.otherStoresInventoryDetails }
componentProps: { otherStoresInventory: this.otherStoresInventoryDetails, currentFacilityId: this.currentFacility?.facilityId }
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is still not handled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants