@fleetbase/storefront-engine 0.2.9 → 0.2.11

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.
@@ -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,80 @@
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
+ * The widget ID to use for registering.
9
+ *
10
+ * @memberof WidgetFleetOpsKeyMetricsComponent
11
+ */
12
+ static widgetId = 'storefront-key-metrics-widget';
13
+
14
+ /**
15
+ * Inject the fetch service.
16
+ *
17
+ * @memberof WidgetKeyMetricsComponent
18
+ */
19
+ @service fetch;
20
+
21
+ /**
22
+ * Property for loading metrics to.
23
+ *
24
+ * @memberof WidgetKeyMetricsComponent
25
+ */
26
+ @tracked metrics = {};
27
+
28
+ /**
29
+ * Creates an instance of WidgetKeyMetricsComponent.
30
+ * @memberof WidgetKeyMetricsComponent
31
+ */
32
+ constructor() {
33
+ super(...arguments);
34
+ this.getDashboardMetrics.perform();
35
+ }
36
+
37
+ /**
38
+ * Task which fetches key metrics.
39
+ *
40
+ * @memberof WidgetKeyMetricsComponent
41
+ */
42
+ @task *getDashboardMetrics() {
43
+ this.metrics = yield this.fetch.get('metrics', {}, { namespace: 'storefront/int/v1' }).then((response) => {
44
+ return this.createMetricsMapFromResponse(response);
45
+ });
46
+ }
47
+
48
+ /**
49
+ * Creates a map of metrics from the response data. This method organizes the metrics data into a more usable format.
50
+ *
51
+ * @param {Object} metrics - The metrics object fetched from the server.
52
+ * @returns {Object} A map of metrics where each key is a metric name and its value is an object of metric options.
53
+ * @memberof WidgetKeyMetricsComponent
54
+ */
55
+ createMetricsMapFromResponse(metrics = {}) {
56
+ const keys = Object.keys(metrics);
57
+ const map = {};
58
+
59
+ for (let i = 0; i < keys.length; i++) {
60
+ const key = keys[i];
61
+ map[key] = this.createMetricOptionsHash(key, metrics[key]);
62
+ }
63
+
64
+ return map;
65
+ }
66
+
67
+ /**
68
+ * Creates a hash of options for a given metric. Depending on the metric key, it assigns a specific format.
69
+ *
70
+ * @param {string} key - The key representing the specific metric.
71
+ * @param {number} value - The value of the metric.
72
+ * @returns {Object} An object containing the metric value and its format.
73
+ * @memberof WidgetKeyMetricsComponent
74
+ */
75
+ createMetricOptionsHash(key, value) {
76
+ const options = { value };
77
+
78
+ return options;
79
+ }
80
+ }
@@ -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()), 'P');
20
- @tracked end = format(endOfMonth(new Date()), 'P');
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
+ widgetId: 'storefront-key-metrics-widget',
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
 
@@ -33,5 +33,6 @@
33
33
  </div>
34
34
 
35
35
  <div>{{outlet}}</div>
36
+ <Spacer @height="300px" />
36
37
  </Overlay::Body>
37
38
  </Overlay>
@@ -296,5 +296,6 @@
296
296
  </ArrayInput>
297
297
  </div>
298
298
  </ContentPanel>
299
+ <Spacer @height="300px" />
299
300
  </Overlay::Body>
300
301
  </Overlay>
@@ -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.9",
3
+ "version": "0.2.11",
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": "^7.4|^8.0",
25
- "fleetbase/core-api": "^1.3.13",
26
- "fleetbase/fleetops-api": "^0.4.4",
24
+ "php": "^8.0",
25
+ "fleetbase/core-api": "^1.4.0",
26
+ "fleetbase/fleetops-api": "^0.4.6",
27
27
  "geocoder-php/google-maps-places-provider": "^1.4",
28
- "laravel-notification-channels/apn": "^3.8",
29
- "laravel-notification-channels/fcm": "^2.7",
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": "^9.0",
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": "^5.11.0|^6.4.0",
39
- "pestphp/pest": "^1.22.6",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "Storefront",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "description": "Headless Commerce & Marketplace Extension for Fleetbase",
5
5
  "repository": "https://github.com/fleetbase/storefront",
6
6
  "license": "MIT",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fleetbase/storefront-engine",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
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.0",
46
+ "@fleetbase/ember-core": "^0.2.4",
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 Grimzy\LaravelMysqlSpatial\Types\Point;
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->whenLoaded('products')),
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 Grimzy\LaravelMysqlSpatial\Eloquent\SpatialTrait;
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 \Grimzy\LaravelMysqlSpatial\Types\Point
124
+ * @return \Fleetbase\LaravelMysqlSpatial\Types\Point
125
125
  */
126
126
  public function getLocationAttribute()
127
127
  {
@@ -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('all', 'MetricsController@all');
166
+ $router->get('/', 'MetricsController@all');
171
167
  }
172
168
  );
173
169
  }
@@ -212,6 +212,8 @@ storefront:
212
212
  security-access-code: Security Access Code
213
213
  postal-code: Postal Code
214
214
  widget:
215
+ key-metrics:
216
+ title: Storefront Metrics
215
217
  customers:
216
218
  widget-title: Recent Customers
217
219
  phone: Phone