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: support for mobile view in Inprogress order details page (#244) #671

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
126 changes: 96 additions & 30 deletions src/views/EditPackagingModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,56 +7,52 @@
</ion-button>
</ion-buttons>
<ion-title>{{ translate("Edit packaging") }}</ion-title>
<ion-buttons slot="end">
<ion-button fill="clear">{{ translate("Save") }}</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>

<ion-content>
<ion-card>
<div class="card-header">
<div class="order-tags">
<ion-chip outline>
<ion-chip outline @click="copyToClipboard(order.orderName, 'Copied to clipboard')">
<ion-icon :icon="pricetag" />
<ion-label>NN10584</ion-label>
<ion-label>{{ order.orderName }}</ion-label>
</ion-chip>
</div>

<div class="order-primary-info">
<ion-label>
Darooty Magwood
<p>{{ translate("Ordered") }} 27th January 2020 9:24 PM EST</p>
{{ order.customerName }}
<p>{{ translate("Ordered") }} {{ formatUtcDate(order.orderDate, 'dd MMMM yyyy t a ZZZZ') }}</p>
</ion-label>
</div>

<div class="order-metadata">
<ion-label>
Next Day Shipping
<p>{{ translate("Ordered") }} 28th January 2020 2:32 PM EST</p>
{{ order.shipmentMethodTypeDesc }}
<p v-if="order.reservedDatetime">{{ translate("Last brokered") }} {{ formatUtcDate(order.reservedDatetime, 'dd MMMM yyyy t a ZZZZ') }}</p>
</ion-label>
</div>
</div>

<div class="order-item">
<div class="order-item" v-for="(item, index) in order.items" :key="index">
<div class="product-info">
<ion-item lines="none">
<ion-thumbnail slot="start">
<img src="https://dev-resources.hotwax.io/resources/uploads/images/product/m/j/mj08-blue_main.jpg" />
<DxpShopifyImg size="small" :src="getProduct(item.productId).mainImageUrl" />
</ion-thumbnail>
<ion-label>
<p class="overline">WJ06-XL-PURPLE</p>
Juno Jacket
<p>Blue XL</p>
<p class="overline">{{ getProductIdentificationValue(productIdentificationPref.secondaryId, getProduct(item.productId)) }}</p>
{{ getProductIdentificationValue(productIdentificationPref.primaryId, getProduct(item.productId)) ? getProductIdentificationValue(productIdentificationPref.primaryId, getProduct(item.productId)) : item.productName }}
<p>{{ getFeature(getProduct(item.productId).featureHierarchy, '1/COLOR/')}} {{ getFeature(getProduct(item.productId).featureHierarchy, '1/SIZE/')}}</p>
</ion-label>
</ion-item>
</div>

<div class="product-metadata">
<ion-item lines="none">
<ion-select :label="translate('Select box')">
<ion-select-option>Box A Type 3</ion-select-option>
<ion-select-option>Box B Type 2</ion-select-option>
<ion-select aria-label="Select box" interface="popover" :value="item.selectedBox" @ionChange="updateBox($event, item)">
<ion-select-option v-for="shipmentPackage in order.shipmentPackages" :key="shipmentPackage.shipmentId" :value="shipmentPackage.packageName"> {{ translate("Box") }} {{ shipmentPackage.packageName }}</ion-select-option>
</ion-select>
</ion-item>
</div>
Expand All @@ -66,29 +62,35 @@
<ion-list>
<ion-item lines="none">
<ion-note slot="start">{{ translate('Boxes') }}</ion-note>
<ion-button fill="clear" slot="end">
<ion-button fill="clear" slot="end" :disabled="addingBoxForOrderIds.includes(currentOrder.orderId)" @click="addBox(currentOrder)">
{{ translate("Add") }}
<ion-icon :icon="addCircleOutline"/>
</ion-button>
</ion-item>
<ion-item>
<ion-select label="Box A" value="3">
<ion-select-option value="1">Type 1</ion-select-option>
<ion-select-option value="2">Type 2</ion-select-option>
<ion-select-option value="3">Type 3</ion-select-option>
<ion-item v-for="shipmentPackage in order.shipmentPackages" :key="shipmentPackage.shipmentId">
<ion-select :label="translate('Box ') + shipmentPackage.packageName" interface="popover" :value="shipmentPackage.shipmentBoxTypeId" :placeholder="translate('Select')" :disabled="!shipmentPackage.shipmentBoxTypes.length" @ionChange="updateBoxType($event, shipmentPackage.shipmentId)">
<ion-select-option v-for="boxType in shipmentPackage.shipmentBoxTypes" :key="boxTypeDesc(boxType)" :value="boxType">{{ boxTypeDesc(boxType) }}</ion-select-option>
</ion-select>
</ion-item>
</ion-list>
</ion-content>

<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button @click="saveOrder()">
<ion-icon :icon="saveOutline" />
</ion-fab-button>
</ion-fab>
</template>

<script>
<script lang="ts">
import {
IonButtons,
IonButton,
IonCard,
IonChip,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
Expand All @@ -101,9 +103,11 @@ import {
IonTitle,
IonToolbar,
modalController } from "@ionic/vue";
import { defineComponent } from "vue";
import { addCircleOutline, closeOutline, pricetag } from "ionicons/icons";
import { translate } from '@hotwax/dxp-components'
import { computed, defineComponent } from "vue";
import { addCircleOutline, closeOutline, pricetag, saveOutline } from "ionicons/icons";
import { getProductIdentificationValue, translate, useProductIdentificationStore } from "@hotwax/dxp-components";
import { copyToClipboard, formatUtcDate, getFeature } from "@/utils";
import { mapGetters } from "vuex";

export default defineComponent({
name: "EditPackagingModal",
Expand All @@ -113,6 +117,8 @@ export default defineComponent({
IonCard,
IonChip,
IonContent,
IonFab,
IonFabButton,
IonHeader,
IonIcon,
IonItem,
Expand All @@ -125,18 +131,78 @@ export default defineComponent({
IonTitle,
IonToolbar,
},
props: ["addingBoxForOrderIds", "addShipmentBox", "order"],
computed: {
...mapGetters({
getProduct: 'product/getProduct',
boxTypeDesc: 'util/getShipmentBoxDesc'
}),
},
data() {
return {
currentOrder: {} as any
}
},
mounted() {
this.currentOrder = JSON.parse(JSON.stringify(this.order));
},
methods: {
closeModal() {
modalController.dismiss({ dismissed: true });
closeModal(payload = {}) {
modalController.dismiss({ dismissed: true, ...payload });
},
getShipmentPackageType(shipmentPackage: any) {
let packageType = '';
if(shipmentPackage.shipmentBoxTypes.length){
packageType = shipmentPackage.shipmentBoxTypes.find((boxType: string) => boxType === shipmentPackage.shipmentBoxTypeId) ? shipmentPackage.shipmentBoxTypes.find((boxType: string) => boxType === shipmentPackage.shipmentBoxTypeId) : shipmentPackage.shipmentBoxTypes[0];
}
return packageType;
},
updateBox(event: any, item: any) {
const updatedBox = event.detail.value;

const currentOrderItem = this.currentOrder.items.find((currentItem: any) => currentItem.orderItemSeqId === item.orderItemSeqId);
currentOrderItem.selectedBox = updatedBox

this.currentOrder.isModified = true;
},
updateBoxType(event: any, shipmentId: any) {
const updatedBoxType = event.detail.value;

const currentShipmentPackage = this.currentOrder.shipmentPackages.find((shipmentPackage: any) => shipmentPackage.shipmentId === shipmentId)
currentShipmentPackage.shipmentBoxTypeId = updatedBoxType;

this.currentOrder.isModified = true
},
addBox(currentOrder: any) {
this.addShipmentBox(currentOrder);
modalController.dismiss();
},
saveOrder() {
this.closeModal({ updatedOrder: this.currentOrder })
}
},
setup() {
const productIdentificationStore = useProductIdentificationStore();
let productIdentificationPref = computed(() => productIdentificationStore.getProductIdentificationPref)

return {
addCircleOutline,
closeOutline,
copyToClipboard,
formatUtcDate,
getFeature,
getProductIdentificationValue,
productIdentificationPref,
pricetag,
saveOutline,
translate
};
},
});
</script>
</script>

<style scoped>
ion-content {
--padding-bottom: 80px;
}
</style>
40 changes: 35 additions & 5 deletions src/views/InProgress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@
<ion-icon v-if="item.showKitComponents" color="medium" slot="icon-only" :icon="chevronUpOutline"/>
<ion-icon v-else color="medium" slot="icon-only" :icon="listOutline"/>
</ion-button>
<ion-button fill="clear" size="small" @click.stop="openRejectReasonPopover($event, item, order)">
<ion-button fill="clear" size="small" class="desktop-only" @click.stop="openRejectReasonPopover($event, item, order)">
<ion-icon color="danger" slot="icon-only" :icon="trashBinOutline"/>
</ion-button>
<ion-note v-if="getProductStock(item.productId).quantityOnHandTotal">{{ getProductStock(item.productId).quantityOnHandTotal }} {{ translate('pieces in stock') }}</ion-note>
Expand Down Expand Up @@ -176,7 +176,7 @@
<div class="mobile-only">
<ion-item>
<ion-button fill="clear" :disabled="order.isModified || order.hasMissingInfo" @click.stop="isForceScanEnabled ? scanOrder(order) : packOrder(order)">{{ translate("Pack using default packaging") }}</ion-button>
<ion-button slot="end" fill="clear" color="medium" @click.stop="packagingPopover">
<ion-button slot="end" fill="clear" color="medium" @click.stop="packagingPopover($event, order)">
<ion-icon slot="icon-only" :icon="ellipsisVerticalOutline" />
</ion-button>
</ion-item>
Expand Down Expand Up @@ -310,6 +310,8 @@ import ShipmentBoxPopover from '@/components/ShipmentBoxPopover.vue'
import QRCodeModal from '@/components/QRCodeModal.vue'
import { useAuthStore } from '@hotwax/dxp-components'
import ScanOrderItemModal from "@/components/ScanOrderItemModal.vue";
import EditPackagingModal from '@/views/EditPackagingModal.vue'
import ReportIssueModal from '@/views/ReportIssueModal.vue'


export default defineComponent({
Expand Down Expand Up @@ -441,13 +443,34 @@ export default defineComponent({
getInProgressOrders() {
return JSON.parse(JSON.stringify(this.inProgressOrders.list)).splice(0, (this.inProgressOrders.query.viewIndex + 1) * (process.env.VUE_APP_VIEW_SIZE as any));
},
async packagingPopover(ev: Event) {
async packagingPopover(ev: Event, order: any) {
const popover = await popoverController.create({
component: PackagingPopover,
componentProps: { order },
event: ev,
translucent: true,
showBackdrop: false,
});

popover.onDidDismiss().then(async(result) => {
if(result.data?.dismissed) {
const selectedAction = result.data.selectedAction;

const modal = await modalController.create({
component: selectedAction === 'editPackaging' ? EditPackagingModal : ReportIssueModal,
componentProps: selectedAction === 'editPackaging' ? { order, addingBoxForOrderIds: this.addingBoxForOrderIds, addShipmentBox: this.addShipmentBox } : { order }
})

modal.onDidDismiss().then((result) => {
if(result.data?.updatedOrder) {
this.save(result.data.updatedOrder);
}
})

modal.present();
}
})

return popover.present();
},
async packOrder(order: any) {
Expand Down Expand Up @@ -1290,8 +1313,15 @@ ion-segment > ion-segment-button > ion-skeleton-text, ion-item > ion-skeleton-te
height: 30px;
}

.order-item {
grid-template-columns: repeat(3, 1fr);
.product-metadata {
display: flex;
align-items: center;
}

@media (min-width: 991px) {
.order-item {
grid-template-columns: repeat(3, 1fr);
}
}
</style>

33 changes: 29 additions & 4 deletions src/views/OrderDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
<div v-if="category === 'in-progress'" class="mobile-only">
<ion-item>
<ion-button fill="clear" :disabled="order.hasMissingInfo" @click="isForceScanEnabled ? scanOrder(order) :packOrder(order)">{{ translate("Pack using default packaging") }}</ion-button>
<ion-button slot="end" fill="clear" color="medium" @click="packagingPopover">
<ion-button slot="end" fill="clear" color="medium" @click="packagingPopover($event, order)">
<ion-icon slot="icon-only" :icon="ellipsisVerticalOutline" />
</ion-button>
</ion-item>
Expand Down Expand Up @@ -347,6 +347,8 @@ import ReportIssuePopover from '@/components/ReportIssuePopover.vue'
import ShippingDetails from '@/views/ShippingDetails.vue';
import { isKit } from '@/utils/order'
import ScanOrderItemModal from "@/components/ScanOrderItemModal.vue";
import EditPackagingModal from '@/views/EditPackagingModal.vue';
import ReportIssueModal from '@/views/ReportIssueModal.vue';

export default defineComponent({
name: "OrderDetail",
Expand Down Expand Up @@ -699,13 +701,34 @@ export default defineComponent({
inProgressOrdersQuery.viewIndex = 0 // If the size changes, list index should be reintialised
await this.store.dispatch('order/updateInProgressQuery', { ...inProgressOrdersQuery })
},
async packagingPopover(ev: Event) {
async packagingPopover(ev: Event, order: any) {
const popover = await popoverController.create({
component: PackagingPopover,
componentProps: { order },
event: ev,
translucent: true,
showBackdrop: false,
});

popover.onDidDismiss().then(async(result) => {
if(result.data?.dismissed) {
const selectedAction = result.data.selectedAction;

const modal = await modalController.create({
component: selectedAction === 'editPackaging' ? EditPackagingModal : ReportIssueModal,
componentProps: selectedAction === 'editPackaging' ? { order, addingBoxForOrderIds: this.addingBoxForOrderIds, addShipmentBox: this.addShipmentBox } : { order }
})

modal.onDidDismiss().then((result) => {
if(result.data?.updatedOrder) {
this.save(result.data.updatedOrder);
}
})

modal.present();
}
})

return popover.present();
},
async openRejectReasonPopover(ev: Event, item: any, order: any, kitProducts?: any) {
Expand Down Expand Up @@ -1373,8 +1396,10 @@ ion-segment > ion-segment-button > ion-skeleton-text, ion-item > ion-skeleton-te
height: 30px;
}

.order-item {
grid-template-columns: repeat(3, 1fr);
@media (min-width: 991px) {
.order-item {
grid-template-columns: repeat(3, 1fr);
}
}

.other-shipment-actions {
Expand Down
Loading
Loading