diff --git a/addon/components/add-product-as-entity-button.js b/addon/components/add-product-as-entity-button.js
index 4db8f67..ee46f7f 100644
--- a/addon/components/add-product-as-entity-button.js
+++ b/addon/components/add-product-as-entity-button.js
@@ -40,12 +40,12 @@ export default class AddProductAsEntityButtonComponent extends Component {
this.order.meta.pushObjects([
{
key: 'storefront',
- value: selectedStorefront.name
+ value: selectedStorefront.name,
},
{
key: 'storefront_id',
- value: selectedStorefront.public_id
- }
+ value: selectedStorefront.public_id,
+ },
]);
}
})
diff --git a/addon/components/modals/create-first-store.hbs b/addon/components/modals/create-first-store.hbs
index d396f00..3ea1cd2 100644
--- a/addon/components/modals/create-first-store.hbs
+++ b/addon/components/modals/create-first-store.hbs
@@ -15,18 +15,20 @@
@name={{t "storefront.component.modals.create-first-store.storefront-name"}}
@value={{@options.store.name}}
@helpText={{t "storefront.component.modals.create-first-store.enter-name"}}
+ @disabled={{cannot "storefront create store"}}
/>
-
+
diff --git a/addon/components/widget/storefront-key-metrics.hbs b/addon/components/widget/storefront-key-metrics.hbs
index b297016..bc6556a 100644
--- a/addon/components/widget/storefront-key-metrics.hbs
+++ b/addon/components/widget/storefront-key-metrics.hbs
@@ -10,7 +10,7 @@
{{else}}
{{#each-in this.metrics as |title options|}}
-
+
{{/each-in}}
{{/if}}
diff --git a/addon/controllers/application.js b/addon/controllers/application.js
index cc67f40..c41332c 100644
--- a/addon/controllers/application.js
+++ b/addon/controllers/application.js
@@ -12,7 +12,7 @@ export default class ApplicationController extends Controller {
@action createNewStorefront() {
return this.storefront.createNewStorefront({
onSuccess: () => {
- const loader = this.loader.show({ loadingMessage: `Switching to newly created store...` });
+ const loader = this.loader.show({ loadingMessage: 'Switching to newly created store...' });
this.hostRouter.refresh().then(() => {
this.notifyPropertyChange('activeStore');
diff --git a/addon/controllers/products/index/category/edit.js b/addon/controllers/products/index/category/edit.js
index cfe4bf1..a7aa61a 100644
--- a/addon/controllers/products/index/category/edit.js
+++ b/addon/controllers/products/index/category/edit.js
@@ -11,6 +11,7 @@ export default class ProductsIndexCategoryEditController extends ProductsIndexCa
@tracked overlayActionButtonTitle = 'Save Changes';
@tracked overlayActionButtonIcon = 'save';
@tracked overlayExitButtonTitle = 'Done';
+ abilityPermission = 'storefront update product';
get overlayTitle() {
return `Edit ${this.product.name}`;
diff --git a/addon/controllers/products/index/category/new.js b/addon/controllers/products/index/category/new.js
index befe937..c8dd0f2 100644
--- a/addon/controllers/products/index/category/new.js
+++ b/addon/controllers/products/index/category/new.js
@@ -26,6 +26,7 @@ export default class ProductsIndexCategoryNewController extends BaseController {
@tracked uploadedFiles = [];
@tracked primaryFile = null;
@tracked isSaving = false;
+ abilityPermission = 'storefront create product';
/** overlay options */
@tracked overlayTitle = 'New Product';
@@ -66,10 +67,13 @@ export default class ProductsIndexCategoryNewController extends BaseController {
this.loader.removeLoader(loader);
this.notifications.success(this.intl.t('storefront.products.index.new.new-product-created-success'));
-
+
try {
yield this.transitionToRoute('products.index.category', category.slug);
- } catch (error) {}
+ } catch (error) {
+ this.notifications.serverError(error);
+ }
+
this.reset();
}
diff --git a/addon/routes/application.js b/addon/routes/application.js
index a1e604a..9ddf445 100644
--- a/addon/routes/application.js
+++ b/addon/routes/application.js
@@ -8,20 +8,31 @@ export default class ApplicationRoute extends Route {
@service loader;
@service currentUser;
@service modalsManager;
- // @service theme;
+ @service notifications;
+ @service hostRouter;
+ @service abilities;
+ @service intl;
@service storefront;
@action loading(transition) {
this.loader.showOnInitialTransition(transition, 'section.next-view-section', { loadingMessage: 'Loading storefront...' });
}
+ @action error(error) {
+ this.notifications.serverError(error);
+ }
+
@action willTransition() {
this.modalsManager.done();
}
beforeModel() {
- this.disableSandbox();
+ if (this.abilities.cannot('storefront see extension')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console');
+ }
+ this.disableSandbox();
return this.fetch.get('actions/store-count', {}, { namespace: 'storefront/int/v1' }).then(({ storeCount }) => {
// if no store count prompt to create a store
if (!storeCount) {
@@ -40,7 +51,7 @@ export default class ApplicationRoute extends Route {
}
}
- @action disableSandbox() {
+ disableSandbox() {
this.currentUser.setOption('sandbox', false);
// this.theme.setEnvironment();
}
diff --git a/addon/routes/customers/index.js b/addon/routes/customers/index.js
index 1a41a90..fcd62dd 100644
--- a/addon/routes/customers/index.js
+++ b/addon/routes/customers/index.js
@@ -6,6 +6,10 @@ import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route
export default class CustomersIndexRoute extends Route {
@service store;
@service storefront;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
queryParams = {
page: { refreshModel: true },
@@ -29,6 +33,13 @@ export default class CustomersIndexRoute extends Route {
}
}
+ beforeModel() {
+ if (this.abilities.cannot('storefront list customer')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model(params) {
return this.store.query('customer', { ...params, storefront: this.storefront.getActiveStore('public_id') });
}
diff --git a/addon/routes/customers/index/edit.js b/addon/routes/customers/index/edit.js
index 1cd64b4..4290631 100644
--- a/addon/routes/customers/index/edit.js
+++ b/addon/routes/customers/index/edit.js
@@ -1,3 +1,16 @@
import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
-export default class CustomersIndexEditRoute extends Route {}
+export default class CustomersIndexEditRoute extends Route {
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
+
+ beforeModel() {
+ if (this.abilities.cannot('storefront update customer')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+}
diff --git a/addon/routes/customers/index/view.js b/addon/routes/customers/index/view.js
index 94612de..75a94a9 100644
--- a/addon/routes/customers/index/view.js
+++ b/addon/routes/customers/index/view.js
@@ -3,11 +3,22 @@ import { inject as service } from '@ember/service';
export default class CustomersIndexViewRoute extends Route {
@service store;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
queryParams = {
view: { refreshModel: false },
};
+ beforeModel() {
+ if (this.abilities.cannot('storefront view customer')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model({ public_id }) {
return this.store.findRecord('contact', public_id);
}
diff --git a/addon/routes/networks/index.js b/addon/routes/networks/index.js
index cdc8735..0dbe597 100644
--- a/addon/routes/networks/index.js
+++ b/addon/routes/networks/index.js
@@ -5,6 +5,10 @@ import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route
export default class NetworksIndexRoute extends Route {
@service store;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
queryParams = {
page: { refreshModel: true },
@@ -22,6 +26,13 @@ export default class NetworksIndexRoute extends Route {
}
}
+ beforeModel() {
+ if (this.abilities.cannot('storefront list network')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model(params) {
return this.store.query('network', { with_gateways: 1, with_notification_channels: 1, ...params });
}
diff --git a/addon/routes/networks/index/network.js b/addon/routes/networks/index/network.js
index 2ff4ea2..f0b671f 100644
--- a/addon/routes/networks/index/network.js
+++ b/addon/routes/networks/index/network.js
@@ -3,6 +3,17 @@ import { inject as service } from '@ember/service';
export default class NetworksIndexNetworkRoute extends Route {
@service store;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
+
+ beforeModel() {
+ if (this.abilities.cannot('storefront view network')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
model({ public_id }) {
return this.store.findRecord('network', public_id);
diff --git a/addon/routes/orders/index.js b/addon/routes/orders/index.js
index 00a5de7..08260b5 100644
--- a/addon/routes/orders/index.js
+++ b/addon/routes/orders/index.js
@@ -6,6 +6,10 @@ import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route
export default class OrdersIndexRoute extends Route {
@service store;
@service storefront;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
queryParams = {
page: { refreshModel: true },
@@ -33,6 +37,13 @@ export default class OrdersIndexRoute extends Route {
}
}
+ beforeModel() {
+ if (this.abilities.cannot('storefront list order')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model(params) {
return this.store.query('order', { ...params, storefront: this.storefront.getActiveStore('public_id') });
}
diff --git a/addon/routes/orders/index/edit.js b/addon/routes/orders/index/edit.js
index e5ce7aa..0f97835 100644
--- a/addon/routes/orders/index/edit.js
+++ b/addon/routes/orders/index/edit.js
@@ -1,3 +1,16 @@
import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
-export default class OrdersIndexEditRoute extends Route {}
+export default class OrdersIndexEditRoute extends Route {
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
+
+ beforeModel() {
+ if (this.abilities.cannot('storefront update order')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+}
diff --git a/addon/routes/orders/index/new.js b/addon/routes/orders/index/new.js
index 697b8be..82780cc 100644
--- a/addon/routes/orders/index/new.js
+++ b/addon/routes/orders/index/new.js
@@ -1,3 +1,16 @@
import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
-export default class OrdersIndexNewRoute extends Route {}
+export default class OrdersIndexNewRoute extends Route {
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
+
+ beforeModel() {
+ if (this.abilities.cannot('storefront create order')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+}
diff --git a/addon/routes/orders/index/view.js b/addon/routes/orders/index/view.js
index 66e7482..a8fc2a0 100644
--- a/addon/routes/orders/index/view.js
+++ b/addon/routes/orders/index/view.js
@@ -7,11 +7,21 @@ export default class OrdersIndexViewRoute extends Route {
@service notifications;
@service store;
@service socket;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
@action error(error) {
this.notifications.serverError(error);
}
+ beforeModel() {
+ if (this.abilities.cannot('storefront view order')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model({ public_id }) {
const order = this.store.queryRecord('order', {
public_id,
diff --git a/addon/routes/products/index.js b/addon/routes/products/index.js
index 99754f1..77352c3 100644
--- a/addon/routes/products/index.js
+++ b/addon/routes/products/index.js
@@ -6,6 +6,10 @@ import isNestedRouteTransition from '@fleetbase/ember-core/utils/is-nested-route
export default class ProductsIndexRoute extends Route {
@service store;
@service currentUser;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
@action willTransition(transition) {
this.controller.category = null;
@@ -16,6 +20,13 @@ export default class ProductsIndexRoute extends Route {
}
}
+ beforeModel() {
+ if (this.abilities.cannot('storefront list product')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model(params = {}) {
return this.store.query('category', {
for: 'storefront_product',
diff --git a/addon/routes/products/index/category.js b/addon/routes/products/index/category.js
index 2c89bf1..34cf0aa 100644
--- a/addon/routes/products/index/category.js
+++ b/addon/routes/products/index/category.js
@@ -7,6 +7,10 @@ export default class ProductsIndexCategoryRoute extends Route {
@service store;
@service currentUser;
@service loader;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
@tracked categorySlug;
queryParams = {
@@ -26,10 +30,17 @@ export default class ProductsIndexCategoryRoute extends Route {
}
}
- loading(transition) {
+ @action loading(transition) {
this.loader.showOnInitialTransition(transition, 'section.next-view-section', { loadingMessage: 'Loading products...' });
}
+ beforeModel() {
+ if (this.abilities.cannot('storefront list product')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model({ slug, ...params }) {
this.categorySlug = slug;
diff --git a/addon/routes/products/index/category/edit.js b/addon/routes/products/index/category/edit.js
index 13c868d..c058d6d 100644
--- a/addon/routes/products/index/category/edit.js
+++ b/addon/routes/products/index/category/edit.js
@@ -4,8 +4,19 @@ import { filterHasManyForNewRecords } from '../../../../serializers/product';
export default class ProductsIndexCategoryEditRoute extends Route {
@service store;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
templateName = 'products.index.category.new';
+ beforeModel() {
+ if (this.abilities.cannot('storefront update product')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model({ public_id }) {
return this.store.queryRecord('product', {
public_id,
diff --git a/addon/routes/products/index/category/new.js b/addon/routes/products/index/category/new.js
index b0c6810..5b2498d 100644
--- a/addon/routes/products/index/category/new.js
+++ b/addon/routes/products/index/category/new.js
@@ -1,9 +1,23 @@
import Route from '@ember/routing/route';
+import { inject as service } from '@ember/service';
+import { action } from '@ember/object';
export default class ProductsIndexCategoryNewRoute extends Route {
- didTransition() {
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
+
+ @action didTransition() {
if (this.controller) {
this.controller.reset();
}
}
+
+ beforeModel() {
+ if (this.abilities.cannot('storefront create product')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
}
diff --git a/addon/routes/products/index/index.js b/addon/routes/products/index/index.js
index e48661c..fe42d24 100644
--- a/addon/routes/products/index/index.js
+++ b/addon/routes/products/index/index.js
@@ -4,6 +4,10 @@ import { inject as service } from '@ember/service';
export default class ProductsIndexIndexRoute extends Route {
@service store;
@service currentUser;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
queryParams = {
page: { refreshModel: true },
@@ -16,6 +20,13 @@ export default class ProductsIndexIndexRoute extends Route {
updated_at: { refreshModel: true },
};
+ beforeModel() {
+ if (this.abilities.cannot('storefront list product')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console.storefront');
+ }
+ }
+
model(params) {
return this.store.query('product', { store_uuid: this.currentUser.getOption('activeStorefront'), ...params });
}
diff --git a/addon/routes/settings/index.js b/addon/routes/settings/index.js
index 5575fae..f64ea26 100644
--- a/addon/routes/settings/index.js
+++ b/addon/routes/settings/index.js
@@ -5,6 +5,17 @@ export default class SettingsIndexRoute extends Route {
@service store;
@service currentUser;
@service storefront;
+ @service intl;
+ @service abilities;
+ @service hostRouter;
+ @service notifications;
+
+ beforeModel() {
+ if (this.abilities.cannot('storefront view settings')) {
+ this.notifications.warning(this.intl.t('common.unauthorized-access'));
+ return this.hostRouter.transitionTo('console');
+ }
+ }
model() {
return this.store.peekRecord('store', this.currentUser.getOption('activeStorefront'));
diff --git a/addon/services/storefront.js b/addon/services/storefront.js
index cce8df1..9f44638 100644
--- a/addon/services/storefront.js
+++ b/addon/services/storefront.js
@@ -7,47 +7,14 @@ import { get } from '@ember/object';
* Service to manage storefront operations.
*/
export default class StorefrontService extends Service.extend(Evented) {
- /**
- * Ember service for data store.
- * @type {Service}
- */
@service store;
-
- /**
- * Ember service for intl.
- * @type {Service}
- */
@service intl;
-
- /**
- * Ember service for fetch operations.
- * @type {Service}
- */
@service fetch;
-
- /**
- * Ember service for notifications.
- * @type {Service}
- */
@service notifications;
-
- /**
- * Ember service for current user information.
- * @type {Service}
- */
@service currentUser;
-
- /**
- * Ember service for managing modals.
- * @type {Service}
- */
@service modalsManager;
-
- /**
- * Ember service for router operations.
- * @type {Service}
- */
@service hostRouter;
+ @service abilities;
/**
* Gets the active store.
@@ -137,18 +104,17 @@ export default class StorefrontService extends Service.extend(Evented) {
backdropClose: false,
order,
store,
- confirm: (modal) => {
+ confirm: async (modal) => {
modal.startLoading();
- return this.fetch
- .post('orders/accept', { order: order.id }, { namespace: 'storefront/int/v1' })
- .then(() => {
- this.trigger('order.accepted', order);
- modal.stopLoading();
- })
- .catch((error) => {
- this.notifications.serverError(error);
- });
+ try {
+ await this.fetch.post('orders/accept', { order: order.id }, { namespace: 'storefront/int/v1' });
+ this.trigger('order.accepted', order);
+ modal.done();
+ } catch (error) {
+ modal.stopLoading();
+ this.notifications.serverError(error);
+ }
},
});
}
@@ -201,6 +167,7 @@ export default class StorefrontService extends Service.extend(Evented) {
title: this.intl.t('storefront.service.storefront.create-first-storefront'),
acceptButtonIcon: 'check',
acceptButtonIconPrefix: 'fas',
+ acceptButtonDisabled: this.abilities.cannot('storefront create store'),
closeButton: false,
backdropClose: false,
keyboard: true,
@@ -209,20 +176,18 @@ export default class StorefrontService extends Service.extend(Evented) {
declineButtonIcon: 'times',
declineButtonIconPrefix: 'fas',
store,
- confirm: (modal, done) => {
+ confirm: async (modal) => {
modal.startLoading();
- store
- .save()
- .then((store) => {
- this.notifications.success(this.intl.t('storefront.service.storefront.storefront-has-been-create-success'));
- this.setActiveStorefront(store);
- return done();
- })
- .catch((error) => {
- modal.stopLoading();
- this.notifications.serverError(error);
- });
+ try {
+ await store.save();
+ this.notifications.success(this.intl.t('storefront.service.storefront.storefront-has-been-create-success'));
+ this.setActiveStorefront(store);
+ modal.done();
+ } catch (error) {
+ modal.stopLoading();
+ this.notifications.serverError(error);
+ }
},
decline: () => {
this.hostRouter.transitionTo('console');
@@ -250,26 +215,22 @@ export default class StorefrontService extends Service.extend(Evented) {
declineButtonIcon: 'times',
declineButtonIconPrefix: 'fas',
store,
- confirm: (modal, done) => {
+ confirm: async (modal) => {
modal.startLoading();
- store
- .save()
- .then((store) => {
- this.notifications.success(this.intl.t('storefront.service.storefront.storefront-create-success'));
- // this.currentUser.setOption('activeStorefront', store.id);
- this.setActiveStorefront(store);
-
- if (typeof options?.onSuccess === 'function') {
- options.onSuccess(store);
- }
-
- return done();
- })
- .catch((error) => {
- modal.stopLoading();
- this.notifications.serverError(error);
- });
+ try {
+ const store = await store.save();
+ this.notifications.success(this.intl.t('storefront.service.storefront.storefront-create-success'));
+ // this.currentUser.setOption('activeStorefront', store.id);
+ this.setActiveStorefront(store);
+ if (typeof options?.onSuccess === 'function') {
+ options.onSuccess(store);
+ }
+ modal.done();
+ } catch (error) {
+ modal.stopLoading();
+ this.notifications.serverError(error);
+ }
},
...options,
});
diff --git a/addon/templates/application.hbs b/addon/templates/application.hbs
index 303e672..efb1c8f 100644
--- a/addon/templates/application.hbs
+++ b/addon/templates/application.hbs
@@ -2,11 +2,37 @@
{{t "storefront.sidebar.dashboard"}}
- {{t "storefront.sidebar.products"}}
- {{t "storefront.sidebar.customers"}}
- {{t "storefront.sidebar.orders"}}
- {{t "storefront.sidebar.networks"}}
- {{t "storefront.sidebar.settings"}}
+ {{t "storefront.sidebar.products"}}
+ {{t
+ "storefront.sidebar.customers"
+ }}
+ {{t "storefront.sidebar.orders"}}
+ {{t "storefront.sidebar.networks"}}
+ {{t "storefront.sidebar.settings"}}
{{t "storefront.sidebar.launch-app"}}
diff --git a/addon/templates/customers/index.hbs b/addon/templates/customers/index.hbs
index fb1dcb2..8f5a07c 100644
--- a/addon/templates/customers/index.hbs
+++ b/addon/templates/customers/index.hbs
@@ -8,7 +8,7 @@
@buttonWrapperClass="mr-2"
/>
-
+
diff --git a/addon/templates/networks/index.hbs b/addon/templates/networks/index.hbs
index 8dfb450..4c5cb7b 100644
--- a/addon/templates/networks/index.hbs
+++ b/addon/templates/networks/index.hbs
@@ -1,5 +1,5 @@
-
+
@@ -26,13 +26,13 @@