@fleetbase/storefront-engine 0.2.9 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addon/components/widget/storefront-key-metrics.hbs +19 -0
- package/addon/components/widget/storefront-key-metrics.js +73 -0
- package/addon/components/widget/storefront-metrics.js +2 -2
- package/addon/engine.js +18 -0
- package/addon/templates/networks/index/network.hbs +1 -0
- package/addon/templates/products/index/category/new.hbs +1 -0
- package/app/components/widget/storefront-key-metrics.js +1 -0
- package/composer.json +9 -9
- package/extension.json +1 -1
- package/package.json +2 -2
- package/server/src/Http/Controllers/ActionController.php +1 -21
- package/server/src/Http/Controllers/MetricsController.php +6 -46
- package/server/src/Http/Controllers/v1/NetworkController.php +1 -1
- package/server/src/Http/Resources/Category.php +2 -2
- package/server/src/Http/Resources/Store.php +3 -3
- package/server/src/Models/NetworkStore.php +2 -0
- package/server/src/Models/StoreLocation.php +2 -2
- package/server/src/routes.php +1 -5
- package/translations/en-us.yaml +2 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div class="storefront-key-metrics" ...attributes>
|
|
2
|
+
<div class="flex flex-col">
|
|
3
|
+
<div class="flex flex-row items-center justify-between px-4 py-2 border dark:border-gray-700 border-gray-200 dark:bg-gray-800 bg-gray-50 rounded-lg shadow-sm">
|
|
4
|
+
<span class="text-base font-bold text-black dark:text-gray-100">{{t "storefront.component.widget.key-metrics.title"}}</span>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<div class="mt-4">
|
|
8
|
+
{{#if this.getDashboardMetrics.isRunning}}
|
|
9
|
+
<Spinner />
|
|
10
|
+
{{else}}
|
|
11
|
+
<div class="grid grid-cols-2 lg:grid-cols-12 gap-4">
|
|
12
|
+
{{#each-in this.metrics as |title options|}}
|
|
13
|
+
<Dashboard::Count @title={{smart-humanize title}} @options={{options}} />
|
|
14
|
+
{{/each-in}}
|
|
15
|
+
</div>
|
|
16
|
+
{{/if}}
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import Component from '@glimmer/component';
|
|
2
|
+
import { tracked } from '@glimmer/tracking';
|
|
3
|
+
import { inject as service } from '@ember/service';
|
|
4
|
+
import { task } from 'ember-concurrency-decorators';
|
|
5
|
+
|
|
6
|
+
export default class WidgetStorefrontKeyMetricsComponent extends Component {
|
|
7
|
+
/**
|
|
8
|
+
* Inject the fetch service.
|
|
9
|
+
*
|
|
10
|
+
* @memberof WidgetKeyMetricsComponent
|
|
11
|
+
*/
|
|
12
|
+
@service fetch;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Property for loading metrics to.
|
|
16
|
+
*
|
|
17
|
+
* @memberof WidgetKeyMetricsComponent
|
|
18
|
+
*/
|
|
19
|
+
@tracked metrics = {};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates an instance of WidgetKeyMetricsComponent.
|
|
23
|
+
* @memberof WidgetKeyMetricsComponent
|
|
24
|
+
*/
|
|
25
|
+
constructor() {
|
|
26
|
+
super(...arguments);
|
|
27
|
+
this.getDashboardMetrics.perform();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Task which fetches key metrics.
|
|
32
|
+
*
|
|
33
|
+
* @memberof WidgetKeyMetricsComponent
|
|
34
|
+
*/
|
|
35
|
+
@task *getDashboardMetrics() {
|
|
36
|
+
this.metrics = yield this.fetch.get('metrics', {}, { namespace: 'storefront/int/v1' }).then((response) => {
|
|
37
|
+
return this.createMetricsMapFromResponse(response);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Creates a map of metrics from the response data. This method organizes the metrics data into a more usable format.
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} metrics - The metrics object fetched from the server.
|
|
45
|
+
* @returns {Object} A map of metrics where each key is a metric name and its value is an object of metric options.
|
|
46
|
+
* @memberof WidgetKeyMetricsComponent
|
|
47
|
+
*/
|
|
48
|
+
createMetricsMapFromResponse(metrics = {}) {
|
|
49
|
+
const keys = Object.keys(metrics);
|
|
50
|
+
const map = {};
|
|
51
|
+
|
|
52
|
+
for (let i = 0; i < keys.length; i++) {
|
|
53
|
+
const key = keys[i];
|
|
54
|
+
map[key] = this.createMetricOptionsHash(key, metrics[key]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return map;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Creates a hash of options for a given metric. Depending on the metric key, it assigns a specific format.
|
|
62
|
+
*
|
|
63
|
+
* @param {string} key - The key representing the specific metric.
|
|
64
|
+
* @param {number} value - The value of the metric.
|
|
65
|
+
* @returns {Object} An object containing the metric value and its format.
|
|
66
|
+
* @memberof WidgetKeyMetricsComponent
|
|
67
|
+
*/
|
|
68
|
+
createMetricOptionsHash(key, value) {
|
|
69
|
+
const options = { value };
|
|
70
|
+
|
|
71
|
+
return options;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -16,8 +16,8 @@ export default class WidgetStorefrontMetricsComponent extends Component {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
@tracked isLoading = true;
|
|
19
|
-
@tracked start = format(startOfMonth(new Date()), '
|
|
20
|
-
@tracked end = format(endOfMonth(new Date()), '
|
|
19
|
+
@tracked start = format(startOfMonth(new Date()), 'yyyy-MM-dd');
|
|
20
|
+
@tracked end = format(endOfMonth(new Date()), 'yyyy-MM-dd');
|
|
21
21
|
|
|
22
22
|
@computed('args.title') get title() {
|
|
23
23
|
return this.args.title || 'This Month';
|
package/addon/engine.js
CHANGED
|
@@ -3,6 +3,7 @@ import loadInitializers from 'ember-load-initializers';
|
|
|
3
3
|
import Resolver from 'ember-resolver';
|
|
4
4
|
import config from './config/environment';
|
|
5
5
|
import services from '@fleetbase/ember-core/exports/services';
|
|
6
|
+
import StorefrontKeyMetricsWidget from './components/widget/storefront-key-metrics';
|
|
6
7
|
|
|
7
8
|
const { modulePrefix } = config;
|
|
8
9
|
const externalRoutes = ['console', 'extensions'];
|
|
@@ -17,6 +18,23 @@ export default class StorefrontEngine extends Engine {
|
|
|
17
18
|
setupExtension = function (app, engine, universe) {
|
|
18
19
|
// register menu item in header
|
|
19
20
|
universe.registerHeaderMenuItem('Storefront', 'console.storefront', { icon: 'store', priority: 1 });
|
|
21
|
+
|
|
22
|
+
// widgets for registry
|
|
23
|
+
const KeyMetricsWidgetDefinition = {
|
|
24
|
+
did: 'storefront-metrics',
|
|
25
|
+
name: 'Storefront Metrics',
|
|
26
|
+
description: 'Key metrics from Storefront.',
|
|
27
|
+
icon: 'store',
|
|
28
|
+
component: StorefrontKeyMetricsWidget,
|
|
29
|
+
grid_options: { w: 12, h: 7, minW: 8, minH: 7 },
|
|
30
|
+
options: {
|
|
31
|
+
title: 'Storefront Metrics',
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// register widgets
|
|
36
|
+
universe.registerDefaultDashboardWidgets([KeyMetricsWidgetDefinition]);
|
|
37
|
+
universe.registerDashboardWidgets([KeyMetricsWidgetDefinition]);
|
|
20
38
|
};
|
|
21
39
|
}
|
|
22
40
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/components/widget/storefront-key-metrics';
|
package/composer.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fleetbase/storefront-api",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "Headless Commerce & Marketplace Extension for Fleetbase",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fleetbase-extension",
|
|
@@ -21,22 +21,22 @@
|
|
|
21
21
|
}
|
|
22
22
|
],
|
|
23
23
|
"require": {
|
|
24
|
-
"php": "^
|
|
25
|
-
"fleetbase/core-api": "^1.
|
|
26
|
-
"fleetbase/fleetops-api": "^0.4.
|
|
24
|
+
"php": "^8.0",
|
|
25
|
+
"fleetbase/core-api": "^1.4.0",
|
|
26
|
+
"fleetbase/fleetops-api": "^0.4.5",
|
|
27
27
|
"geocoder-php/google-maps-places-provider": "^1.4",
|
|
28
|
-
"laravel-notification-channels/apn": "^
|
|
29
|
-
"laravel-notification-channels/fcm": "^
|
|
28
|
+
"laravel-notification-channels/apn": "^5.0",
|
|
29
|
+
"laravel-notification-channels/fcm": "^4.1",
|
|
30
30
|
"laravel-notification-channels/twilio": "^3.3",
|
|
31
|
-
"milon/barcode": "^
|
|
31
|
+
"milon/barcode": "^10.0",
|
|
32
32
|
"php-http/guzzle7-adapter": "^1.0",
|
|
33
33
|
"psr/http-factory-implementation": "*",
|
|
34
34
|
"toin0u/geocoder-laravel": "^4.4"
|
|
35
35
|
},
|
|
36
36
|
"require-dev": {
|
|
37
37
|
"friendsofphp/php-cs-fixer": "^3.34.1",
|
|
38
|
-
"nunomaduro/collision": "^
|
|
39
|
-
"pestphp/pest": "^
|
|
38
|
+
"nunomaduro/collision": "^7.0",
|
|
39
|
+
"pestphp/pest": "^2.33.2",
|
|
40
40
|
"phpstan/phpstan": "^1.10.38",
|
|
41
41
|
"symfony/var-dumper": "^5.4.29"
|
|
42
42
|
},
|
package/extension.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fleetbase/storefront-engine",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "Headless Commerce & Marketplace Extension for Fleetbase",
|
|
5
5
|
"fleetbase": {
|
|
6
6
|
"route": "storefront",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@fleetbase/ember-core": "^0.2.
|
|
46
|
+
"@fleetbase/ember-core": "^0.2.3",
|
|
47
47
|
"@fleetbase/ember-ui": "^0.2.10",
|
|
48
48
|
"@fleetbase/fleetops-data": "^0.1.8",
|
|
49
49
|
"@babel/core": "^7.23.2",
|
|
@@ -11,11 +11,6 @@ use Illuminate\Support\Carbon;
|
|
|
11
11
|
|
|
12
12
|
class ActionController extends Controller
|
|
13
13
|
{
|
|
14
|
-
public function welcome()
|
|
15
|
-
{
|
|
16
|
-
return response()->json(['message' => 'Hello Friend!']);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
14
|
/**
|
|
20
15
|
* Get the number of storefronts created.
|
|
21
16
|
*
|
|
@@ -53,15 +48,10 @@ class ActionController extends Controller
|
|
|
53
48
|
}
|
|
54
49
|
|
|
55
50
|
$store = Store::where('uuid', $store)->first();
|
|
56
|
-
|
|
57
51
|
if (!$store) {
|
|
58
52
|
return response()->json($metrics);
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
/*
|
|
62
|
-
* Query metrics between given time period
|
|
63
|
-
*/
|
|
64
|
-
|
|
65
55
|
// send back currency
|
|
66
56
|
$metrics['currency'] = $store->currency;
|
|
67
57
|
|
|
@@ -102,16 +92,6 @@ class ActionController extends Controller
|
|
|
102
92
|
return $order->transaction->amount;
|
|
103
93
|
});
|
|
104
94
|
|
|
105
|
-
response()->json($metrics);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* CORS OPTIONS.
|
|
110
|
-
*
|
|
111
|
-
* @return \Illuminate\Http\Response
|
|
112
|
-
*/
|
|
113
|
-
public function options()
|
|
114
|
-
{
|
|
115
|
-
return response()->json(['status' => 'ok']);
|
|
95
|
+
return response()->json($metrics);
|
|
116
96
|
}
|
|
117
97
|
}
|
|
@@ -8,6 +8,12 @@ use Illuminate\Http\Request;
|
|
|
8
8
|
|
|
9
9
|
class MetricsController extends Controller
|
|
10
10
|
{
|
|
11
|
+
/**
|
|
12
|
+
* Get all key metrics for a companies storefront
|
|
13
|
+
*
|
|
14
|
+
* @param \Illuminate\Http\Request $request
|
|
15
|
+
* @return \Illuminate\Http\Response
|
|
16
|
+
*/
|
|
11
17
|
public function all(Request $request)
|
|
12
18
|
{
|
|
13
19
|
$start = $request->date('start');
|
|
@@ -22,50 +28,4 @@ class MetricsController extends Controller
|
|
|
22
28
|
|
|
23
29
|
return response()->json($data);
|
|
24
30
|
}
|
|
25
|
-
|
|
26
|
-
public function dashboard(Request $request)
|
|
27
|
-
{
|
|
28
|
-
$start = $request->date('start');
|
|
29
|
-
$end = $request->date('end');
|
|
30
|
-
$discover = $request->array('discover', []);
|
|
31
|
-
$metrics = [];
|
|
32
|
-
|
|
33
|
-
try {
|
|
34
|
-
$metrics = Metrics::forCompany($request->user()->company, $start, $end)->with($discover)->get();
|
|
35
|
-
} catch (\Exception $e) {
|
|
36
|
-
return response()->error($e->getMessage());
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// metrics format map
|
|
40
|
-
$metricsFormats = [];
|
|
41
|
-
|
|
42
|
-
// dashboard config
|
|
43
|
-
$dashboardConfig = [
|
|
44
|
-
[
|
|
45
|
-
'size' => 12,
|
|
46
|
-
'title' => 'Storefront Metrics',
|
|
47
|
-
'classList' => [],
|
|
48
|
-
'component' => null,
|
|
49
|
-
'queryParams' => [
|
|
50
|
-
'start' => ['component' => 'date-picker'],
|
|
51
|
-
'end' => ['component' => 'date-picker'],
|
|
52
|
-
],
|
|
53
|
-
'widgets' => collect($metrics)
|
|
54
|
-
->map(function ($value, $key) use ($metricsFormats) {
|
|
55
|
-
return [
|
|
56
|
-
'component' => 'count',
|
|
57
|
-
'options' => [
|
|
58
|
-
'format' => $metricsFormats[$key] ?? null,
|
|
59
|
-
'title' => str_replace('_', ' ', \Illuminate\Support\Str::title($key)),
|
|
60
|
-
'value' => $value,
|
|
61
|
-
],
|
|
62
|
-
];
|
|
63
|
-
})
|
|
64
|
-
->values()
|
|
65
|
-
->toArray(),
|
|
66
|
-
],
|
|
67
|
-
];
|
|
68
|
-
|
|
69
|
-
return response()->json(array_values($dashboardConfig));
|
|
70
|
-
}
|
|
71
31
|
}
|
|
@@ -9,7 +9,7 @@ use Fleetbase\Storefront\Http\Resources\Store as StorefrontStore;
|
|
|
9
9
|
use Fleetbase\Storefront\Http\Resources\StoreLocation as StorefrontStoreLocation;
|
|
10
10
|
use Fleetbase\Storefront\Models\Store;
|
|
11
11
|
use Fleetbase\Storefront\Models\StoreLocation;
|
|
12
|
-
use
|
|
12
|
+
use Fleetbase\LaravelMysqlSpatial\Types\Point;
|
|
13
13
|
use Illuminate\Http\Request;
|
|
14
14
|
|
|
15
15
|
class NetworkController extends Controller
|
|
@@ -30,9 +30,9 @@ class Category extends FleetbaseResource
|
|
|
30
30
|
),
|
|
31
31
|
'tags' => $this->tags ?? [],
|
|
32
32
|
'translations' => $this->translations ?? [],
|
|
33
|
-
'products' => Product::collection($this->
|
|
33
|
+
'products' => $this->when($request->has('with_products') || $request->inArray('with', 'products'), Product::collection($this->products)),
|
|
34
34
|
'subcategories' => $this->when(
|
|
35
|
-
$request->has('with_subcategories'),
|
|
35
|
+
$request->has('with_subcategories') || $request->inArray('with', 'subcategories'),
|
|
36
36
|
array_map(
|
|
37
37
|
function ($subCategory) {
|
|
38
38
|
return new Category($subCategory);
|
|
@@ -43,10 +43,10 @@ class Store extends FleetbaseResource
|
|
|
43
43
|
'online' => $this->online,
|
|
44
44
|
'is_network' => false,
|
|
45
45
|
'is_store' => true,
|
|
46
|
-
'category' => $this->when($request->filled('network') && $request->has('with_category'), new Category($this->getNetworkCategoryUsingId($request->input('network')))),
|
|
46
|
+
'category' => $this->when($request->filled('network') && ($request->has('with_category') || $request->inArray('with', 'category')), new Category($this->getNetworkCategoryUsingId($request->input('network')))),
|
|
47
47
|
'networks' => $this->when($request->boolean('with_networks') || $request->inArray('with', 'networks'), Network::collection($this->networks)),
|
|
48
|
-
'locations' => $this->when($request->boolean('with_locations'), $this->locations->mapInto(StoreLocation::class)),
|
|
49
|
-
'media' => $this->when($request->boolean('with_media'), Media::collection($this->media)),
|
|
48
|
+
'locations' => $this->when($request->boolean('with_locations') || $request->inArray('with', 'locations'), $this->locations->mapInto(StoreLocation::class)),
|
|
49
|
+
'media' => $this->when($request->boolean('with_media') || $request->inArray('with', 'media'), Media::collection($this->media)),
|
|
50
50
|
'slug' => $this->slug,
|
|
51
51
|
'created_at' => $this->created_at,
|
|
52
52
|
'updated_at' => $this->updated_at,
|
|
@@ -6,11 +6,13 @@ use Fleetbase\Models\Category;
|
|
|
6
6
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
7
7
|
use Fleetbase\Traits\HasUuid;
|
|
8
8
|
use Illuminate\Database\Eloquent\Relations\Pivot;
|
|
9
|
+
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
9
10
|
|
|
10
11
|
class NetworkStore extends Pivot
|
|
11
12
|
{
|
|
12
13
|
use HasUuid;
|
|
13
14
|
use HasApiModelBehavior;
|
|
15
|
+
use SoftDeletes;
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
18
|
* The database table used by the model.
|
|
@@ -7,7 +7,7 @@ use Fleetbase\Models\User;
|
|
|
7
7
|
use Fleetbase\Traits\HasApiModelBehavior;
|
|
8
8
|
use Fleetbase\Traits\HasPublicid;
|
|
9
9
|
use Fleetbase\Traits\HasUuid;
|
|
10
|
-
use
|
|
10
|
+
use Fleetbase\LaravelMysqlSpatial\Eloquent\SpatialTrait;
|
|
11
11
|
|
|
12
12
|
class StoreLocation extends StorefrontModel
|
|
13
13
|
{
|
|
@@ -121,7 +121,7 @@ class StoreLocation extends StorefrontModel
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
* @return \
|
|
124
|
+
* @return \Fleetbase\LaravelMysqlSpatial\Types\Point
|
|
125
125
|
*/
|
|
126
126
|
public function getLocationAttribute()
|
|
127
127
|
{
|
package/server/src/routes.php
CHANGED
|
@@ -112,7 +112,6 @@ Route::prefix(config('storefront.api.routing.prefix', 'storefront'))->namespace(
|
|
|
112
112
|
$router->group(
|
|
113
113
|
['prefix' => 'v1', 'middleware' => ['fleetbase.protected']],
|
|
114
114
|
function ($router) {
|
|
115
|
-
$router->get('/', 'ActionController@welcome');
|
|
116
115
|
$router->group(
|
|
117
116
|
['prefix' => 'actions'],
|
|
118
117
|
function ($router) {
|
|
@@ -161,13 +160,10 @@ Route::prefix(config('storefront.api.routing.prefix', 'storefront'))->namespace(
|
|
|
161
160
|
$router->group(
|
|
162
161
|
[],
|
|
163
162
|
function ($router) {
|
|
164
|
-
/* Dashboard Build */
|
|
165
|
-
$router->get('dashboard', 'MetricsController@dashboard');
|
|
166
|
-
|
|
167
163
|
$router->group(
|
|
168
164
|
['prefix' => 'metrics'],
|
|
169
165
|
function ($router) {
|
|
170
|
-
$router->get('
|
|
166
|
+
$router->get('/', 'MetricsController@all');
|
|
171
167
|
}
|
|
172
168
|
);
|
|
173
169
|
}
|
package/translations/en-us.yaml
CHANGED