Hi I do not believe they are meant to be used that way. You will end up wrting your own component to do that.
Auto refreshing Metrics card in Laravel Nova
Whats the best way to update a custom metrics card value metric that auto refreshes without requiring to reload the page?
Hi. In reply to @aurawindsurfing , I see that metrics are refreshed every time one changes the drop down for the time frame (30 min, 60 min, etc), so why not adding either a refresh button, or refreshing it at a rate?
I think they ARE meant for that. I am relative new to Laravel and Nova (been playing with it for over a year, and now working hard with it), and before diving deep into Vue and custom components, I wonder if there is an easy way to add this feature to metrics...
I've been looking for such feature so hard that I was close to jump into Livewire and abandon Nova dashboard because I can't make Nova dashboard to show me more "live" data.
Anyone can drop me a bone or a clue on how to do it? Thanks
2 months passed, thousand of views coming from people interested, and no ideas? Come on, guys. This has to be something not so hard to do. Are Nova developers thinking of adding such feature?
Nova's dev team don't look at threads here. You should send them a feature request.
thanks!
So, this is how you would quickly modify Nova 4 to support refreshing at intervals.
In nova/src/Metric/Metrics.php, inside the Metric class, add:
/**
* Indicates whether the metric should be refreshed every `n` seconds.
*
* @var int
*/
public $refreshAtInterval = 0;
/**
* Set whether the metric should refresh every `n` seconds.
*
* @param int $value
* @return $this
*/
public function refreshAtInterval(int $value = 0)
{
$this->refreshAtInterval = $value * 1000;
return $this;
}
and insert the line starting with refreshAtInterval line into jsonSerialize (same file):
public function jsonSerialize(): array
{
return array_merge(parent::jsonSerialize(), [
'class' => get_class($this),
'name' => $this->name(),
'uriKey' => $this->uriKey(),
'helpWidth' => $this->getHelpWidth(),
'helpText' => $this->getHelpText(),
'refreshWhenActionRuns' => $this->refreshWhenActionRuns,
'refreshWhenFiltersChange' => $this->refreshWhenFiltersChange,
'refreshAtInterval' => $this->refreshAtInterval, // <-- Add this line
]);
}
In nova/resources/js/mixins/MetricBehavior.js, add the lines commented with // add until it looks like so:
export default {
data: () => ({ // add
refreshInterval: null, // add
}), // add
created() {
Nova.$on('metric-refresh', this.fetch)
Nova.$on('resources-deleted', this.fetch)
Nova.$on('resources-restored', this.fetch)
if (this.card.refreshWhenActionRuns) {
Nova.$on('action-executed', this.fetch)
}
if (this.card.refreshAtInterval) { // add
this.refreshInterval = setInterval(this.fetch, this.card.refreshAtInterval) // add
} // add
},
beforeUnmount() {
if (this.refreshInterval) // add
clearInterval(this.refreshInterval) // add
Nova.$off('metric-refresh', this.fetch)
Nova.$off('resources-deleted', this.fetch)
Nova.$off('resources-restored', this.fetch)
Nova.$off('action-executed', this.fetch)
},
}
When instantiating a metric, you can apply the new method like so (example from app/Nova/Dashboards/Main.php:
public function cards()
{
return [
(new MyMetric())->refreshAtInterval(60), // refresh every 60 seconds
];
}
That should work on all nova metrics. As the files you are editing are fairly "base", they are unlikely to change in future Nova updates, but you will have to re-copy them back when you update.
Though I could write a package to separate this logic, there would have to be replacement classes for every kind of Nova metric, and I can't really be bothered :)
Please or to participate in this conversation.