-
-
Notifications
You must be signed in to change notification settings - Fork 2k
[18.0][IMP] web_refresher: add auto refresh on interval #3256
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
base: 18.0
Are you sure you want to change the base?
Changes from all commits
90bc435
9eda219
4983e51
992ed85
aa684db
1a50329
c6c84f4
b4a4e75
6e41e8b
358c6a4
d3e4545
5e1be95
c5f8789
935ca4d
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 |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
* Copyright 2023 Taras Shabaranskyi | ||
* License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). */ | ||
|
||
import {Component} from "@odoo/owl"; | ||
import {Component, onMounted, onWillUnmount} from "@odoo/owl"; | ||
import {useDebounced} from "@web/core/utils/timing"; | ||
import {useService} from "@web/core/utils/hooks"; | ||
|
||
|
@@ -39,13 +39,59 @@ export function useRefreshAnimation(timeout) { | |
} | ||
|
||
export class Refresher extends Component { | ||
autoRefreshIntervalKey = "oca.web_refresher.auto_refresh"; | ||
refreshDefaultSettingsKey = "default"; | ||
setup() { | ||
super.setup(); | ||
this.action = useService("action"); | ||
this.refreshAnimation = useRefreshAnimation(1000); | ||
this.onClickRefresh = useDebounced(this.onClickRefresh, 200); | ||
this.onChangeAutoRefreshInterval = this.onChangeAutoRefreshInterval.bind(this); | ||
this.runningRefresherId = null; | ||
onMounted(() => { | ||
const intervalValue = this._getLocalStorageValue(window.location.pathname); | ||
this.onChangeAutoRefreshInterval({ | ||
value: intervalValue.refreshInterval, | ||
textContent: intervalValue.intervalText, | ||
}); | ||
}); | ||
onWillUnmount(() => { | ||
if (this.runningRefresherId) { | ||
clearTimeout(this.runningRefresherId); | ||
} | ||
}); | ||
} | ||
|
||
_getLocalStorageValue(lookupKey) { | ||
const jsonValue = localStorage.getItem(this.autoRefreshIntervalKey); | ||
const refreshSettings = jsonValue ? JSON.parse(jsonValue) : {}; | ||
if (!lookupKey) { | ||
return refreshSettings; | ||
} | ||
let returnInterval = -1; | ||
let returnText = "Off"; | ||
if (Object.hasOwn(refreshSettings, lookupKey)) { | ||
const {refreshInterval = -1, intervalText = "Off"} = | ||
refreshSettings[lookupKey]; | ||
returnInterval = parseInt(refreshInterval ?? -1); | ||
returnText = intervalText; | ||
} else if (Object.hasOwn(refreshSettings, this.refreshDefaultSettingsKey)) { | ||
const {refreshInterval = -1, intervalText = "Off"} = | ||
refreshSettings[this.refreshDefaultSettingsKey]; | ||
returnInterval = parseInt(refreshInterval ?? -1); | ||
returnText = intervalText; | ||
} | ||
return {refreshInterval: returnInterval, intervalText: returnText}; | ||
} | ||
|
||
_setLocalStorageValue(settingsKey, {refreshInterval, intervalText}) { | ||
// Get current settings | ||
const jsonValue = localStorage.getItem(this.autoRefreshIntervalKey); | ||
const refreshSettings = jsonValue ? JSON.parse(jsonValue) : {}; | ||
refreshSettings[settingsKey] = {refreshInterval, intervalText}; | ||
const value = JSON.stringify(refreshSettings); | ||
localStorage.setItem(this.autoRefreshIntervalKey, value); | ||
} | ||
/** | ||
* @returns {Boolean} | ||
* @private | ||
|
@@ -81,6 +127,16 @@ export class Refresher extends Component { | |
if (!updated) { | ||
updated = this._searchModelRefresh(); | ||
} | ||
// Check the refreshInterval is greater than 0 and start a timer for the next refresh | ||
if (this.refreshInterval > 0) { | ||
// Always attempt to clear a running timeout in case the refresh was done manually | ||
if (typeof this.runningRefresherId === "number") { | ||
clearTimeout(this.runningRefresherId); | ||
} | ||
this.runningRefresherId = setTimeout(() => { | ||
this.refresh(); | ||
}, this.refreshInterval); | ||
} | ||
Comment on lines
+130
to
+139
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. Consolidated logic for starting the refresh interval in the current refresh to allow recursive calls |
||
return updated; | ||
} | ||
|
||
|
@@ -101,6 +157,23 @@ export class Refresher extends Component { | |
this.action.doAction(viewAction, options); | ||
} | ||
|
||
_isRefreshIntervalDefault() { | ||
const localStoredIntervals = this._getLocalStorageValue(); | ||
|
||
if ( | ||
Object.hasOwn(localStoredIntervals, this.refreshDefaultSettingsKey) && | ||
Object.hasOwn( | ||
localStoredIntervals[this.refreshDefaultSettingsKey], | ||
"refreshInterval" | ||
) && | ||
this.refreshInterval === | ||
localStoredIntervals[this.refreshDefaultSettingsKey].refreshInterval | ||
) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
async onClickRefresh() { | ||
const {searchModel, pagerProps} = this.props; | ||
if (!searchModel && !pagerProps) { | ||
|
@@ -111,6 +184,63 @@ export class Refresher extends Component { | |
this.refreshAnimation(); | ||
} | ||
} | ||
|
||
setRefreshAsDefault() { | ||
this._setLocalStorageValue(this.refreshDefaultSettingsKey, { | ||
refreshInterval: this.refreshInterval, | ||
intervalText: document.getElementById("auto-refresh-interval-text") | ||
.textContent, | ||
}); | ||
this._setIntervalUi( | ||
document.getElementById("auto-refresh-interval-text").textContent | ||
); | ||
} | ||
|
||
onChangeAutoRefreshInterval(clickedOption) { | ||
const newInterval = | ||
parseInt(clickedOption.value ?? clickedOption.target.value) ?? -1; | ||
const newIntervalText = | ||
clickedOption.textContent ?? clickedOption.target.textContent ?? "Off"; | ||
this.refreshInterval = newInterval; | ||
this._setIntervalUi(newIntervalText); | ||
if (this.runningRefresherId) { | ||
clearTimeout(this.runningRefresherId); | ||
} | ||
this.refresh(); | ||
|
||
this._setLocalStorageValue(window.location.pathname, { | ||
refreshInterval: newInterval, | ||
intervalText: newIntervalText, | ||
}); | ||
} | ||
|
||
_setIntervalUi(intervalText) { | ||
// Check if the refresh is active and spin the refresh button if active | ||
const manualRefreshIcon = document.getElementById("manual-refresh-icon"); | ||
if (manualRefreshIcon) { | ||
if (!this.refreshInterval || this.refreshInterval <= 0) { | ||
manualRefreshIcon.classList.remove("fa-spin"); | ||
} else { | ||
manualRefreshIcon.classList.add("fa-spin"); | ||
} | ||
} | ||
// Set the interval dropdown text to the selected interval | ||
const refreshText = document.getElementById("auto-refresh-interval-text"); | ||
if (refreshText) { | ||
refreshText.textContent = intervalText; | ||
} | ||
// Check if the current interval is the default and set the star icon accordingly | ||
const setAsDefaultIcon = document.getElementById("set-as-default-icon"); | ||
if (setAsDefaultIcon) { | ||
if (this._isRefreshIntervalDefault()) { | ||
setAsDefaultIcon.classList.remove("fa-star-o"); | ||
setAsDefaultIcon.classList.add("fa-star"); | ||
} else { | ||
setAsDefaultIcon.classList.remove("fa-star"); | ||
setAsDefaultIcon.classList.add("fa-star-o"); | ||
} | ||
} | ||
} | ||
} | ||
|
||
Object.assign(Refresher, { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,13 +5,71 @@ | |
<template> | ||
<t t-name="web_refresher.Button"> | ||
<nav class="oe_refresher" aria-label="Refresher" aria-atomic="true"> | ||
<button | ||
class="fa fa-refresh btn btn-icon oe_pager_refresh" | ||
aria-label="Refresh" | ||
t-on-click="onClickRefresh" | ||
title="Refresh" | ||
tabindex="-1" | ||
/> | ||
<div class="btn-group" role="group"> | ||
<div class="btn-group" role="group"> | ||
<button | ||
id="auto-refresh-dd" | ||
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. added |
||
class="btn btn-secondary dropdown-toggle" | ||
type="button" | ||
data-bs-toggle="dropdown" | ||
aria-expanded="false" | ||
> | ||
Auto Refresh: <span id="auto-refresh-interval-text">Off</span> | ||
</button> | ||
<div class="dropdown-menu" aria-labelledby="auto-refresh-dd"> | ||
<button | ||
class="dropdown-item" | ||
t-on-click="onChangeAutoRefreshInterval" | ||
value="-1" | ||
>Off</button> | ||
Comment on lines
+20
to
+24
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. Used |
||
<button | ||
class="dropdown-item" | ||
t-on-click="onChangeAutoRefreshInterval" | ||
value="1000" | ||
>1s</button> | ||
Comment on lines
+25
to
+29
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. I'm not sure 1s is really appropriate. I could easily be persuaded to remove |
||
<button | ||
class="dropdown-item" | ||
t-on-click="onChangeAutoRefreshInterval" | ||
value="5000" | ||
>5s</button> | ||
<button | ||
class="dropdown-item" | ||
t-on-click="onChangeAutoRefreshInterval" | ||
value="10000" | ||
>10s</button> | ||
<button | ||
class="dropdown-item" | ||
t-on-click="onChangeAutoRefreshInterval" | ||
value="30000" | ||
>30s</button> | ||
<button | ||
class="dropdown-item" | ||
t-on-click="onChangeAutoRefreshInterval" | ||
value="60000" | ||
>1min</button> | ||
</div> | ||
</div> | ||
<button | ||
id="set-as-default-btn" | ||
class="btn btn-secondary m-0" | ||
aria-label="Set as Default" | ||
t-on-click="setRefreshAsDefault" | ||
title="Set as Default" | ||
tabindex="-1" | ||
> | ||
<i id="set-as-default-icon" class="fa" /> | ||
</button> | ||
<button | ||
id="manual-refresh-btn" | ||
class="btn btn-secondary m-0" | ||
aria-label="Refresh" | ||
t-on-click="onClickRefresh" | ||
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. Maintain existing flow with the a reset of the new timeout when manually clicked |
||
title="Refresh" | ||
tabindex="-1" | ||
> | ||
<i id="manual-refresh-icon" class="fa fa-refresh" /> | ||
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. Moved the icons to an 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. added |
||
</button> | ||
</div> | ||
</nav> | ||
</t> | ||
</template> |
Uh oh!
There was an error while loading. Please reload this page.