Skip to content

Commit

Permalink
Pallet Main Folder Structure
Browse files Browse the repository at this point in the history
  • Loading branch information
TemuulenBM committed Nov 10, 2023
1 parent ce0cf17 commit 6d0de1b
Show file tree
Hide file tree
Showing 223 changed files with 4,200 additions and 27 deletions.
Empty file.
5 changes: 5 additions & 0 deletions addon/components/context-panel.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{{#if this.contextPanel.currentContextRegistry}}
{{#let this.contextPanel.currentContext this.contextPanel.currentContextRegistry this.contextPanel.currentContextComponentArguments as |model registry dynamicArgs|}}
{{component registry.component context=model dynamicArgs=dynamicArgs onPressCancel=this.contextPanel.clear options=this.contextPanel.contextOptions}}
{{/let}}
{{/if}}
6 changes: 6 additions & 0 deletions addon/components/context-panel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Component from '@glimmer/component';
import { inject as service } from '@ember/service';

export default class ContextPanelComponent extends Component {
@service contextPanel;
}
72 changes: 72 additions & 0 deletions addon/components/product-form-panel.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<Overlay
@onLoad={{this.setOverlayContext}}
@position="right"
@noBackdrop={{true}}
@fullHeight={{true}}
@isResizeble={{or this.isResizable @isResizable}}
@width={{or this.width @width "600px"}}
>
<Overlay::Header @hideLeftSection={{true}} @actionsWrapperClass="flex-1 flex-col py-3" class="h-auto-i min-h-[127px]">
<div class="flex flex-row items-center justify-between w-full mb-4">
<div class="flex flex-1 space-x-2">
{{#if this.product.id}}
<Button @type="default" @icon="id-card" @helpText="View product details" @onClick={{this.onViewDetails}} />
{{/if}}
</div>
<div class="flex flex-1 justify-end">
<div class="mr-2">
<Button @icon={{if this.product.id "save" "check"}} @type="primary" @text={{if this.product.id "Save Product" "Create Product"}} @onClick={{this.save}} />
</div>
<Button @type="default" @icon="times" @helpText={{if this.product.id "Cancel edit product" "Cancel new product"}} @onClick={{this.onPressCancel}} />
</div>
</div>
<div class="flex flex-row justify-between w-full">
<div class="flex flex-col flex-1 w-3/4">
<div class="flex flex-row">
<div class="w-14">
<div class="w-12 h-12 flex items-center justify-start relative hover:bg-gray-100 transition-all rounded-lg overflow-hidden">
<img src={{this.product.photo_url}} alt={{this.product.name}} height="48" width="48" class="h-12 w-12 rounded-lg shadow-sm" />
<Attach::Tooltip @class="clean" @animation="scale" @placement="top">
<InputInfo @text={{this.product.public_id}} />
</Attach::Tooltip>
<div class="absolute inset-0 flex items-center justify-center opacity-0 hover:opacity-100 transition-opacity bg-gray-600 bg-opacity-50 rounded-lg">
<UploadButton
@name="photos"
@accept="image/*"
@onFileAdded={{this.onUploadNewPhoto}}
@icon="upload"
@hideButtonText={{true}}
@labelClass="upload-avatar-label-overlay"
class="w-12 btn-reset"
/>
</div>
</div>
</div>
<div class="flex flex-col">
<h1 class="text-gray-900 dark:text-white text-2xl">
{{#if this.product.id}}
{{this.product.name}}
{{else}}
{{#if this.product.name}}
{{this.product.name}}
{{else}}
<span>New Product</span>
{{/if}}
{{/if}}
</h1>
<div class="-mt-1">
<div class="flex flex-row items-center">
<span class="text-sm dark:text-blue-400 text-blue-600">{{n-a this.product.title (smart-humanize this.product.type)}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="flex justify-end w-1/4">
<Badge @status={{this.product.status}} @type="info" @hideStatusDot={{true}} />
</div>
</div>
</Overlay::Header>

<Overlay::Body @wrapperClass="new-service-rate-overlay-body px-4 pt-4" @increaseInnerBodyHeightBy={{700}} />
</Overlay>
195 changes: 195 additions & 0 deletions addon/components/product-form-panel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
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 ProductFormPanelComponent extends Component {
/**
* @service store
*/
@service store;

/**
* @service fetch
*/
@service fetch;

/**
* @service currentUser
*/
@service currentUser;

/**
* @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;

/**
* All possible product types.
*
* @var {String}
*/
@tracked productTypeOptions = ['product', 'customer'];

/**
* All possible product status options.
*
* @var {String}
*/
@tracked productStatusOptions = ['pending', 'active', 'do-not-product', 'prospective', 'archived'];

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

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

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

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

contextComponentCallback(this, 'onBeforeSave', product);

try {
return product
.save()
.then((product) => {
this.notifications.success(`product (${product.name}) saved successfully.`);
contextComponentCallback(this, 'onAfterSave', product);
})
.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;
}
}

/**
* Uploads a new photo for the driver.
*
* @param {File} file
* @memberof DriverFormPanelComponent
*/
@action onUploadNewPhoto(file) {
this.fetch.uploadFile.perform(
file,
{
path: `uploads/${this.currentUser.companyId}/drivers/${this.product.id}`,
subject_uuid: this.product.id,
subject_type: `product`,
type: `product_photo`,
},
(uploadedFile) => {
this.product.setProperties({
photo_uuid: uploadedFile.id,
photo_url: uploadedFile.url,
photo: uploadedFile,
});
}
);
}

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

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

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

/**
* Uploads a file to the server for the product.
*
* @param {File} file
*/
uploadProductPhoto(file) {
this.fetch.uploadFile.perform(
file,
{
path: `uploads/${this.product.company_uuid}/products/${this.product.slug}`,
subject_uuid: this.product.id,
subject_type: 'product',
type: 'product_photo',
},
(uploadedFile) => {
this.product.setProperties({
photo_uuid: uploadedFile.id,
photo_url: uploadedFile.url,
photo: uploadedFile,
});
}
);
}
}
66 changes: 66 additions & 0 deletions addon/components/product-panel.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<Overlay
@onLoad={{this.setOverlayContext}}
@position="right"
@noBackdrop={{true}}
@fullHeight={{true}}
@isResizable={{or this.isResizable @isResizable}}
@width={{or this.width @width "600px"}}
>
<Overlay::Header @hideLeftSection={{true}} @actionsWrapperClass="flex-1 flex-col py-3" class="h-auto-i min-h-[127px]">
<div class="flex flex-row items-center justify-between w-full mb-4">
<div class="flex flex-1 space-x-2">
<Button @type="default" @icon="pen" @helpText="Edit product" @onClick={{this.onEdit}} />
</div>
<div class="flex flex-1 justify-end">
<Button @type="default" @icon="times" @helpText={{if this.product.id "Cancel edit product" "Cancel new product"}} @onClick={{this.onPressCancel}} />
</div>
</div>
<div class="flex flex-row justify-between w-full">
<div class="flex flex-col flex-1 w-3/4">
<div class="flex flex-row">
<div class="w-14 flex items-center justify-start">
<Image
src={{this.product.photo_url}}
@fallbackSrc={{config "defaultValues.productImage"}}
alt={{this.product.name}}
height="48"
width="48"
class="h-12 w-12 rounded-lg shadow-sm"
/>
<Attach::Tooltip @class="clean" @animation="scale" @placement="top">
<InputInfo @text={{this.product.public_id}} />
</Attach::Tooltip>
</div>
<div class="flex flex-col">
<h1 class="text-gray-900 dark:text-white text-2xl">{{this.product.name}}</h1>
<div class="-mt-1">
<div class="flex flex-row items-center">
<span class="text-sm dark:text-blue-400 text-blue-600">{{smart-humanize this.product.type}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="flex justify-end w-1/4">
<Badge @status={{this.product.public_id}} @type="info" @hideStatusDot={{true}} />
</div>
</div>
</Overlay::Header>
<Overlay::Body class="no-padding" @increaseInnerBodyHeightBy={{1000}}>
<div class="section-header-actions w-full overflow-x-scroll lg:overflow-x-auto">
<div class="ui-tabs mt-4">
<nav>
{{#each this.tabs as |tab|}}
<a href="javascript:;" class="ui-tab {{if (eq this.tab.slug tab.slug) 'active'}}" {{on "click" (fn this.onTabChanged tab.slug)}}>
<FaIcon @icon={{tab.icon}} class="mr-1" />
<span>{{tab.title}}</span>
</a>
{{/each}}
</nav>
</div>
</div>
<div class="tab-content tab-{{this.tab.slug}}">
{{component this.tab.component product=this.product tabOptions=this.tab options=this.tab.componentParams}}
</div>
</Overlay::Body>
</Overlay>
Loading

0 comments on commit 6d0de1b

Please sign in to comment.