Skip to content

Commit

Permalink
Merge pull request #1 from fleetbase/dev-main
Browse files Browse the repository at this point in the history
Dev main
  • Loading branch information
roncodes authored Jan 31, 2024
2 parents 623145d + 9e7592e commit 3618598
Show file tree
Hide file tree
Showing 484 changed files with 30,569 additions and 2,232 deletions.
13 changes: 13 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,16 @@

# broccoli-debug
/DEBUG/

# server
.idea/*
.idea/codeStyleSettings.xml
composer.lock
/server_vendor
/server/vendor/
.phpunit.result.cache
.php_cs.cache
.php-cs-fixer.cache
*.swp
*.swo
.DS_Store
1 change: 1 addition & 0 deletions addon/adapters/expired-stock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './pallet';
1 change: 1 addition & 0 deletions addon/adapters/low-stock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './pallet';
1 change: 1 addition & 0 deletions addon/adapters/warehouse-aisle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './pallet';
1 change: 1 addition & 0 deletions addon/adapters/warehouse-bin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './pallet';
1 change: 1 addition & 0 deletions addon/adapters/warehouse-dock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './pallet';
1 change: 1 addition & 0 deletions addon/adapters/warehouse-rack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './pallet';
1 change: 1 addition & 0 deletions addon/adapters/warehouse-section.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './pallet';
32 changes: 32 additions & 0 deletions addon/components/admin/product-category.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<ContentPanel @title="Categories" @open={{true}} @pad={{true}} @panelBodyClass="bg-white dark:bg-gray-800">
<div class="mt-3 flex items-center justify-end">
<Button @type="primary" @size="sm" @icon="plus" @text="Add category" @onClick={{this.addCategory}} @disabled={{this.isLoading}} @isLoading={{this.isLoading}} />
</div>
<div class="mt-3">
<ul>
{{#each this.categories as |category|}}
<div class="flex justify-between items-center border-b border-gray-700 py-2">
<span>{{category.name}}</span>
<div class="flex items-center space-x-2">
<Button @type="info" @size="sm" @icon="eye" @text="Add subcategories" @onClick={{fn this.addSubCategory category}} />
<Button @type="danger" @size="sm" @icon="trash" @text="Delete" @onClick={{fn this.deleteCategory category}} />
</div>
</div>

{{#if category.subcategories}}
<ul class="ml-4">
{{#each category.subcategories as |subCategory|}}
<div class="flex justify-between items-center border-b border-gray-700 py-2">
<li>{{subCategory.name}}</li>
<div class="flex items-center space-x-2">
<Button @type="info" @size="sm" @icon="eye" @text="Add subcategories" @onClick={{fn this.addSubCategory subCategory}} />
<Button @type="danger" @size="sm" @icon="trash" @text="Delete" @onClick={{fn this.deleteCategory subCategory}} />
</div>
</div>
{{/each}}
</ul>
{{/if}}
{{/each}}
</ul>
</div>
</ContentPanel>
139 changes: 139 additions & 0 deletions addon/components/admin/product-category.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
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;

constructor() {
super(...arguments);
this.category = this.args.category;
this.fetchCategoryHierarchy();
}

@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.fetchCategoryHierarchy();
});
},
});
}

@action async fetchCategoryHierarchy() {
const allCategories = await this.store.query('category', {
for: 'pallet_product',
with_subcategories: true,
});

this.categories = allCategories.filter((category) => !category.parent);
this.categories.forEach((parentCategory) => {
parentCategory.subcategories = allCategories.filter((subcategory) => subcategory.parent?.id === parentCategory.id);
});
}

@action async addSubCategory(parentCategory) {
const subCategory = this.store.createRecord('category', {
parent: parentCategory,
for: 'pallet_product',
});

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/${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: async (modal) => {
modal.startLoading();

try {
await subCategory.save();
this.notifications.success('New subcategory created.');
await this.fetchCategoryHierarchy();
} catch (error) {
this.notifications.error('Error creating subcategory.');
console.error('Error creating subcategory:', error);
}
},
});
}

@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.fetchCategoryHierarchy();
} catch (error) {
this.notifications.error('Error deleting category.');
console.error('Error deleting category:', error);
}
}
}
}
55 changes: 55 additions & 0 deletions addon/components/batch-form-panel.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<Overlay
@onLoad={{this.setOverlayContext}}
@position="right"
@noBackdrop={{true}}
@fullHeight={{true}}
@isResizeble={{or this.isResizable @isResizable}}
@width={{or this.width @width "600px"}}
>
<Overlay::Header
@title={{if this.batch.public_id this.batch.name "Add Batch"}}
@status={{this.batch.public_id}}
@hideStatusDot={{true}}
@createdAt={{this.batch.createdAt}}
@titleWrapperClass="leading-5"
>
<div class="flex flex-1 justify-end">
<Button
@icon={{if this.batch.id "save" "check"}}
@type="primary"
@text={{if this.batch.id "Save Batch" "Add Batch"}}
@onClick={{this.save}}
@wrapperClass="mr-2"
/>
{{#if this.batch.id}}
<Button @type="default" @icon="batch" @helpText="View batch details" @onClick={{this.onViewDetails}} @wrapperClass="mr-2" />
{{/if}}
<Button @type="default" @icon="times" @helpText={{if this.batch.id "Cancel edit batch" "Cancel add batch"}} @onClick={{this.onPressCancel}} />
</div>
</Overlay::Header>

<Overlay::Body @wrapperClass="new-service-rate-overlay-body px-4 space-y-4 pt-4" @increaseInnerBodyHeightBy={{1000}}>
<div class="grid grid-cols-1 text-xs dark:text-gray-100">
<InputGroup @name="Product">
<ModelSelect
@modelName="pallet-product"
@selectedModel={{this.batch.product}}
@placeholder="Select Product"
@triggerClass="form-select form-input"
@infiniteScroll={{false}}
@renderInPlace={{true}}
@onChange={{fn (mut this.batch.product)}}
@onChangeId={{fn (mut this.batch.product_uuid)}}
as |model|
>
{{model.name}}
</ModelSelect>
</InputGroup>
<InputGroup @name="Quantity" @type="number" @value={{this.batch.quantity}} />
<InputGroup @name="Batch Number" @type="number" @value={{this.batch.batch_number}} />
<InputGroup @name="Batch Reason">
<Textarea @value={{this.batch.reason}} aria-label="Reason" class="w-full form-input" placeholder="Reason" rows={{5}} />
</InputGroup>
</div>
</Overlay::Body>
</Overlay>
128 changes: 128 additions & 0 deletions addon/components/batch-form-panel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import contextComponentCallback from '../utils/context-component-callback';
import applyContextComponentArguments from '../utils/apply-context-component-arguments';

export default class BatchFormPanelComponent extends Component {
/**
* @service store
*/
@service store;

/**
* @service notifications
*/
@service notifications;

/**
* @service hostRouter
*/
@service hostRouter;

/**
* @service loader
*/
@service loader;

/**
* @service contextPanel
*/
@service contextPanel;

/**
* Overlay context.
* @type {any}
*/
@tracked context;

/**
* Indicates whether the component is in a loading state.
* @type {boolean}
*/
@tracked isLoading = false;

/**
* Fuel Report status
* @type {Array}
*/
@tracked statusOptions = ['draft', 'pending-approval', 'approved', 'rejected', 'revised', 'submitted', 'in-review', 'confirmed', 'processed', 'archived', 'cancelled'];

/**
* Constructs the component and applies initial state.
*/
constructor() {
super(...arguments);
this.batch = this.args.batch;
applyContextComponentArguments(this);
}

/**
* Sets the overlay context.
*
* @action
* @param {OverlayContextObject} overlayContext
*/
@action setOverlayContext(overlayContext) {
this.context = overlayContext;
contextComponentCallback(this, 'onLoad', ...arguments);
}

/**
* Saves the fuel report changes.
*
* @action
* @returns {Promise<any>}
*/
@action save() {
const { batch } = this;

this.loader.showLoader('.next-content-overlay-panel-container', { loadingMessage: 'Saving batch...', preserveTargetPosition: true });
this.isLoading = true;

contextComponentCallback(this, 'onBeforeSave', batch);

try {
return batch
.save()
.then((batch) => {
this.notifications.success(`Batch saved successfully.`);
contextComponentCallback(this, 'onAfterSave', batch);
})
.catch((error) => {
this.notifications.serverError(error);
})
.finally(() => {
this.loader.removeLoader('.next-content-overlay-panel-container ');
this.isLoading = false;
});
} catch (error) {
this.loader.removeLoader('.next-content-overlay-panel-container ');
this.isLoading = false;
}
}

/**
* View the details of the fuel-report.
*
* @action
*/
@action onViewDetails() {
const isActionOverrided = contextComponentCallback(this, 'onViewDetails', this.batch);

if (!isActionOverrided) {
this.contextPanel.focus(this.batch, 'viewing');
}
}

/**
* Handles cancel button press.
*
* @action
* @returns {any}
*/
@action onPressCancel() {
return contextComponentCallback(this, 'onPressCancel', this.batch);
}
}
Loading

0 comments on commit 3618598

Please sign in to comment.