@fleetbase/storefront-engine 0.2.4 → 0.2.5
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/README.md +4 -4
- package/addon/components/modals/import-products.hbs +1 -1
- package/addon/components/schedule-manager.hbs +2 -2
- package/addon/components/widget/customers.hbs +1 -1
- package/addon/components/widget/customers.js +7 -4
- package/addon/components/widget/orders.js +4 -0
- package/addon/controllers/base-controller.js +31 -0
- package/addon/controllers/networks/index/network.js +2 -2
- package/addon/controllers/networks/index.js +3 -2
- package/addon/controllers/products/index/category/new.js +9 -2
- package/addon/controllers/products/index/category.js +2 -2
- package/addon/controllers/products/index/index.js +2 -2
- package/addon/controllers/products/index.js +2 -3
- package/addon/models/network.js +0 -1
- package/addon/routes/customers/index.js +11 -1
- package/addon/routes/networks/index.js +9 -0
- package/addon/routes/orders/index.js +11 -1
- package/addon/routes/products/index.js +8 -2
- package/addon/services/storefront.js +81 -0
- package/addon/templates/networks/index/network/stores.hbs +2 -2
- package/addon/templates/networks/index/network.hbs +1 -1
- package/addon/templates/products/index/category/new.hbs +1 -1
- package/addon/templates/products/index/category.hbs +20 -3
- package/app/controllers/base-controller.js +1 -0
- package/assets/sounds/storefront_order_alert.mp3 +0 -0
- package/composer.json +1 -1
- package/config/environment.js +11 -1
- package/index.js +15 -0
- package/package.json +132 -125
- package/server/src/Expansions/ContactFilterExpansion.php +36 -0
- package/server/src/Expansions/OrderFilterExpansion.php +31 -0
- package/server/src/Expansions/VendorFilterExpansion.php +36 -0
- package/server/src/Http/Resources/Cart.php +9 -1
- package/server/src/Http/Resources/Network.php +4 -0
- package/server/src/Http/Resources/Product.php +5 -0
- package/server/src/Http/Resources/Store.php +4 -0
- package/server/src/Http/Resources/StoreLocation.php +1 -2
- package/tsconfig.declarations.json +10 -0
package/README.md
CHANGED
|
@@ -15,10 +15,10 @@ This monorepo contains both the frontend and backend components of the Storefron
|
|
|
15
15
|
|
|
16
16
|
### Requirements
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
* PHP 7.3.0 or above
|
|
19
|
+
* Ember.js v4.8 or above
|
|
20
|
+
* Ember CLI v4.8 or above
|
|
21
|
+
* Node.js v18 or above
|
|
22
22
|
|
|
23
23
|
## Structure
|
|
24
24
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{{#if @options.isProcessing}}
|
|
4
4
|
<div class="min-h-56 dropzone w-full rounded px-4 py-8 min-h text-gray-900 dark:text-white text-center flex flex-col items-center justify-center border-2 border-dashed border-gray-200 dark:border-indigo-500">
|
|
5
5
|
<div class="flex items-center justify-center py-5">
|
|
6
|
-
<
|
|
6
|
+
<Spinner class="text-sm dark:text-gray-100" @loadingMessage="Processing import..." />
|
|
7
7
|
</div>
|
|
8
8
|
</div>
|
|
9
9
|
{{else}}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
{{#each-in this.schedule as |day hours|}}
|
|
3
3
|
<div class="content-panel {{@contentPanelClass}} shadow-sm">
|
|
4
4
|
<div class="content-panel-header items-center {{@contentPanelHeaderClass}}">
|
|
5
|
-
<h4 class="font-semibold dark:text-gray-100">{{day}}</h4>
|
|
5
|
+
<h4 class="font-semibold text-sm dark:text-gray-100">{{day}}</h4>
|
|
6
6
|
<div>
|
|
7
|
-
<Button @icon="calendar-week" @text="Add Hours" @onClick={{fn this.addHours @subject day}} class="{{@addHoursButtonClass}}" />
|
|
7
|
+
<Button @icon="calendar-week" @text="Add Hours" @textClass="truncate text-xs" @size="sm" @onClick={{fn this.addHours @subject day}} class="{{@addHoursButtonClass}}" />
|
|
8
8
|
</div>
|
|
9
9
|
</div>
|
|
10
10
|
<div class="content-panel-body {{@contentPanelBodyClass}}">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<ContentPanel @title={{this.title}} @titleStatusRight={{this.customers.length}} @
|
|
1
|
+
<ContentPanel @title={{this.title}} @titleStatusRight={{this.customers.length}} @titleStatusRightClass="info-status-badge" @hideStatusDot={{true}} @open={{this.customers.length}} @pad={{false}} @wrapperClass={{@wrapperClass}} @onInsert={{this.getCustomers}}>
|
|
2
2
|
{{#if this.isLoading}}
|
|
3
3
|
<div class="px-3 py-2">
|
|
4
4
|
<Spinner class="text-sky-400" />
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import Component from '@glimmer/component';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
|
-
import { action
|
|
4
|
+
import { action } from '@ember/object';
|
|
5
|
+
import setComponentArg from '@fleetbase/ember-core/utils/set-component-arg';
|
|
5
6
|
|
|
6
7
|
export default class WidgetCustomersComponent extends Component {
|
|
7
8
|
@service store;
|
|
8
9
|
@service storefront;
|
|
9
10
|
@tracked isLoading = true;
|
|
10
11
|
@tracked customers = [];
|
|
12
|
+
@tracked title = 'Recent Customers';
|
|
11
13
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
constructor(owner, { title }) {
|
|
15
|
+
super(...arguments);
|
|
16
|
+
setComponentArg(this, 'title', title);
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
@action async getCustomers() {
|
|
@@ -28,7 +31,7 @@ export default class WidgetCustomersComponent extends Component {
|
|
|
28
31
|
this.isLoading = true;
|
|
29
32
|
|
|
30
33
|
return new Promise((resolve) => {
|
|
31
|
-
const storefront = this.storefront
|
|
34
|
+
const storefront = this.storefront.getActiveStore('public_id');
|
|
32
35
|
|
|
33
36
|
if (!storefront) {
|
|
34
37
|
this.isLoading = false;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Controller from '@ember/controller';
|
|
2
|
+
import { inject as service } from '@ember/service';
|
|
3
|
+
import { action } from '@ember/object';
|
|
4
|
+
|
|
5
|
+
export default class BaseController extends Controller {
|
|
6
|
+
/**
|
|
7
|
+
* Inject the `universe` service
|
|
8
|
+
*
|
|
9
|
+
* @var {Service}
|
|
10
|
+
*/
|
|
11
|
+
@service universe;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Transitions to a specified route within the '@fleetbase/storefront-engine' engine.
|
|
15
|
+
*
|
|
16
|
+
* This action is a wrapper around the `transitionToEngineRoute` method of the `universe` service (or object),
|
|
17
|
+
* specifically targeting the '@fleetbase/storefront-engine'. It allows for easy transitioning to routes
|
|
18
|
+
* within this engine, abstracting away the need to repeatedly specify the engine name.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} route - The route within the '@fleetbase/storefront-engine' to transition to.
|
|
21
|
+
* @param {...any} args - Additional arguments to pass to the transitionToEngineRoute method.
|
|
22
|
+
* @returns {Promise} A Promise that resolves with the result of the transitionToEngineRoute method.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // To transition to the 'management.fleets.index.new' route within the '@fleetbase/storefront-engine'
|
|
26
|
+
* this.transitionToRoute('management.fleets.index.new');
|
|
27
|
+
*/
|
|
28
|
+
@action transitionToRoute(route, ...args) {
|
|
29
|
+
return this.universe.transitionToEngineRoute('@fleetbase/storefront-engine', route, ...args);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseController from '@fleetbase/storefront-engine/controllers/base-controller';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
3
|
import { action } from '@ember/object';
|
|
4
4
|
|
|
5
|
-
export default class NetworksIndexNetworkController extends
|
|
5
|
+
export default class NetworksIndexNetworkController extends BaseController {
|
|
6
6
|
@service modalsManager;
|
|
7
7
|
|
|
8
8
|
@action transitionBack({ closeOverlay }) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseController from '@fleetbase/storefront-engine/controllers/base-controller';
|
|
2
|
+
import { inject as controller } from '@ember/controller';
|
|
2
3
|
import { inject as service } from '@ember/service';
|
|
3
4
|
import { tracked } from '@glimmer/tracking';
|
|
4
5
|
import { action } from '@ember/object';
|
|
@@ -6,7 +7,7 @@ import { isBlank } from '@ember/utils';
|
|
|
6
7
|
import { timeout } from 'ember-concurrency';
|
|
7
8
|
import { task } from 'ember-concurrency-decorators';
|
|
8
9
|
|
|
9
|
-
export default class NetworksIndexController extends
|
|
10
|
+
export default class NetworksIndexController extends BaseController {
|
|
10
11
|
/**
|
|
11
12
|
* Inject the `NetworksIndexNetworkStoresController` controller
|
|
12
13
|
*
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseController from '@fleetbase/storefront-engine/controllers/base-controller';
|
|
2
|
+
import { inject as controller } from '@ember/controller';
|
|
2
3
|
import { tracked } from '@glimmer/tracking';
|
|
3
4
|
import { isArray } from '@ember/array';
|
|
4
5
|
import { action } from '@ember/object';
|
|
@@ -6,7 +7,7 @@ import { alias } from '@ember/object/computed';
|
|
|
6
7
|
import { underscore } from '@ember/string';
|
|
7
8
|
import { inject as service } from '@ember/service';
|
|
8
9
|
|
|
9
|
-
export default class ProductsIndexCategoryNewController extends
|
|
10
|
+
export default class ProductsIndexCategoryNewController extends BaseController {
|
|
10
11
|
@controller('products.index.category') productsIndexCategoryController;
|
|
11
12
|
@service notifications;
|
|
12
13
|
@service modalsManager;
|
|
@@ -89,6 +90,12 @@ export default class ProductsIndexCategoryNewController extends Controller {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
@action queueFile(file) {
|
|
93
|
+
// since we have dropzone and upload button within dropzone validate the file state first
|
|
94
|
+
// as this method can be called twice from both functions
|
|
95
|
+
if (['queued', 'failed', 'timed_out', 'aborted'].indexOf(file.state) === -1) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
92
99
|
this.uploadQueue.pushObject(file);
|
|
93
100
|
this.fetch.uploadFile.perform(
|
|
94
101
|
file,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseController from '@fleetbase/storefront-engine/controllers/base-controller';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { action } from '@ember/object';
|
|
@@ -7,7 +7,7 @@ import { isBlank } from '@ember/utils';
|
|
|
7
7
|
import { timeout } from 'ember-concurrency';
|
|
8
8
|
import { task } from 'ember-concurrency-decorators';
|
|
9
9
|
|
|
10
|
-
export default class ProductsIndexCategoryController extends
|
|
10
|
+
export default class ProductsIndexCategoryController extends BaseController {
|
|
11
11
|
@service modalsManager;
|
|
12
12
|
@service fetch;
|
|
13
13
|
@service hostRouter;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseController from '@fleetbase/storefront-engine/controllers/base-controller';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
3
|
import { tracked } from '@glimmer/tracking';
|
|
4
4
|
import { action } from '@ember/object';
|
|
@@ -6,7 +6,7 @@ import { isBlank } from '@ember/utils';
|
|
|
6
6
|
import { timeout } from 'ember-concurrency';
|
|
7
7
|
import { task } from 'ember-concurrency-decorators';
|
|
8
8
|
|
|
9
|
-
export default class ProductsIndexIndexController extends
|
|
9
|
+
export default class ProductsIndexIndexController extends BaseController {
|
|
10
10
|
/**
|
|
11
11
|
* Inject the `filters` service
|
|
12
12
|
*
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BaseController from '@fleetbase/storefront-engine/controllers/base-controller';
|
|
2
2
|
import { tracked } from '@glimmer/tracking';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
4
|
import { action } from '@ember/object';
|
|
5
5
|
import { alias } from '@ember/object/computed';
|
|
6
6
|
import { dasherize } from '@ember/string';
|
|
7
7
|
|
|
8
|
-
export default class ProductsIndexController extends
|
|
8
|
+
export default class ProductsIndexController extends BaseController {
|
|
9
9
|
@service store;
|
|
10
10
|
@service modalsManager;
|
|
11
11
|
@service currentUser;
|
|
12
|
-
@service modalsManager;
|
|
13
12
|
@service notifications;
|
|
14
13
|
@service fetch;
|
|
15
14
|
@service hostRouter;
|
package/addon/models/network.js
CHANGED
|
@@ -15,7 +15,6 @@ export default class NetworkModel extends Model {
|
|
|
15
15
|
@hasMany('store') stores;
|
|
16
16
|
@hasMany('notification-channel') notification_channels;
|
|
17
17
|
@hasMany('gateway') gateways;
|
|
18
|
-
@hasMany('store') stores;
|
|
19
18
|
@belongsTo('file') logo;
|
|
20
19
|
@belongsTo('file') backdrop;
|
|
21
20
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
|
+
import { action, set } from '@ember/object';
|
|
4
|
+
import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route-transition';
|
|
3
5
|
|
|
4
6
|
export default class CustomersIndexRoute extends Route {
|
|
5
7
|
@service store;
|
|
8
|
+
@service storefront;
|
|
6
9
|
|
|
7
10
|
queryParams = {
|
|
8
11
|
page: { refreshModel: true },
|
|
@@ -19,7 +22,14 @@ export default class CustomersIndexRoute extends Route {
|
|
|
19
22
|
updated_at: { refreshModel: true },
|
|
20
23
|
};
|
|
21
24
|
|
|
25
|
+
@action willTransition(transition) {
|
|
26
|
+
if (isNestedRouteTransition(transition)) {
|
|
27
|
+
set(this.queryParams, 'page.refreshModel', false);
|
|
28
|
+
set(this.queryParams, 'sort.refreshModel', false);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
model(params) {
|
|
23
|
-
return this.store.query('customer', params);
|
|
33
|
+
return this.store.query('customer', { ...params, storefront: this.storefront.getActiveStore('public_id') });
|
|
24
34
|
}
|
|
25
35
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
|
+
import { action, set } from '@ember/object';
|
|
4
|
+
import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route-transition';
|
|
3
5
|
|
|
4
6
|
export default class NetworksIndexRoute extends Route {
|
|
5
7
|
@service store;
|
|
@@ -13,6 +15,13 @@ export default class NetworksIndexRoute extends Route {
|
|
|
13
15
|
updated_at: { refreshModel: true },
|
|
14
16
|
};
|
|
15
17
|
|
|
18
|
+
@action willTransition(transition) {
|
|
19
|
+
if (isNestedRouteTransition(transition)) {
|
|
20
|
+
set(this.queryParams, 'page.refreshModel', false);
|
|
21
|
+
set(this.queryParams, 'sort.refreshModel', false);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
16
25
|
model(params) {
|
|
17
26
|
return this.store.query('network', params);
|
|
18
27
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
|
+
import { action, set } from '@ember/object';
|
|
4
|
+
import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route-transition';
|
|
3
5
|
|
|
4
6
|
export default class OrdersIndexRoute extends Route {
|
|
5
7
|
@service store;
|
|
8
|
+
@service storefront;
|
|
6
9
|
|
|
7
10
|
queryParams = {
|
|
8
11
|
page: { refreshModel: true },
|
|
@@ -23,7 +26,14 @@ export default class OrdersIndexRoute extends Route {
|
|
|
23
26
|
before: { refreshModel: true },
|
|
24
27
|
};
|
|
25
28
|
|
|
29
|
+
@action willTransition(transition) {
|
|
30
|
+
if (isNestedRouteTransition(transition)) {
|
|
31
|
+
set(this.queryParams, 'page.refreshModel', false);
|
|
32
|
+
set(this.queryParams, 'sort.refreshModel', false);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
26
36
|
model(params) {
|
|
27
|
-
return this.store.query('order', params);
|
|
37
|
+
return this.store.query('order', { ...params, storefront: this.storefront.getActiveStore('public_id') });
|
|
28
38
|
}
|
|
29
39
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import Route from '@ember/routing/route';
|
|
2
2
|
import { inject as service } from '@ember/service';
|
|
3
|
-
import { action } from '@ember/object';
|
|
3
|
+
import { action, set } from '@ember/object';
|
|
4
|
+
import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route-transition';
|
|
4
5
|
|
|
5
6
|
export default class ProductsIndexRoute extends Route {
|
|
6
7
|
@service store;
|
|
7
8
|
@service currentUser;
|
|
8
9
|
|
|
9
|
-
@action willTransition() {
|
|
10
|
+
@action willTransition(transition) {
|
|
10
11
|
this.controller.category = null;
|
|
12
|
+
|
|
13
|
+
if (isNestedRouteTransition(transition)) {
|
|
14
|
+
set(this.queryParams, 'page.refreshModel', false);
|
|
15
|
+
set(this.queryParams, 'sort.refreshModel', false);
|
|
16
|
+
}
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
model(params = {}) {
|
|
@@ -1,24 +1,86 @@
|
|
|
1
1
|
import Service from '@ember/service';
|
|
2
2
|
import Evented from '@ember/object/evented';
|
|
3
3
|
import { inject as service } from '@ember/service';
|
|
4
|
+
import { get } from '@ember/object';
|
|
4
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Service to manage storefront operations.
|
|
8
|
+
*/
|
|
5
9
|
export default class StorefrontService extends Service.extend(Evented) {
|
|
10
|
+
/**
|
|
11
|
+
* Ember service for data store.
|
|
12
|
+
* @type {Service}
|
|
13
|
+
*/
|
|
6
14
|
@service store;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Ember service for fetch operations.
|
|
18
|
+
* @type {Service}
|
|
19
|
+
*/
|
|
7
20
|
@service fetch;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Ember service for notifications.
|
|
24
|
+
* @type {Service}
|
|
25
|
+
*/
|
|
8
26
|
@service notifications;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Ember service for current user information.
|
|
30
|
+
* @type {Service}
|
|
31
|
+
*/
|
|
9
32
|
@service currentUser;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Ember service for managing modals.
|
|
36
|
+
* @type {Service}
|
|
37
|
+
*/
|
|
10
38
|
@service modalsManager;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Ember service for router operations.
|
|
42
|
+
* @type {Service}
|
|
43
|
+
*/
|
|
11
44
|
@service hostRouter;
|
|
12
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Gets the active store.
|
|
48
|
+
* @returns {Object} The active store object.
|
|
49
|
+
*/
|
|
13
50
|
get activeStore() {
|
|
14
51
|
return this.findActiveStore();
|
|
15
52
|
}
|
|
16
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Sets the active storefront.
|
|
56
|
+
* @param {Object} store - The store to set as active.
|
|
57
|
+
*/
|
|
17
58
|
setActiveStorefront(store) {
|
|
18
59
|
this.currentUser.setOption('activeStorefront', store.id);
|
|
19
60
|
this.trigger('storefront.changed', store);
|
|
20
61
|
}
|
|
21
62
|
|
|
63
|
+
/**
|
|
64
|
+
* Gets the active store or a specific property of it.
|
|
65
|
+
* @param {string|null} property - The property to retrieve from the active store.
|
|
66
|
+
* @returns {Object|null} The active store or its specific property.
|
|
67
|
+
*/
|
|
68
|
+
getActiveStore(property = null) {
|
|
69
|
+
if (this.activeStore) {
|
|
70
|
+
if (typeof property === 'string') {
|
|
71
|
+
return get(this.activeStore, property);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return this.activeStore;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Finds the active store based on the current user's settings.
|
|
82
|
+
* @returns {Object|null} The active store object or null if not found.
|
|
83
|
+
*/
|
|
22
84
|
findActiveStore() {
|
|
23
85
|
const activeStoreId = this.currentUser.getOption('activeStorefront');
|
|
24
86
|
|
|
@@ -43,6 +105,11 @@ export default class StorefrontService extends Service.extend(Evented) {
|
|
|
43
105
|
return activeStore;
|
|
44
106
|
}
|
|
45
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Alerts about an incoming order.
|
|
110
|
+
* @param {string} orderId - The ID of the incoming order.
|
|
111
|
+
* @param {Object} store - The store associated with the order.
|
|
112
|
+
*/
|
|
46
113
|
async alertIncomingOrder(orderId, store) {
|
|
47
114
|
const order = await this.store.queryRecord('order', {
|
|
48
115
|
public_id: orderId,
|
|
@@ -80,6 +147,9 @@ export default class StorefrontService extends Service.extend(Evented) {
|
|
|
80
147
|
});
|
|
81
148
|
}
|
|
82
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Listens for incoming orders and handles them.
|
|
152
|
+
*/
|
|
83
153
|
async listenForIncomingOrders() {
|
|
84
154
|
const store = this.findActiveStore();
|
|
85
155
|
|
|
@@ -109,6 +179,10 @@ export default class StorefrontService extends Service.extend(Evented) {
|
|
|
109
179
|
this.hostRouter.on('routeWillChange', channel.close);
|
|
110
180
|
}
|
|
111
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Creates the first store with given options.
|
|
184
|
+
* @param {Object} [options={}] - Options for creating the first store.
|
|
185
|
+
*/
|
|
112
186
|
createFirstStore(options = {}) {
|
|
113
187
|
const store = this.store.createRecord('store');
|
|
114
188
|
const currency = this.currentUser.getWhoisProperty('currency.code');
|
|
@@ -151,6 +225,10 @@ export default class StorefrontService extends Service.extend(Evented) {
|
|
|
151
225
|
});
|
|
152
226
|
}
|
|
153
227
|
|
|
228
|
+
/**
|
|
229
|
+
* Creates a new storefront with given options.
|
|
230
|
+
* @param {Object} [options={}] - Options for creating the new storefront.
|
|
231
|
+
*/
|
|
154
232
|
createNewStorefront(options = {}) {
|
|
155
233
|
const store = this.store.createRecord('store');
|
|
156
234
|
const currency = this.currentUser.getWhoisProperty('currency.code');
|
|
@@ -191,6 +269,9 @@ export default class StorefrontService extends Service.extend(Evented) {
|
|
|
191
269
|
});
|
|
192
270
|
}
|
|
193
271
|
|
|
272
|
+
/**
|
|
273
|
+
* Plays an alert sound.
|
|
274
|
+
*/
|
|
194
275
|
playAlert() {
|
|
195
276
|
// eslint-disable-next-line no-undef
|
|
196
277
|
const alert = new Audio('/sounds/storefront_order_alert.mp3');
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<Layout::Section::Header @title="Stores" @searchQuery={{this.storeQuery}} @onSearch={{perform this.search}}>
|
|
2
|
-
<Button @type="primary" @icon="plus" @text="Add Stores" @onClick={{this.addStores}} @wrapperClass="mr-2" />
|
|
3
|
-
<Button @type="primary" @icon="envelope-open-text" @text="Invite Stores" @onClick={{this.invite}} />
|
|
2
|
+
<Button @type="primary" @icon="plus" @text="Add Stores" @textClass="truncate" @size="sm" @onClick={{this.addStores}} @wrapperClass="mr-2" />
|
|
3
|
+
<Button @type="primary" @icon="envelope-open-text" @textClass="truncate" @size="sm" @text="Invite Stores" @onClick={{this.invite}} />
|
|
4
4
|
</Layout::Section::Header>
|
|
5
5
|
|
|
6
6
|
<Layout::Section::Body>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<Overlay @position="right" @isResizable={{true}} @noBackdrop={{true}} @width="
|
|
1
|
+
<Overlay @position="right" @isResizable={{true}} @noBackdrop={{true}} @width="570px" @minResizeWidth={{570}} @fullHeight={{true}}>
|
|
2
2
|
<Overlay::Header @title="Manage Network" @onPressCancel={{this.transitionBack}} />
|
|
3
3
|
<Overlay::Body class="p-0i" @increaseInnerBodyHeightBy="0" @wrapperClass="space-y-4 pt-4">
|
|
4
4
|
<div class="flex flex-col">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<Overlay @position="right" @noBackdrop={{true}} @width="
|
|
1
|
+
<Overlay @position="right" @noBackdrop={{true}} @isResizable={{true}} @width="570px" @fullHeight={{true}} @containerClass="border-l border-transparent dark:border-gray-700">
|
|
2
2
|
<Overlay::Header @title={{this.overlayTitle}} @titleClass="truncate" @titleWrapperClass="w-3/4" @headerLeftClass="w-70pc" @headerLeftInnerClass="w-full flex-1" @onPressCancel={{this.transitionBack}}>
|
|
3
3
|
<Button @icon={{this.overlayActionButtonIcon}} @type="primary" @text={{this.overlayActionButtonTitle}} @onClick={{this.saveProduct}} @isLoading={{this.isSaving}} @isSubscriptionRequired={{true}} />
|
|
4
4
|
</Overlay::Header>
|
|
@@ -1,6 +1,23 @@
|
|
|
1
|
-
<Layout::Section::Header @title={{concat this.category.name " Products"}} @searchQuery={{this.query}} @onSearch={{perform this.search}}>
|
|
2
|
-
<Button @type="default" @text="Edit this category" @icon="edit" @onClick={{fn this.editCategory this.category}} @disabled={{not this.category}} @wrapperClass="mr-2" />
|
|
3
|
-
<Button @type="danger" @text="Delete this category" @icon="trash" @onClick={{this.deleteCategory}} @disabled={{not this.category}} />
|
|
1
|
+
<Layout::Section::Header @title={{concat this.category.name " Products"}} @titleClass="truncate" @searchQuery={{this.query}} @onSearch={{perform this.search}}>
|
|
2
|
+
{{!-- <Button @type="default" @text="Edit this category" @textClass="truncate" @icon="edit" @onClick={{fn this.editCategory this.category}} @disabled={{not this.category}} @wrapperClass="mr-2" />
|
|
3
|
+
<Button @type="danger" @text="Delete this category" @textClass="truncate" @icon="trash" @onClick={{this.deleteCategory}} @disabled={{not this.category}} /> --}}
|
|
4
|
+
|
|
5
|
+
{{#if this.category}}
|
|
6
|
+
<DropdownButton @icon="gear" @text="Category" @type="default" @size="sm" @contentClass="dropdown-menu" as |dd|>
|
|
7
|
+
<div class="next-dd-menu">
|
|
8
|
+
<div class="px-1">
|
|
9
|
+
<a href="#" class="next-dd-item" {{on "click" (dropdown-fn dd this.editCategory this.category)}}>
|
|
10
|
+
Edit this category...
|
|
11
|
+
</a>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="px-1">
|
|
14
|
+
<a href="#" class="text-red-500 next-dd-item" {{on "click" (dropdown-fn dd this.deleteCategory)}}>
|
|
15
|
+
Delete this category...
|
|
16
|
+
</a>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</DropdownButton>
|
|
20
|
+
{{/if}}
|
|
4
21
|
</Layout::Section::Header>
|
|
5
22
|
|
|
6
23
|
<div class="h-screen overflow-y-scroll p-6">
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from '@fleetbase/storefront-engine/controllers/base-controller';
|
|
Binary file
|
package/composer.json
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"require": {
|
|
24
24
|
"php": "^7.4|^8.0",
|
|
25
25
|
"fleetbase/core-api": "^1.3.2",
|
|
26
|
-
"fleetbase/fleetops-api": "^0.3.
|
|
26
|
+
"fleetbase/fleetops-api": "^0.3.5",
|
|
27
27
|
"geocoder-php/google-maps-places-provider": "^1.4",
|
|
28
28
|
"laravel-notification-channels/apn": "^3.8",
|
|
29
29
|
"laravel-notification-channels/fcm": "^2.7",
|
package/config/environment.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/* eslint-env node */
|
|
2
2
|
'use strict';
|
|
3
|
-
const { name } = require('../package');
|
|
3
|
+
const { name, fleetbase } = require('../package');
|
|
4
4
|
|
|
5
5
|
module.exports = function (environment) {
|
|
6
6
|
let ENV = {
|
|
7
7
|
modulePrefix: name,
|
|
8
8
|
environment,
|
|
9
|
+
mountedEngineRoutePrefix: getMountedEngineRoutePrefix(),
|
|
9
10
|
|
|
10
11
|
defaultValues: {
|
|
11
12
|
categoryImage: getenv('DEFAULT_CATEGORY_IMAGE', 'https://flb-assets.s3.ap-southeast-1.amazonaws.com/images/fallback-placeholder-1.png'),
|
|
@@ -16,6 +17,15 @@ module.exports = function (environment) {
|
|
|
16
17
|
return ENV;
|
|
17
18
|
};
|
|
18
19
|
|
|
20
|
+
function getMountedEngineRoutePrefix() {
|
|
21
|
+
let mountedEngineRoutePrefix = 'storefront';
|
|
22
|
+
if (fleetbase && typeof fleetbase.route === 'string') {
|
|
23
|
+
mountedEngineRoutePrefix = fleetbase.route;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return `console.${mountedEngineRoutePrefix}.`;
|
|
27
|
+
}
|
|
28
|
+
|
|
19
29
|
function getenv(variable, defaultValue = null) {
|
|
20
30
|
return process.env[variable] !== undefined ? process.env[variable] : defaultValue;
|
|
21
31
|
}
|
package/index.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
const { buildEngine } = require('ember-engines/lib/engine-addon');
|
|
3
3
|
const { name } = require('./package');
|
|
4
4
|
const Funnel = require('broccoli-funnel');
|
|
5
|
+
const MergeTrees = require('broccoli-merge-trees');
|
|
6
|
+
const path = require('path');
|
|
5
7
|
|
|
6
8
|
module.exports = buildEngine({
|
|
7
9
|
name,
|
|
@@ -23,4 +25,17 @@ module.exports = buildEngine({
|
|
|
23
25
|
isDevelopingAddon() {
|
|
24
26
|
return true;
|
|
25
27
|
},
|
|
28
|
+
|
|
29
|
+
treeForPublic: function () {
|
|
30
|
+
const publicTree = this._super.treeForPublic.apply(this, arguments);
|
|
31
|
+
|
|
32
|
+
const addonTree = [
|
|
33
|
+
new Funnel(path.join(__dirname, 'assets'), {
|
|
34
|
+
destDir: '/',
|
|
35
|
+
}),
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
// Merge the addon tree with the existing tree
|
|
39
|
+
return publicTree ? new MergeTrees([publicTree, ...addonTree], { overwrite: true }) : new MergeTrees([...addonTree], { overwrite: true });
|
|
40
|
+
},
|
|
26
41
|
});
|
package/package.json
CHANGED
|
@@ -1,127 +1,134 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
"
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
2
|
+
"name": "@fleetbase/storefront-engine",
|
|
3
|
+
"version": "0.2.5",
|
|
4
|
+
"description": "Headless Commerce & Marketplace Extension for Fleetbase",
|
|
5
|
+
"fleetbase": {
|
|
6
|
+
"route": "storefront",
|
|
7
|
+
"dashboard": "storefront/int/v1/dashboard"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"fleetbase-extension",
|
|
11
|
+
"fleetbase-storefront",
|
|
12
|
+
"fleetbase",
|
|
13
|
+
"e-commerce",
|
|
14
|
+
"headless-commerce",
|
|
15
|
+
"headless-marketplace",
|
|
16
|
+
"ember-engine",
|
|
17
|
+
"ember-addon"
|
|
18
|
+
],
|
|
19
|
+
"repository": "https://github.com/fleetbase/storefront",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "Fleetbase Pte Ltd <hello@fleetbase.io>",
|
|
22
|
+
"directories": {
|
|
23
|
+
"app": "app",
|
|
24
|
+
"addon": "addon",
|
|
25
|
+
"tests": "tests"
|
|
26
|
+
},
|
|
27
|
+
"scripts": {
|
|
28
|
+
"build": "ember build --environment=production",
|
|
29
|
+
"lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
|
|
30
|
+
"lint:css": "stylelint \"**/*.css\"",
|
|
31
|
+
"lint:css:fix": "concurrently \"npm:lint:css -- --fix\"",
|
|
32
|
+
"lint:fix": "concurrently \"npm:lint:*:fix\" --names \"fix:\"",
|
|
33
|
+
"lint:hbs": "ember-template-lint .",
|
|
34
|
+
"lint:hbs:fix": "ember-template-lint . --fix",
|
|
35
|
+
"lint:js": "eslint . --cache",
|
|
36
|
+
"lint:js:fix": "eslint . --fix",
|
|
37
|
+
"start": "ember serve",
|
|
38
|
+
"test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"",
|
|
39
|
+
"test:ember": "ember test",
|
|
40
|
+
"test:ember-compatibility": "ember try:each",
|
|
41
|
+
"publish:npm": "npm config set registry https://registry.npmjs.org/ && npm publish",
|
|
42
|
+
"publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@fleetbase/ember-core": "^0.1.9",
|
|
46
|
+
"@fleetbase/ember-ui": "^0.2.8",
|
|
47
|
+
"@fleetbase/fleetops-data": "^0.1.6",
|
|
48
|
+
"@babel/core": "^7.23.2",
|
|
49
|
+
"@fortawesome/ember-fontawesome": "^0.4.1",
|
|
50
|
+
"@fortawesome/fontawesome-svg-core": "^6.4.0",
|
|
51
|
+
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
|
52
|
+
"ember-cli-babel": "^8.2.0",
|
|
53
|
+
"ember-cli-htmlbars": "^6.3.0",
|
|
54
|
+
"ember-intl": "6.3.2",
|
|
55
|
+
"ember-tag-input": "^3.1.0",
|
|
56
|
+
"ember-wormhole": "^0.6.0"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
60
|
+
"@babel/plugin-proposal-decorators": "^7.23.2",
|
|
61
|
+
"@ember/optional-features": "^2.0.0",
|
|
62
|
+
"@ember/test-helpers": "^3.2.0",
|
|
63
|
+
"@embroider/test-setup": "^3.0.2",
|
|
64
|
+
"@glimmer/component": "^1.1.2",
|
|
65
|
+
"@glimmer/tracking": "^1.1.2",
|
|
66
|
+
"broccoli-asset-rev": "^3.0.0",
|
|
67
|
+
"broccoli-funnel": "^3.0.8",
|
|
68
|
+
"broccoli-merge-trees": "^4.2.0",
|
|
69
|
+
"concurrently": "^8.2.2",
|
|
70
|
+
"ember-auto-import": "^2.6.3",
|
|
71
|
+
"ember-classic-decorator": "^3.0.0",
|
|
72
|
+
"ember-cli": "~5.4.1",
|
|
73
|
+
"ember-cli-clean-css": "^3.0.0",
|
|
74
|
+
"ember-cli-dependency-checker": "^3.3.2",
|
|
75
|
+
"ember-cli-inject-live-reload": "^2.1.0",
|
|
76
|
+
"ember-cli-sri": "^2.1.1",
|
|
77
|
+
"ember-cli-terser": "^4.0.2",
|
|
78
|
+
"ember-concurrency": "^3.1.1",
|
|
79
|
+
"ember-concurrency-decorators": "^2.0.3",
|
|
80
|
+
"ember-data": "^4.12.5",
|
|
81
|
+
"ember-engines": "^0.9.0",
|
|
82
|
+
"ember-load-initializers": "^2.1.2",
|
|
83
|
+
"ember-math-helpers": "^4.0.0",
|
|
84
|
+
"ember-page-title": "^8.0.0",
|
|
85
|
+
"ember-qunit": "^8.0.1",
|
|
86
|
+
"ember-resolver": "^11.0.1",
|
|
87
|
+
"ember-responsive": "^5.0.0",
|
|
88
|
+
"ember-source": "~5.4.0",
|
|
89
|
+
"ember-source-channel-url": "^3.0.0",
|
|
90
|
+
"ember-template-lint": "^5.11.2",
|
|
91
|
+
"ember-try": "^3.0.0",
|
|
92
|
+
"eslint": "^8.52.0",
|
|
93
|
+
"eslint-config-prettier": "^9.0.0",
|
|
94
|
+
"eslint-plugin-ember": "^11.11.1",
|
|
95
|
+
"eslint-plugin-n": "^16.2.0",
|
|
96
|
+
"eslint-plugin-prettier": "^5.0.1",
|
|
97
|
+
"eslint-plugin-qunit": "^8.0.1",
|
|
98
|
+
"loader.js": "^4.7.0",
|
|
99
|
+
"prettier": "^3.0.3",
|
|
100
|
+
"qunit": "^2.20.0",
|
|
101
|
+
"qunit-dom": "^2.0.0",
|
|
102
|
+
"stylelint": "^15.11.0",
|
|
103
|
+
"stylelint-config-standard": "^34.0.0",
|
|
104
|
+
"stylelint-prettier": "^4.0.2",
|
|
105
|
+
"webpack": "^5.89.0"
|
|
106
|
+
},
|
|
107
|
+
"peerDependencies": {
|
|
108
|
+
"ember-engines": "^0.9.0"
|
|
109
|
+
},
|
|
110
|
+
"engines": {
|
|
111
|
+
"node": ">= 18"
|
|
112
|
+
},
|
|
113
|
+
"ember": {
|
|
114
|
+
"edition": "octane"
|
|
115
|
+
},
|
|
116
|
+
"ember-addon": {
|
|
117
|
+
"configPath": "tests/dummy/config"
|
|
118
|
+
},
|
|
119
|
+
"prettier": {
|
|
120
|
+
"trailingComma": "es5",
|
|
121
|
+
"tabWidth": 4,
|
|
122
|
+
"semi": true,
|
|
123
|
+
"singleQuote": true,
|
|
124
|
+
"printWidth": 190,
|
|
125
|
+
"overrides": [
|
|
126
|
+
{
|
|
127
|
+
"files": "*.hbs",
|
|
128
|
+
"options": {
|
|
129
|
+
"singleQuote": false
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
}
|
|
127
134
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\Storefront\Expansions;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Build\Expansion;
|
|
6
|
+
|
|
7
|
+
class ContactFilterExpansion implements Expansion
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* Get the target class to expand.
|
|
11
|
+
*
|
|
12
|
+
* @return string|Class
|
|
13
|
+
*/
|
|
14
|
+
public static function target()
|
|
15
|
+
{
|
|
16
|
+
return \Fleetbase\FleetOps\Http\Filter\ContactFilter::class;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Filter contact's by their storefront order.
|
|
21
|
+
*
|
|
22
|
+
* @return \Closure
|
|
23
|
+
*/
|
|
24
|
+
public function storefront()
|
|
25
|
+
{
|
|
26
|
+
return function (?string $storefront) {
|
|
27
|
+
/** @var \Fleetbase\FleetOps\Http\Filter\ContactFilter $this */
|
|
28
|
+
$this->builder->whereHas(
|
|
29
|
+
'customerOrders',
|
|
30
|
+
function ($query) use ($storefront) {
|
|
31
|
+
$query->where('meta->storefront_id', $storefront);
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\Storefront\Expansions;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Build\Expansion;
|
|
6
|
+
|
|
7
|
+
class OrderFilterExpansion implements Expansion
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* Get the target class to expand.
|
|
11
|
+
*
|
|
12
|
+
* @return string|Class
|
|
13
|
+
*/
|
|
14
|
+
public static function target()
|
|
15
|
+
{
|
|
16
|
+
return \Fleetbase\FleetOps\Http\Filter\OrderFilter::class;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Filter orders by the storefront id.
|
|
21
|
+
*
|
|
22
|
+
* @return \Closure
|
|
23
|
+
*/
|
|
24
|
+
public function storefront()
|
|
25
|
+
{
|
|
26
|
+
return function (?string $storefront) {
|
|
27
|
+
/** @var \Fleetbase\FleetOps\Http\Filter\OrderFilter $this */
|
|
28
|
+
$this->builder->where('meta->storefront_id', $storefront);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Fleetbase\Storefront\Expansions;
|
|
4
|
+
|
|
5
|
+
use Fleetbase\Build\Expansion;
|
|
6
|
+
|
|
7
|
+
class VendorFilterExpansion implements Expansion
|
|
8
|
+
{
|
|
9
|
+
/**
|
|
10
|
+
* Get the target class to expand.
|
|
11
|
+
*
|
|
12
|
+
* @return string|Class
|
|
13
|
+
*/
|
|
14
|
+
public static function target()
|
|
15
|
+
{
|
|
16
|
+
return \Fleetbase\FleetOps\Http\Filter\VendorFilter::class;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Filter vendor's by their storefront order.
|
|
21
|
+
*
|
|
22
|
+
* @return \Closure
|
|
23
|
+
*/
|
|
24
|
+
public function storefront()
|
|
25
|
+
{
|
|
26
|
+
return function (?string $storefront) {
|
|
27
|
+
/** @var \Fleetbase\FleetOps\Http\Filter\VendorFilter $this */
|
|
28
|
+
$this->builder->whereHas(
|
|
29
|
+
'customerOrders',
|
|
30
|
+
function ($query) use ($storefront) {
|
|
31
|
+
$query->where('meta->storefront_id', $storefront);
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
namespace Fleetbase\Storefront\Http\Resources;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
6
|
+
use Fleetbase\Support\Http;
|
|
6
7
|
|
|
7
8
|
class Cart extends FleetbaseResource
|
|
8
9
|
{
|
|
@@ -15,7 +16,14 @@ class Cart extends FleetbaseResource
|
|
|
15
16
|
public function toArray($request)
|
|
16
17
|
{
|
|
17
18
|
return [
|
|
18
|
-
'id' => $this->public_id,
|
|
19
|
+
'id' => $this->when(Http::isInternalRequest(), $this->id,$this->public_id),
|
|
20
|
+
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
21
|
+
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
22
|
+
'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
|
|
23
|
+
'user_uuid' => $this->when(Http::isInternalRequest(), $this->user_uuid),
|
|
24
|
+
'checkout_uuid' => $this->when(Http::isInternalRequest(), $this->checkout_uuid),
|
|
25
|
+
'checkout_uuid' => $this->when(Http::isInternalRequest(), $this->checkout_uuid),
|
|
26
|
+
'customer_id' => $this->customer_id,
|
|
19
27
|
'currency' => $this->currency,
|
|
20
28
|
'subtotal' => $this->subtotal,
|
|
21
29
|
'total_items' => $this->total_items,
|
|
@@ -20,6 +20,10 @@ class Network extends FleetbaseResource
|
|
|
20
20
|
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
21
21
|
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
22
22
|
'key' => $this->when(Http::isInternalRequest(), $this->key),
|
|
23
|
+
'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
|
|
24
|
+
'created_by_uuid' => $this->when(Http::isInternalRequest(), $this->created_by_uuid),
|
|
25
|
+
'logo_uuid' => $this->when(Http::isInternalRequest(), $this->logo_uuid),
|
|
26
|
+
'backdrop_uuid' => $this->when(Http::isInternalRequest(), $this->backdrop_uuid),
|
|
23
27
|
'name' => $this->name,
|
|
24
28
|
'description' => $this->description,
|
|
25
29
|
'translations' => $this->translations ?? [],
|
|
@@ -21,6 +21,11 @@ class Product extends FleetbaseResource
|
|
|
21
21
|
'id' => $this->when(Http::isInternalRequest(), $this->id, $this->public_id),
|
|
22
22
|
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
23
23
|
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
24
|
+
'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
|
|
25
|
+
'store_uuid' => $this->when(Http::isInternalRequest(), $this->store_uuid),
|
|
26
|
+
'category_uuid' => $this->when(Http::isInternalRequest(), $this->category_uuid),
|
|
27
|
+
'created_by_uuid' => $this->when(Http::isInternalRequest(), $this->created_by_uuid),
|
|
28
|
+
'primary_image_uuid' => $this->when(Http::isInternalRequest(), $this->primary_image_uuid),
|
|
24
29
|
'name' => $this->name,
|
|
25
30
|
'description' => $this->description,
|
|
26
31
|
'sku' => $this->sku,
|
|
@@ -20,6 +20,10 @@ class Store extends FleetbaseResource
|
|
|
20
20
|
'uuid' => $this->when(Http::isInternalRequest(), $this->uuid),
|
|
21
21
|
'public_id' => $this->when(Http::isInternalRequest(), $this->public_id),
|
|
22
22
|
'key' => $this->when(Http::isInternalRequest(), $this->key),
|
|
23
|
+
'company_uuid' => $this->when(Http::isInternalRequest(), $this->company_uuid),
|
|
24
|
+
'created_by_uuid' => $this->when(Http::isInternalRequest(), $this->created_by_uuid),
|
|
25
|
+
'logo_uuid' => $this->when(Http::isInternalRequest(), $this->logo_uuid),
|
|
26
|
+
'backdrop_uuid' => $this->when(Http::isInternalRequest(), $this->backdrop_uuid),
|
|
23
27
|
'name' => $this->name,
|
|
24
28
|
'description' => $this->description,
|
|
25
29
|
'translations' => $this->translations ?? [],
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
namespace Fleetbase\Storefront\Http\Resources;
|
|
4
4
|
|
|
5
5
|
use Fleetbase\FleetOps\Http\Resources\v1\Place;
|
|
6
|
-
use Fleetbase\FleetOps\Http\Resources\Internal\v1\Place as InternalPlace;
|
|
7
6
|
use Fleetbase\Http\Resources\FleetbaseResource;
|
|
8
7
|
use Fleetbase\Support\Http;
|
|
9
8
|
|
|
@@ -24,7 +23,7 @@ class StoreLocation extends FleetbaseResource
|
|
|
24
23
|
'store' => data_get($this, 'store.public_id'),
|
|
25
24
|
'store_data' => $this->when($request->boolean('with_store'), new Store($this->store)),
|
|
26
25
|
'name' => $this->name,
|
|
27
|
-
'place' =>
|
|
26
|
+
'place' => $this->place ? new Place($this->place) : null,
|
|
28
27
|
'hours' => StoreHour::collection($this->hours),
|
|
29
28
|
'created_at' => $this->created_at,
|
|
30
29
|
'updated_at' => $this->updated_at,
|