-
Notifications
You must be signed in to change notification settings - Fork 73
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
🚀 enhance: Indexed DB integration to sync products over counters and improve frontend products search #126
base: develop
Are you sure you want to change the base?
Changes from 31 commits
0de5dec
4c5571a
8b3e12f
d9ebc1a
b49af7d
2740026
3a83eea
c59fc16
6958e22
ba8accf
6daf361
b675ef6
621fc13
8eaf467
7eb58db
b7c6b2e
e5a744c
4f9f226
47181e4
210059f
61333b1
182feef
ef6d01c
fcbfc82
52528f8
09f0bce
c2acc01
96fc7f8
070741b
19bb681
397a5c9
3e76019
8e9d7c6
e78a3cc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -34,7 +34,16 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</template> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</multiselect> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div class="refresh-products"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<v-popover popover-base-class="refresh-products-tooltip-wrapper tooltip popover" placement="auto" trigger="hover"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="refresh-icon list-view" :class="{ active: productLogsLoading }" @click.prevent="refreshProducts"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<svg xmlns="http://www.w3.org/2000/svg" data-name="Isolation Mode" viewBox="0 0 24 24" width="14" height="14"><path d="M12 2.99a9.03 9.03 0 0 1 6.36 2.65l-2.37 2.37h5.83a1.15 1.15 0 0 0 1.14-1.14V1.04l-2.49 2.49A11.98 11.98 0 0 0 0 12h2.99A9.02 9.02 0 0 1 12 2.99ZM21.01 12a9 9 0 0 1-15.37 6.36l2.37-2.37H2a.96.96 0 0 0-.95.95v6.02l2.49-2.49A11.98 11.98 0 0 0 24 12Z"/></svg> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<template slot="popover"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="refresh-products-tooltip-text">{{ __( 'Refresh Products', 'wepos' ) }}</span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</template> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</v-popover> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div class="toggle-view"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<div class="product-toggle"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<span class="toggle-icon list-view flaticon-menu-button-of-three-horizontal-lines" @click="productView = 'list'" :class="{ active: productView == 'list'}"></span> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -592,6 +601,7 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
filteredProducts: [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
totalPages: 1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
page: 1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
productLogsLoading: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
showOverlay: false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
selectedVariationProduct: {}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
attributeDisabled: true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -681,6 +691,9 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
productsStorageUpdatedOn() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return localStorage.getItem( 'productsStorageUpdatedOn' ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -922,9 +935,54 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}).then( ( response, status, xhr ) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.fetchProducts(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.productLoading = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else if ( this.isProductsStorageUpdateRequired() ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Remove existing products from the IndexedDB storage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
wepos.productIndexedDb.deleteAllProducts(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Insert products to the IndexedDB storage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
wepos.productIndexedDb.insertProducts( this.products ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Store products IndexedDB updating time to Local Storage. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
localStorage.setItem( 'productsStorageUpdatedOn', dayjs().unix() ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.productLoading = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
isProductsStorageUpdateRequired() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ( ! this.productsStorageUpdatedOn || this.productsStorageUpdatedOn < dayjs().subtract( 7, 'days' ).unix() ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+1060
to
+1062
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure correct comparison by parsing The value of Apply this diff to fix the comparison: isProductsStorageUpdateRequired() {
if ( ! this.productsStorageUpdatedOn ||
- this.productsStorageUpdatedOn < dayjs().subtract( 7, 'days' ).unix() ) {
+ parseInt(this.productsStorageUpdatedOn, 10) < dayjs().subtract( 7, 'days' ).unix() ) {
return true;
}
return false;
} Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
refreshProducts() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.fetchProductLogs( wepos.current_cashier.counter_id ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fetchProductLogs( counterId ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let fetchingToast = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
title: this.__( 'Products already updated!', 'wepos' ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
type: 'info' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.productLogsLoading = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
wepos.api.get( wepos.rest.root + wepos.rest.posversion + '/product/logs/' + counterId ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.done( ( response, status, xhr ) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ( response.length > 0 ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
wepos.productLogs.updateProductsToIndexedDb( response ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
wepos.productLogs.updateProductLogsData( counterId ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fetchingToast.title = this.__( 'Products refreshed successfully!', 'wepos' ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fetchingToast.type = 'success'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} ).fail( ( response, status, xhr ) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fetchingToast.title = this.__( 'Failed to refresh products!', 'wepos' ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fetchingToast.type = 'error'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} ).then( ( response, status, xhr ) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.productLogsLoading = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.toast( fetchingToast ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+1066
to
+1093
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Improve error handling in the Currently, the method does not handle potential API failures gracefully. Consider adding error handling to improve the robustness of the product log fetching process. + .fail( (error) => {
+ console.error('Failed to fetch product logs:', error);
+ this.productLogsLoading = false;
+ });
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
appendProducts( products ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
products.forEach( product => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1137,6 +1195,15 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async beforeCreate() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const dbName = 'ProductsDB'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const isExistsProductsDB = ( await window.indexedDB.databases() ).map( db => db.name ).includes( dbName ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ( ! isExistsProductsDB ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
wepos.productIndexedDb.createProductsDB(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+1306
to
+1312
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ensure browser compatibility when using The Apply this diff to handle browser compatibility: async beforeCreate() {
+ if ('databases' in indexedDB) {
const dbName = 'ProductsDB';
const isExistsProductsDB = ( await window.indexedDB.databases() ).map( db => db.name ).includes( dbName );
if ( ! isExistsProductsDB ) {
wepos.productIndexedDb.createProductsDB();
}
+ } else {
+ // Fallback for browsers without indexedDB.databases()
+ const request = indexedDB.open('ProductsDB');
+ request.onupgradeneeded = (event) => {
+ wepos.productIndexedDb.createProductsDB();
+ };
+ request.onsuccess = (event) => {
+ // Database exists
+ };
+ request.onerror = (event) => {
+ // Handle errors
+ };
+ }
} Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async created() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.fetchSettings(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this.fetchTaxes(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1171,6 +1238,15 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<style lang="less"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@keyframes rotation { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
transform: rotate(0deg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
to { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
transform: rotate(360deg); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
#wepos-main { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
padding: 20px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
display: flex; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1364,7 +1440,7 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.category { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width: 26%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
margin-right: 2%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
margin-right: 1%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float:left; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
position: relative; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -1401,8 +1477,50 @@ export default { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.refresh-products { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float: left; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
margin-right: -5px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width: 4.5%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.refresh-icon { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
box-sizing: border-box; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
padding: 9px 10px 7px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
background: #fff; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
display: inline-block; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
border: 1px solid #E9EDF0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
box-shadow: 0 3px 15px 0 rgba(0,0,0,.02); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
cursor: pointer; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&:hover { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
svg { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fill: #3B80F4; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&.active { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
svg { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fill: #3B80F4; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
animation: rotation 1s infinite linear; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&:before { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
margin-left: 0px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
font-size: 13px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
&.list-view { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
margin-right: -4px; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
border-right: none; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
svg { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fill: #bdc0c9; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.toggle-view { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width: 14%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
width: 10%; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
float: left; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
text-align: right; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimize the handling of IndexedDB operations.
Consider abstracting IndexedDB operations into a separate method to improve code readability and maintainability.
And then define
updateIndexedDBProducts
method in the methods section.Committable suggestion