diff --git a/addon/components/admin/product-category.hbs b/addon/components/admin/product-category.hbs
index fb5c4b15..414b6945 100644
--- a/addon/components/admin/product-category.hbs
+++ b/addon/components/admin/product-category.hbs
@@ -1 +1,29 @@
-{{yield}}
\ No newline at end of file
+
+
+
+
+
+
+ {{#each this.categories as |category|}}
+
+
{{category.name}}
+
+
+
+
+
+ {{#each this.categories as |subCategory|}}
+ {{#if (and (eq subCategory.parent.id category.id) (not (eq subCategory.id category.id)))}}
+
+
{{subCategory.name}}
+
+
+
+
+
+ {{/if}}
+ {{/each}}
+ {{/each}}
+
+
+
\ No newline at end of file
diff --git a/addon/components/admin/product-category.js b/addon/components/admin/product-category.js
index 48b9c2ac..f7c3e1e4 100644
--- a/addon/components/admin/product-category.js
+++ b/addon/components/admin/product-category.js
@@ -1,3 +1,134 @@
import Component from '@glimmer/component';
+import { tracked } from '@glimmer/tracking';
+import { inject as service } from '@ember/service';
+import { action } from '@ember/object';
+import { dasherize } from '@ember/string';
+export default class AdminProductCategoryComponent extends Component {
+ @service store;
+ @service modalsManager;
+ @service currentUser;
+ @service modalsManager;
+ @service notifications;
+ @service fetch;
+ @service hostRouter;
+ @tracked categories = [];
+ @tracked selectedCategory;
+ @tracked isLoading = false;
+ @tracked buttonTitle = null;
-export default class AdminProductCategoryComponent extends Component {}
+ constructor() {
+ super(...arguments);
+ this.category = this.args.category;
+ this.fetchCategories();
+ }
+
+ @action async addCategory() {
+ const category = this.store.createRecord('category', {
+ for: 'pallet_product',
+ });
+
+ this.modalsManager.show('modals/create-product-category', {
+ title: 'Create a new product category',
+ acceptButtonIcon: 'check',
+ acceptButtonIconPrefix: 'fas',
+ declineButtonIcon: 'times',
+ declineButtonIconPrefix: 'fas',
+ category,
+ uploadNewPhoto: (file) => {
+ this.fetch.uploadFile.perform(
+ file,
+ {
+ path: `uploads/${category.company_uuid}/product-category-icon/${dasherize(category.name ?? this.currentUser.companyId)}`,
+ subject_uuid: category.id,
+ subject_type: `category`,
+ type: `category_icon`,
+ },
+ (uploadedFile) => {
+ category.setProperties({
+ icon_file_uuid: uploadedFile.id,
+ icon_url: uploadedFile.url,
+ icon: uploadedFile,
+ });
+ }
+ );
+ },
+ confirm: (modal) => {
+ modal.startLoading();
+
+ return category.save().then(() => {
+ this.notifications.success('New product category created.');
+ return this.fetchCategories();
+ });
+ },
+ });
+ }
+
+ @action async fetchCategories() {
+ this.categories = await this.store.query('category', {
+ for: 'pallet_product',
+ });
+ }
+
+ @action async addSubCategory(category) {
+ const subCategory = this.store.createRecord('category', {
+ for: 'pallet_product',
+ parent: category,
+ });
+
+ this.modalsManager.show('modals/create-product-category', {
+ title: 'Create a new subcategory',
+ acceptButtonIcon: 'check',
+ acceptButtonIconPrefix: 'fas',
+ declineButtonIcon: 'times',
+ declineButtonIconPrefix: 'fas',
+ category: subCategory,
+ uploadNewPhoto: (file) => {
+ this.fetch.uploadFile.perform(
+ file,
+ {
+ path: `uploads/${subCategory.company_uuid}/product-category-icon/${dasherize(subCategory.name ?? this.currentUser.companyId)}`,
+ subject_uuid: subCategory.id,
+ subject_type: `category`,
+ type: `category_icon`,
+ },
+ (uploadedFile) => {
+ subCategory.setProperties({
+ icon_file_uuid: uploadedFile.id,
+ icon_url: uploadedFile.url,
+ icon: uploadedFile,
+ });
+ }
+ );
+ },
+ confirm: async (modal) => {
+ modal.startLoading();
+
+ try {
+ await subCategory.save();
+ this.notifications.success('New subcategory created.');
+ await this.fetchCategories();
+ } catch (error) {
+ this.notifications.error('Error creating subcategory.');
+ console.error('Error creating subcategory:', error);
+ } finally {
+ modal.stopLoading();
+ }
+ },
+ });
+ }
+
+ @action async deleteCategory(category) {
+ const confirmation = confirm(`Are you sure you want to delete the category "${category.name}"?`);
+
+ if (confirmation) {
+ try {
+ await category.destroyRecord();
+ this.notifications.success('Category deleted successfully.');
+ await this.fetchCategories();
+ } catch (error) {
+ this.notifications.error('Error deleting category.');
+ console.error('Error deleting category:', error);
+ }
+ }
+ }
+}
diff --git a/addon/components/admin/visibility-controls.hbs b/addon/components/admin/visibility-controls.hbs
deleted file mode 100644
index dc14590e..00000000
--- a/addon/components/admin/visibility-controls.hbs
+++ /dev/null
@@ -1,12 +0,0 @@
-
- Visibility controls allow you to disable sections of Pallet. Toggle the checkbox to enable or disable sections to hide in Pallet
- {{#each this.visibilitySettings as |visibilityControl|}}
-
-
-
- {{/each}}
-
-
-
-
-
\ No newline at end of file
diff --git a/addon/components/admin/visibility-controls.js b/addon/components/admin/visibility-controls.js
deleted file mode 100644
index e6ea41bd..00000000
--- a/addon/components/admin/visibility-controls.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import Component from '@glimmer/component';
-import { tracked } from '@glimmer/tracking';
-import { inject as service } from '@ember/service';
-import { action } from '@ember/object';
-import { isArray } from '@ember/array';
-
-export default class AdminVisibilityControlsComponent extends Component {
- @service fetch;
- @tracked visibilitySettings = [
- // { name: 'Dashboard', route: 'operations.orders', visible: true },
- { name: 'Products', route: 'products', visible: true },
- { name: 'Warehouses', route: 'warehouses', visible: true },
- { name: 'Suppliers', route: 'suppliers', visible: true },
- { name: 'Inventory', route: 'inventory', visible: true },
- { name: 'Sales Orders', route: 'sales-orders', visible: true },
- { name: 'Purchase Orders', route: 'purchase-orders', visible: true },
- { name: 'Audits', route: 'audits', visible: true },
- { name: 'Reports', route: 'reports', visible: true },
- ];
- @tracked isLoading = false;
-
- constructor() {
- super(...arguments);
- this.loadVisibilitySettings();
- }
-
- @action mutateVisibility(route, visible) {
- this.visibilitySettings = [...this.visibilitySettings].map((visibilityControl) => {
- if (visibilityControl.route === route) {
- return {
- ...visibilityControl,
- visible,
- };
- }
-
- return visibilityControl;
- });
- }
-
- @action loadVisibilitySettings() {
- this.isLoading = true;
-
- this.fetch
- .get('pallet/settings/visibility')
- .then(({ visibilitySettings }) => {
- if (isArray(visibilitySettings)) {
- for (let i = 0; i < visibilitySettings.length; i++) {
- const visibilityControl = visibilitySettings.objectAt(i);
- this.mutateVisibility(visibilityControl.route, visibilityControl.visible);
- }
- }
- })
- .catch((error) => {
- this.notifications.serverError(error);
- })
- .finally(() => {
- this.isLoading = false;
- });
- }
-
- @action saveVisibilitySettings() {
- this.isLoading = true;
-
- this.fetch
- .post('pallet/settings/visibility', { visibilitySettings: this.visibilitySettings })
- .then(({ visibilitySettings }) => {
- if (isArray(visibilitySettings)) {
- for (let i = 0; i < visibilitySettings.length; i++) {
- const visibilityControl = visibilitySettings.objectAt(i);
- this.mutateVisibility(visibilityControl.route, visibilityControl.visible);
- }
- }
- })
- .catch((error) => {
- this.notifications.serverError(error);
- })
- .finally(() => {
- this.isLoading = false;
- });
- }
-}
diff --git a/addon/controllers/admin/product-category.js b/addon/controllers/admin/product-category.js
deleted file mode 100644
index 948d3a6e..00000000
--- a/addon/controllers/admin/product-category.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Controller from '@ember/controller';
-
-export default class AdminProductCategoryController extends Controller {}
diff --git a/addon/engine.js b/addon/engine.js
index 944b547e..afbe46fa 100644
--- a/addon/engine.js
+++ b/addon/engine.js
@@ -3,7 +3,7 @@ import loadInitializers from 'ember-load-initializers';
import Resolver from 'ember-resolver';
import config from './config/environment';
import services from '@fleetbase/ember-core/exports/services';
-import AdminVisibilityControlsComponent from './components/admin/visibility-controls';
+import AdminProductCategoryComponent from './components/admin/product-category';
const { modulePrefix } = config;
const externalRoutes = ['console', 'extensions'];
@@ -17,37 +17,22 @@ export default class PalletEngine extends Engine {
};
setupExtension = function (app, engine, universe) {
// register menu item in header
- universe.registerHeaderMenuItem('Pallet', 'console.pallet', { icon: 'pallet', priority: 0 });
+ universe.registerHeaderMenuItem('Pallet', 'console.pallet', { icon: 'pallet', priority: 1 });
// register admin settings -- create a pallet menu panel with it's own setting options
universe.registerAdminMenuPanel(
'Pallet Config',
[
{
- title: 'Visibility Controls',
+ title: 'Product Category',
icon: 'eye',
- component: AdminVisibilityControlsComponent,
+ component: AdminProductCategoryComponent,
},
],
{
slug: 'pallet',
}
);
-
- // create primary registry for engine
- universe.createRegistry('engine:pallet');
-
- // register the product panel
- universe.createRegistry('component:product-panel');
-
- // register the inventory panel
- universe.createRegistry('component:inventory-panel');
-
- // register the supplier panel
- universe.createRegistry('component:supplier-panel');
-
- // register the warehouse panel
- universe.createRegistry('component:warehouse-panel');
};
}
diff --git a/addon/routes/admin/product-category.js b/addon/routes/admin/product-category.js
deleted file mode 100644
index 0ada6d8f..00000000
--- a/addon/routes/admin/product-category.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import Route from '@ember/routing/route';
-import { inject as service } from '@ember/service';
-
-export default class AdminProductCategoryRoute extends Route {
- @service store;
-
- queryParams = {
- page: { refreshModel: true },
- limit: { refreshModel: true },
- sort: { refreshModel: true },
- query: { refreshModel: true },
- created_at: { refreshModel: true },
- };
-
- /**
- * Fetch the model data based on the specified parameters.
- *
- * @param {Object} params - Query parameters for fetching notifications.
- * @returns {Promise} - A promise that resolves with the notification data.
- */
- model(params = {}) {
- return this.store.query('notification', params);
- }
-}
diff --git a/addon/templates/admin/product-category.hbs b/addon/templates/admin/product-category.hbs
deleted file mode 100644
index 4abdd78c..00000000
--- a/addon/templates/admin/product-category.hbs
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/addon/templates/purchase-orders/index.hbs b/addon/templates/purchase-orders/index.hbs
index 8e5a9438..5ac34b2d 100644
--- a/addon/templates/purchase-orders/index.hbs
+++ b/addon/templates/purchase-orders/index.hbs
@@ -13,7 +13,7 @@
diff --git a/app/components/admin/visibility-controls.js b/app/components/admin/visibility-controls.js
deleted file mode 100644
index 94d6bebc..00000000
--- a/app/components/admin/visibility-controls.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@fleetbase/pallet-engine/components/admin/visibility-controls';
diff --git a/app/controllers/admin/product-category.js b/app/controllers/admin/product-category.js
deleted file mode 100644
index fa08e325..00000000
--- a/app/controllers/admin/product-category.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@fleetbase/pallet-engine/controllers/admin/product-category';
diff --git a/app/routes/admin/product-category.js b/app/routes/admin/product-category.js
deleted file mode 100644
index 1ece2cae..00000000
--- a/app/routes/admin/product-category.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@fleetbase/pallet-engine/routes/admin/product-category';
diff --git a/app/templates/admin/product-category.js b/app/templates/admin/product-category.js
deleted file mode 100644
index 3a750f16..00000000
--- a/app/templates/admin/product-category.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from '@fleetbase/pallet-engine/templates/admin/product-category';
diff --git a/tests/integration/components/admin/visibility-controls-test.js b/tests/integration/components/admin/visibility-controls-test.js
deleted file mode 100644
index 40f2675b..00000000
--- a/tests/integration/components/admin/visibility-controls-test.js
+++ /dev/null
@@ -1,26 +0,0 @@
-import { module, test } from 'qunit';
-import { setupRenderingTest } from 'dummy/tests/helpers';
-import { render } from '@ember/test-helpers';
-import { hbs } from 'ember-cli-htmlbars';
-
-module('Integration | Component | admin/visibility-controls', function (hooks) {
- setupRenderingTest(hooks);
-
- test('it renders', async function (assert) {
- // Set any properties with this.set('myProperty', 'value');
- // Handle any actions with this.set('myAction', function(val) { ... });
-
- await render(hbs` `);
-
- assert.dom(this.element).hasText('');
-
- // Template block usage:
- await render(hbs`
-
- template block text
-
- `);
-
- assert.dom(this.element).hasText('template block text');
- });
-});
diff --git a/tests/unit/controllers/admin/product-category-test.js b/tests/unit/controllers/admin/product-category-test.js
deleted file mode 100644
index d2898401..00000000
--- a/tests/unit/controllers/admin/product-category-test.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'dummy/tests/helpers';
-
-module('Unit | Controller | admin/product-category', function (hooks) {
- setupTest(hooks);
-
- // TODO: Replace this with your real tests.
- test('it exists', function (assert) {
- let controller = this.owner.lookup('controller:admin/product-category');
- assert.ok(controller);
- });
-});
diff --git a/tests/unit/routes/admin/product-category-test.js b/tests/unit/routes/admin/product-category-test.js
deleted file mode 100644
index f9371676..00000000
--- a/tests/unit/routes/admin/product-category-test.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { module, test } from 'qunit';
-import { setupTest } from 'dummy/tests/helpers';
-
-module('Unit | Route | admin/product-category', function (hooks) {
- setupTest(hooks);
-
- test('it exists', function (assert) {
- let route = this.owner.lookup('route:admin/product-category');
- assert.ok(route);
- });
-});