Skip to content

Commit 519fe14

Browse files
authored
[KC-10] Performance Improvements (#63)
* [KC-10] Add new performance improvement controllers * [KC-10] Add api.routes * [KC-10] Change getNovaChartjsComparisonData to have search Query * [KC-10] Remove heavy data loading from resource->resolve function * [KC-10] Add Ajax loading to additionalDatasets and comparisonData * [KC-10] Add field.js * [KC-10] Add fallback option to searchFields
1 parent baf48f9 commit 519fe14

File tree

8 files changed

+148
-22
lines changed

8 files changed

+148
-22
lines changed

dist/js/field.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

resources/js/components/DetailField.vue

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</div>
77
<div class="w-3/4 py-4 flex-grow">
88
<div class="flex border-b border-40">
9-
<div class="w-1/4 py-4"><h4 class="font-normal text-80">Select another {{field.model}} to compare</h4></div>
9+
<div class="w-1/4 py-4"><h4 class="font-normal text-80">Select another {{field.chartableName}} to compare</h4></div>
1010
<div class="w-3/4 py-4">
1111
<multiselect
1212
v-model = "selected"
@@ -19,21 +19,23 @@
1919
:label="field.settings.titleProp"
2020
track-by="id"
2121
:options = "comparisonList"
22+
:loading="isLoading"
23+
@search-change="getComparisonData"
2224
/>
2325
</div>
2426
</div>
2527
<div class="flex border-b border-40">
26-
<div class="w-full py-4">
28+
<div class="w-full py-4" v-if="loaded">
2729
<chartjs-bar-chart v-if="isType('bar')"
2830
:dataset="comparisonDataset"
29-
:additionalDatasets="field.additionalDatasets"
31+
:additionalDatasets="additionalDatasets"
3032
:settings="field.settings"
3133
:height="field.settings.height"
3234
:width="field.settings.width"
3335
/>
3436
<chartjs-line-chart v-else
3537
:dataset="comparisonDataset"
36-
:additionalDatasets="field.additionalDatasets"
38+
:additionalDatasets="additionalDatasets"
3739
:settings="field.settings"
3840
:height="field.settings.height"
3941
:width="field.settings.width"
@@ -66,10 +68,21 @@ export default {
6668
6769
data() {
6870
return {
69-
selected: []
71+
isLoading: false,
72+
loaded: false,
73+
selected: [],
74+
comparisonList: [{
75+
groupLabel: 'Select/Deselect All',
76+
groupItems: []
77+
}],
78+
additionalDatasets: []
7079
}
7180
},
7281
82+
created() {
83+
this.getAdditionalDatasets()
84+
},
85+
7386
methods: {
7487
isType: function(type){
7588
return this.field.settings.type.toLowerCase() === type
@@ -95,7 +108,7 @@ export default {
95108
}
96109
},
97110
98-
getChartTypeCustomizations: function(type, color){
111+
getChartTypeCustomizations: function(type, color) {
99112
if(this.isType('line')){
100113
return {
101114
borderColor: color
@@ -105,8 +118,36 @@ export default {
105118
backgroundColor: color
106119
}
107120
}
108-
}
121+
},
122+
123+
getComparisonData: async function(searchValue){
124+
let response = await Nova.request()
125+
.post("/nova-chartjs/retrieve-model-comparison-data",
126+
{
127+
"field": this.field,
128+
"searchFields": this.field.searchFields,
129+
"searchValue": searchValue
130+
}
131+
)
132+
133+
this.comparisonList = [
134+
{
135+
groupLabel: 'Select/Deselect All',
136+
groupItems: response.data.comparison
137+
},
138+
]
139+
},
109140
141+
getAdditionalDatasets: async function() {
142+
this.isLoading = true
143+
144+
let response = await Nova.request()
145+
.post("/nova-chartjs/get-additional-datasets", this.field)
146+
147+
this.isLoading = false
148+
this.additionalDatasets = response.data.additionalDatasets;
149+
this.loaded = true;
150+
},
110151
},
111152
112153
computed: {
@@ -127,15 +168,6 @@ export default {
127168
];
128169
},
129170
130-
comparisonList: function(){
131-
return [
132-
{
133-
groupLabel: 'Select/Deselect All',
134-
groupItems: this.field.comparison.filter(this.isNotUser)
135-
},
136-
];
137-
},
138-
139171
valueDataset: function () {
140172
return {
141173
labels: Object.keys(this.field.value),

routes/api.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\Route;
4+
use KirschbaumDevelopment\NovaChartjs\Http\Controllers\GetAdditionalDatasetsController;
5+
use KirschbaumDevelopment\NovaChartjs\Http\Controllers\RetrieveModelComparisonDataController;
6+
7+
8+
Route::post('/retrieve-model-comparison-data', RetrieveModelComparisonDataController::class);
9+
Route::post('/get-additional-datasets', GetAdditionalDatasetsController::class);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace KirschbaumDevelopment\NovaChartjs\Http\Controllers;
4+
5+
use Illuminate\Routing\Controller;
6+
7+
class GetAdditionalDatasetsController extends Controller
8+
{
9+
public function __invoke()
10+
{
11+
$field = request()->all();
12+
$resource = resolve($field["model"])->find($field["ident"]);
13+
14+
return response()->json([
15+
'additionalDatasets' => data_get(
16+
$resource->getAdditionalDatasets(),
17+
$field["chartName"],
18+
[]
19+
),
20+
]);
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace KirschbaumDevelopment\NovaChartjs\Http\Controllers;
4+
5+
use Illuminate\Routing\Controller;
6+
7+
class RetrieveModelComparisonDataController extends Controller
8+
{
9+
public function __invoke()
10+
{
11+
$request = request()->all();
12+
$resource = resolve(data_get($request, "field.model"))->find(data_get($request,"field.ident"));
13+
14+
return response()->json([
15+
'comparison' => $resource::getNovaChartjsComparisonData(
16+
data_get($request, "field.chartName"),
17+
data_get($request, "searchFields"),
18+
data_get($request, "searchValue"),
19+
),
20+
]);
21+
}
22+
}

src/NovaChartjs.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public function __construct($name, $attribute = null, callable $resolveCallback
3232
'showLabel' => false,
3333
'notEditable' => false,
3434
'chartName' => 'default',
35+
'searchFields' => 'id',
3536
]);
3637
}
3738

@@ -66,9 +67,9 @@ public function resolve($resource, $attribute = null)
6667

6768
$this->withMeta([
6869
'settings' => $settings,
69-
'comparison' => $resource::getNovaChartjsComparisonData($this->getChartName()),
70-
'additionalDatasets' => data_get($resource->getAdditionalDatasets(), $this->getChartName(), []),
71-
'model' => Str::singular(Str::title(Str::snake(class_basename($resource), ' '))),
70+
'model' => get_class($resource),
71+
'searchFields' => data_get($this->meta(), 'searchFields', data_get($settings, 'titleProp', 'id')),
72+
'chartableName' => Str::singular(Str::title(Str::snake(class_basename($resource), ' '))),
7273
'title' => $this->getChartableProp($resource, $settings['titleProp'] ?? $resource->getKeyName()),
7374
'ident' => $this->getChartableProp($resource, $settings['identProp'] ?? $resource->getKeyName()),
7475
]);

src/NovaChartjsServiceProvider.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Laravel\Nova\Nova;
66
use Illuminate\Support\ServiceProvider;
7+
use Illuminate\Support\Facades\Route;
78
use KirschbaumDevelopment\NovaChartjs\Nova\MetricValue;
89

910
class NovaChartjsServiceProvider extends ServiceProvider
@@ -16,6 +17,9 @@ public function boot()
1617
$this->loadMigrations();
1718
$this->registerResources();
1819
$this->serveField();
20+
$this->app->booted(function () {
21+
$this->routes();
22+
});
1923
}
2024

2125
protected function loadMigrations()
@@ -37,4 +41,20 @@ protected function registerResources(): void
3741
MetricValue::class,
3842
]);
3943
}
44+
45+
/**
46+
* Register package routes.
47+
*
48+
* @return void
49+
*/
50+
protected function routes()
51+
{
52+
if ($this->app->routesAreCached()) {
53+
return;
54+
}
55+
56+
Route::middleware(['nova'])
57+
->prefix('nova-chartjs')
58+
->group(__DIR__.'/../routes/api.php');
59+
}
4060
}

src/Traits/HasChart.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Relations\MorphMany;
66
use KirschbaumDevelopment\NovaChartjs\Models\NovaChartjsMetricValue;
7-
7+
use Illuminate\Support\Arr;
88
trait HasChart
99
{
1010
/** @var array */
@@ -75,10 +75,13 @@ public function setNovaChartjsMetricValueAttribute($value): void
7575
*
7676
* @return array
7777
*/
78-
public static function getNovaChartjsComparisonData($chartName = 'default'): array
78+
public static function getNovaChartjsComparisonData($chartName = 'default', $searchFields = 'id', $searchValue = ''): array
7979
{
8080
$resources = static::query()
8181
->has('novaChartjsMetricValue')
82+
->when($searchFields && $searchValue, function ($query) use ($searchFields, $searchValue){
83+
return static::resolveSearchQuery($query, $searchFields, $searchValue);
84+
})
8285
->get();
8386

8487
$charts = NovaChartjsMetricValue::query()
@@ -105,6 +108,23 @@ public static function getNovaChartjsComparisonData($chartName = 'default'): arr
105108
->toArray();
106109
}
107110

111+
public static function resolveSearchQuery($query, $searchFields, $searchValue)
112+
{
113+
if (is_array($searchFields)) {
114+
$firstField = Arr::pull($searchFields, 0);
115+
$query->where($firstField, 'like', "%{$searchValue}%");
116+
117+
foreach ($searchFields as $field) {
118+
$query->orWhere(function ($query) use ($field, $searchValue) {
119+
return $query->where($field, 'like', "%{$searchValue}%");
120+
});
121+
}
122+
return $query;
123+
}
124+
125+
return $query->where($searchFields, 'like', "%{$searchValue}%");
126+
}
127+
108128
/**
109129
* Return a list of additional datasets added to chart.
110130
*

0 commit comments

Comments
 (0)