diff --git a/package-lock.json b/package-lock.json index aea84914..b9d25da1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "@casl/ability": "^6.0.0", "@hotwax/app-version-info": "^1.0.0", "@hotwax/apps-theme": "^1.2.6", - "@hotwax/dxp-components": "^1.14.0", + "@hotwax/dxp-components": "^1.17.0", "@hotwax/oms-api": "^1.14.0", "@ionic/core": "^7.8.6", "@ionic/vue": "^7.8.6", @@ -2598,8 +2598,9 @@ "license": "Apache-2.0" }, "node_modules/@hotwax/dxp-components": { - "version": "1.14.1", - "license": "Apache-2.0", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/@hotwax/dxp-components/-/dxp-components-1.17.0.tgz", + "integrity": "sha512-ka/wmvxZuqSQ5V7zEI17fZ0deKq0NlBATJ3mqaicfF3J0VwQM4lomGIbBTZc3tPvmVnD8XLS/u1v3vMMVy+1Sw==", "dependencies": { "@hotwax/oms-api": "^1.8.1", "@ionic/core": "^7.6.0", @@ -2610,7 +2611,8 @@ "pinia-plugin-persistedstate": "^3.1.0", "register-service-worker": "^1.7.2", "vue": "^3.3.4", - "vue-i18n": "^9.2.2" + "vue-i18n": "^9.2.2", + "vue-markdown-render": "^2.2.1" } }, "node_modules/@hotwax/dxp-components/node_modules/@intlify/core-base": { @@ -10757,6 +10759,14 @@ "dev": true, "license": "MIT" }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/listr2": { "version": "3.14.0", "dev": true, @@ -11130,6 +11140,37 @@ "semver": "bin/semver.js" } }, + "node_modules/markdown-it": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/md5": { "version": "2.3.0", "license": "BSD-3-Clause", @@ -11144,6 +11185,11 @@ "dev": true, "license": "CC0-1.0" }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, "node_modules/media-typer": { "version": "0.3.0", "dev": true, @@ -14811,6 +14857,11 @@ "node": ">=4.2.0" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "dev": true, @@ -15629,6 +15680,17 @@ "version": "2.2.3", "license": "MIT" }, + "node_modules/vue-markdown-render": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vue-markdown-render/-/vue-markdown-render-2.2.1.tgz", + "integrity": "sha512-XkYnC0PMdbs6Vy6j/gZXSvCuOS0787Se5COwXlepRqiqPiunyCIeTPQAO2XnB4Yl04EOHXwLx5y6IuszMWSgyQ==", + "dependencies": { + "markdown-it": "^13.0.2" + }, + "peerDependencies": { + "vue": "^3.3.4" + } + }, "node_modules/vue-router": { "version": "4.2.5", "license": "MIT", diff --git a/package.json b/package.json index 5895bd1e..edc72395 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "@casl/ability": "^6.0.0", "@hotwax/app-version-info": "^1.0.0", "@hotwax/apps-theme": "^1.2.6", - "@hotwax/dxp-components": "^1.14.0", + "@hotwax/dxp-components": "^1.17.0", "@hotwax/oms-api": "^1.14.0", "@ionic/core": "^7.8.6", "@ionic/vue": "^7.8.6", diff --git a/src/store/modules/count/CountState.ts b/src/store/modules/count/CountState.ts index f344d943..af78ea28 100644 --- a/src/store/modules/count/CountState.ts +++ b/src/store/modules/count/CountState.ts @@ -19,4 +19,5 @@ export default interface CountState { defaultRecountUpdateBehaviour: String; cachedUnmatchProducts: any; closedCycleCountsTotal: any; + cycleCountItemsCount: number; } \ No newline at end of file diff --git a/src/store/modules/count/actions.ts b/src/store/modules/count/actions.ts index 96d9a8c1..0a6b2a87 100644 --- a/src/store/modules/count/actions.ts +++ b/src/store/modules/count/actions.ts @@ -259,6 +259,24 @@ const actions: ActionTree = { commit(types.COUNT_ITEMS_UPDATED, { itemList: payload }) }, + async fetchCycleCountItemsCount ({ commit }, inventoryCountImportId) { + let total = 0; + try { + const resp = await CountService.fetchCycleCountItemsCount({ + inventoryCountImportId: inventoryCountImportId, + }) + + if(!hasError(resp)) { + total = resp.data.count + } else { + throw resp + } + } catch(error: any) { + logger.error(error); + } + commit(types.COUNT_ITEMS_COUNT_TOTAL_UPDATED, total) + }, + async clearCycleCountItems ({ commit }) { commit(types.COUNT_ITEMS_UPDATED, []) }, diff --git a/src/store/modules/count/getters.ts b/src/store/modules/count/getters.ts index 7bce1144..7c782847 100644 --- a/src/store/modules/count/getters.ts +++ b/src/store/modules/count/getters.ts @@ -35,6 +35,9 @@ const getters: GetterTree = { }, getClosedCycleCountsTotal(state) { return state.closedCycleCountsTotal + }, + getCycleCountItemsCount(state) { + return state.cycleCountItemsCount } }; diff --git a/src/store/modules/count/index.ts b/src/store/modules/count/index.ts index 94ed03ca..65cbcbba 100644 --- a/src/store/modules/count/index.ts +++ b/src/store/modules/count/index.ts @@ -30,7 +30,8 @@ const countModule: Module = { cycleCountItems: {}, defaultRecountUpdateBehaviour: "add", cachedUnmatchProducts: {}, - closedCycleCountsTotal: "" + closedCycleCountsTotal: "", + cycleCountItemsCount: 0 }, getters, actions, diff --git a/src/store/modules/count/mutation-types.ts b/src/store/modules/count/mutation-types.ts index fd3b26a7..d577b3f6 100644 --- a/src/store/modules/count/mutation-types.ts +++ b/src/store/modules/count/mutation-types.ts @@ -7,4 +7,5 @@ export const COUNT_UPDATED = SN_COUNT + '/UPDATED' export const COUNT_ITEMS_UPDATED = SN_COUNT + '/ITEMS_UPDATED' export const COUNT_IMPORT_SYSTEM_MESSAGES_UPDATED = SN_COUNT + 'IMPORT_SYSTEM_MESSAGES_UPDATED' export const COUNT_CACHED_UNMATCH_PRODUCTS_UPDATED = SN_COUNT + 'CACHED_UNMATCHED_PRODUCTS_UPDATED' -export const COUNT_CLOSED_CYCLE_COUNTS_TOTAL_UPDATED = SN_COUNT + 'CLOSED_CYCLE_COUNTS_TOTAL_UPDATED' \ No newline at end of file +export const COUNT_CLOSED_CYCLE_COUNTS_TOTAL_UPDATED = SN_COUNT + 'CLOSED_CYCLE_COUNTS_TOTAL_UPDATED' +export const COUNT_ITEMS_COUNT_TOTAL_UPDATED = SN_COUNT + 'ITEMS_COUNT_TOTAL_UPDATED' \ No newline at end of file diff --git a/src/store/modules/count/mutations.ts b/src/store/modules/count/mutations.ts index 11b370f2..4d574651 100644 --- a/src/store/modules/count/mutations.ts +++ b/src/store/modules/count/mutations.ts @@ -44,6 +44,9 @@ const mutations: MutationTree = { }, [types.COUNT_CLOSED_CYCLE_COUNTS_TOTAL_UPDATED] (state, payload) { state.closedCycleCountsTotal = payload + }, + [types.COUNT_ITEMS_COUNT_TOTAL_UPDATED] (state, payload) { + state.cycleCountItemsCount = payload } } diff --git a/src/views/AssignedDetail.vue b/src/views/AssignedDetail.vue index f7eedead..5da30519 100644 --- a/src/views/AssignedDetail.vue +++ b/src/views/AssignedDetail.vue @@ -60,10 +60,11 @@ {{ translate("Progress") }} {{ getProgress() }} - + + @@ -129,6 +130,14 @@ + + + + + + + + @@ -141,7 +150,7 @@ import { computed, defineProps, nextTick, ref } from "vue"; import { translate } from '@/i18n' import { addOutline, calendarClearOutline, businessOutline, personCircleOutline, ellipsisVerticalOutline, lockClosedOutline } from "ionicons/icons"; -import { IonBackButton, IonButton, IonButtons, IonChip, IonContent, IonDatetime, IonModal, IonFab, IonFabButton, IonHeader, IonIcon, IonInput, IonItem, IonLabel, IonList, IonPage, IonThumbnail, IonTitle, IonToolbar, modalController, onIonViewWillEnter, popoverController, onIonViewWillLeave } from "@ionic/vue"; +import { IonBackButton, IonButton, IonButtons, IonChip, IonContent, IonDatetime, IonModal, IonFab, IonFabButton, IonFooter, IonHeader, IonIcon, IonInput, IonItem, IonLabel, IonList, IonPage, IonThumbnail, IonTitle, IonToolbar, modalController, onIonViewWillEnter, popoverController, onIonViewWillLeave } from "@ionic/vue"; import AssignedCountPopover from "@/components/AssignedCountPopover.vue" import store from "@/store" import logger from "@/logger" @@ -152,6 +161,7 @@ import AddProductModal from "@/components/AddProductModal.vue" import router from "@/router"; import Image from "@/components/Image.vue" import { DateTime } from "luxon"; +import { DxpPagination } from "@hotwax/dxp-components"; const props = defineProps({ inventoryCountImportId: String @@ -160,12 +170,15 @@ const props = defineProps({ const cycleCountStats = computed(() => (id: string) => store.getters["count/getCycleCountStats"](id)) const getProduct = computed(() => (id: string) => store.getters["product/getProduct"](id)) const productStoreSettings = computed(() => store.getters["user/getProductStoreSettings"]) +const totalCountItems = computed(() => store.getters["count/getCycleCountItemsCount"]) const dateTimeModalOpen = ref(false) const currentCycleCount = ref({}) as any const countNameRef = ref() let isCountNameUpdating = ref(false) let countName = ref("") +const pageSize = process.env.VUE_APP_VIEW_SIZE ? JSON.parse(process.env.VUE_APP_VIEW_SIZE) : 20; +let pageIndex = 0; async function addProductToCount(productId: any) { if(!productId) { @@ -187,8 +200,8 @@ async function addProductToCount(productId: any) { if(!hasError(resp)) { showToast(translate("Added product to count")) - // TODO: Fetching all the items again as in the current add api we do not get all the information required to be displayed on UI - await fetchCountItems(); + pageIndex = 0 + await Promise.allSettled([fetchCountItems(), store.dispatch("count/fetchCycleCountItemsCount", props.inventoryCountImportId), store.dispatch("count/fetchCycleCountStats", [props.inventoryCountImportId])]) } } catch(err) { logger.error("Failed to add product to count", err) @@ -213,7 +226,7 @@ onIonViewWillEnter(async () => { } countName.value = resp.data.countImportName - await fetchCountItems(); + await Promise.allSettled([fetchCountItems(), store.dispatch("count/fetchCycleCountItemsCount", props.inventoryCountImportId), store.dispatch("count/fetchCycleCountStats", [props.inventoryCountImportId])]) } } catch(err) { logger.error() @@ -226,20 +239,16 @@ onIonViewWillLeave(() => { emitter.off("addProductToCount", addProductToCount) }) -async function fetchCountItems() { - store.dispatch("count/fetchCycleCountStats", [props.inventoryCountImportId]) - let items = [] as any, resp, pageIndex = 0; +async function fetchCountItems(index?: any) { + let items = [] as any; try { - do { - resp = await CountService.fetchCycleCountItems({ inventoryCountImportId : props?.inventoryCountImportId, pageSize: 100, pageIndex }) - if(!hasError(resp) && resp.data?.itemList?.length) { - items = items.concat(resp.data.itemList) - pageIndex++; - } else { - throw resp.data; - } - } while(resp.data.itemList?.length >= 100) + const resp = await CountService.fetchCycleCountItems({ inventoryCountImportId : props?.inventoryCountImportId, pageSize, pageIndex: index ? index : 0 }) + if(!hasError(resp) && resp.data?.itemList?.length) { + items = resp.data.itemList + } else { + throw resp.data; + } } catch(err) { logger.error(err) } @@ -250,6 +259,11 @@ async function fetchCountItems() { store.dispatch("product/fetchProducts", { productIds: [...new Set(items.map((item: any) => item.productId))] }) } +function updatePageIndex(index: any) { + pageIndex = index; + fetchCountItems(index); +} + async function editCountName() { isCountNameUpdating.value = !isCountNameUpdating.value; // Waiting for DOM updations before focus inside the text-area, as it is conditionally rendered in the DOM diff --git a/src/views/ClosedDetail.vue b/src/views/ClosedDetail.vue index c7e2e60c..073375d7 100644 --- a/src/views/ClosedDetail.vue +++ b/src/views/ClosedDetail.vue @@ -89,12 +89,20 @@

{{ translate("Cycle count not found") }}

+ + + + + + + +