Skip to content

Commit

Permalink
improved responsiveness, additional utility and helpers, migrated das…
Browse files Browse the repository at this point in the history
…hboard components and services
  • Loading branch information
roncodes committed Sep 10, 2024
1 parent 280301e commit 3e0a43d
Show file tree
Hide file tree
Showing 56 changed files with 1,282 additions and 99 deletions.
2 changes: 1 addition & 1 deletion addon/components/chat-container.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="chat-container" ...attributes>
<div class="chat-container {{if (media 'isMobile') 'is-mobile'}}" ...attributes>
{{#each this.chat.openChannels as |chatChannel|}}
<ChatWindow @channel={{chatChannel}} />
{{/each}}
Expand Down
8 changes: 4 additions & 4 deletions addon/components/chat-tray.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
@defaultClass={{@wrapperClass}}
@onOpen={{this.unlockAudio}}
@onClose={{@onClose}}
@calculatePosition={{this.calculatePosition}}
@verticalPosition={{@verticalPosition}}
@horizontalPosition={{@horizontalPosition}}
@renderInPlace={{true}}
@initiallyOpened={{@initiallyOpened}}
@renderInPlace={{or @renderInPlace (not (media "isMobile"))}}
as |dd|
>
<dd.Trigger class={{@triggerClass}}>
<dd.Trigger class="chat-tray-panel-trigger {{@triggerClass}} {{if (media 'isMobile') 'is-mobile'}}">
<div class="next-org-button-trigger chat-tray-icon flex-shrink-0 {{if dd.isOpen 'is-open'}}">
<FaIcon @icon="message" />
{{#if this.unreadCount}}
<div class="chat-tray-unread-notifications-badge">{{this.unreadCount}}</div>
{{/if}}
</div>
</dd.Trigger>
<dd.Content class="chat-tray-panel-container">
<dd.Content class="chat-tray-panel-container {{@contentClass}} {{if (media 'isMobile') 'is-mobile'}}">
<div class="chat-tray-panel">
<div class="p-4">
<Button @type="primary" @text="Start Chat" @icon="paper-plane" @onClick={{dropdown-fn dd this.startChat}} />
Expand Down
22 changes: 22 additions & 0 deletions addon/components/chat-tray.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import { isNone } from '@ember/utils';
import { task } from 'ember-concurrency';
import calculatePosition from 'ember-basic-dropdown/utils/calculate-position';
import noop from '../utils/noop';

export default class ChatTrayComponent extends Component {
Expand All @@ -13,6 +14,7 @@ export default class ChatTrayComponent extends Component {
@service store;
@service modalsManager;
@service currentUser;
@service media;
@tracked channels = [];
@tracked unreadCount = 0;
@tracked notificationSound = new Audio('/sounds/message-notification-sound.mp3');
Expand All @@ -29,6 +31,26 @@ export default class ChatTrayComponent extends Component {
});
}

/**
* Calculate dropdown content position.
*
* @param {HTMLElement} trigger
* @param {HTMLElement} content
* @return {Object}
* @memberof ChatTrayComponent
*/
@action calculatePosition(trigger, content) {
if (this.media.isMobile) {
content.classList.add('is-mobile');
const triggerRect = trigger.getBoundingClientRect();
const top = triggerRect.height + triggerRect.top;

return { style: { left: '0px', right: '0px', top, width: '100%' } };
}

return calculatePosition(...arguments);
}

willDestroy() {
this.chat.off('chat.feed_updated', this.reloadChannelWithDelay.bind(this));
super.willDestroy(...arguments);
Expand Down
100 changes: 100 additions & 0 deletions addon/components/dashboard.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<div class="fleetbase-dashboard-grid" ...attributes>
<div class="left-section {{@leftHeaderWrapperClass}}">
<h1 class="text-lg font-bold">{{this.dashboard.currentDashboard.name}}</h1>
</div>
<div class="fleetbase-dashboard-actions right-section {{@rightHeaderWrapperClass}} flex items-center">
<div class="fleetbase-model-select fleetbase-power-select ember-model-select h-10">
<DropdownButton
class="h-10"
@text={{if this.dashboard.currentDashboard.name this.dashboard.currentDashboard.name (t "component.dashboard.select-dashboard")}}
@textClass="text-sm mr-2"
@buttonClass="flex-row-reverse w-44 justify-between"
@icon="caret-down"
@iconClass="mr-0i"
@size="sm"
@iconPrefix="fas"
@triggerClass="hidden md:flex"
as |dd|
>
<div class="next-dd-menu mt-1 mx-0" aria-labelledby="user-menu">
<div class="p-1">
{{#each this.dashboard.dashboards as |dashboard|}}
<a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.selectDashboard dashboard)}}>
<div class="flex-1 flex flex-row items-center">
<div class="w-6">
<FaIcon @icon="desktop" />
</div>
<span>{{dashboard.name}}</span>
</div>
<div>
{{#if (eq this.dashboard.currentDashboard.id dashboard.id)}}
<FaIcon @icon="check" class="text-green-500" />
{{/if}}
</div>
</a>
{{/each}}
</div>
</div>
</DropdownButton>
</div>

<div class="ml-2 relative h-10">
<DropdownButton class="h-10" @icon="ellipsis-h" @size="sm" @iconPrefix="fas" @triggerClass="hidden md:flex" as |dd|>
<div class="next-dd-menu mt-1 mx-0" aria-labelledby="user-menu">
<div class="p-1">
<a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.createDashboard)}}>
<div class="w-6">
<FaIcon @icon="add" />
</div>
<span>{{t "component.dashboard.create-new-dashboard"}}</span>
</a>

{{#unless (eq this.dashboard.currentDashboard.user_uuid "system")}}
<a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.onChangeEdit true)}}>
<div class="w-6">
<FaIcon @icon="edit" />
</div>
<span>{{t "component.dashboard.edit-layout"}}</span>
</a>
<a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.onAddingWidget true)}}>
<div class="w-6">
<FaIcon @icon="add" />
</div>
<span>{{t "component.dashboard.add-widgets"}}</span>
</a>

<a href="javascript:;" class="next-dd-item" {{on "click" (dropdown-fn dd this.deleteDashboard this.dashboard.currentDashboard)}}>
<div class="w-6">
<FaIcon @icon="trash" />
</div>
<span>{{t "component.dashboard.delete-dashboard"}}</span>
</a>
{{/unless}}

</div>
</div>
</DropdownButton>
</div>
{{#if this.dashboard.isEditingDashboard}}
<div class="ml-2 h-10">
<Button @type="magic" @icon="save" @helpText={{t "component.dashboard.save-dashboard"}} @onClick={{fn this.onChangeEdit false}} class="h-10" />
</div>
{{/if}}
</div>
</div>

<div class="px-10 {{@createWrapperClass}}">
<Dashboard::Create @isEdit={{this.dashboard.isEditingDashboard}} @isAddingWidget={{this.dashboard.isAddingWidget}} @dashboard={{this.dashboard.currentDashboard}} />
{{#if this.dashboard.isAddingWidget}}
<EmberWormhole @to="application-root-wormhole">
<Dashboard::WidgetPanel
@isOpen={{this.dashboard.isAddingWidget}}
@onLoad={{this.setWidgetSelectorPanelContext}}
@dashboard={{this.dashboard.currentDashboard}}
@defaultDashboardId={{@defaultDashboardId}}
@onClose={{fn this.onAddingWidget false}}
class={{@widgetPanelClass}}
/>
</EmberWormhole>
{{/if}}
</div>
113 changes: 113 additions & 0 deletions addon/components/dashboard.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';

/**
* DashboardComponent for managing dashboards in an Ember application.
* This component handles actions such as selecting, creating, deleting dashboards,
* and managing widget selectors and dashboard editing states.
*
* @extends Component
*/
export default class DashboardComponent extends Component {
@service store;
@service intl;
@service notifications;
@service modalsManager;
@service fetch;
@service dashboard;
@service universe;

/**
* Creates an instance of DashboardComponent.
* @memberof DashboardComponent
*/
constructor(owner, { defaultDashboardId = 'dashboard', defaultDashboardName = 'Default Dashboard', showPanelWhenZeroWidgets = false }) {
super(...arguments);
this.dashboard.showPanelWhenZeroWidgets = showPanelWhenZeroWidgets;
this.dashboard.loadDashboards.perform(defaultDashboardId, defaultDashboardName);
}

/**
* Action to select a dashboard.
* @param {Object} dashboard - The dashboard to be selected.
*/
@action selectDashboard(dashboard) {
this.dashboard.selectDashboard.perform(dashboard);
}

/**
* Sets the context for the widget selector panel.
* @param {Object} widgetSelectorContext - The context object for the widget selector.
*/
@action setWidgetSelectorPanelContext(widgetSelectorContext) {
this.widgetSelectorContext = widgetSelectorContext;
}

/**
* Creates a new dashboard.
* @param {Object} dashboard - The dashboard to be created.
* @param {Object} [options={}] - Optional parameters for dashboard creation.
*/
@action createDashboard(dashboard, options = {}) {
this.modalsManager.show('modals/create-dashboard', {
title: this.intl.t('component.dashboard.create-a-new-dashboard'),
acceptButtonText: this.intl.t('component.dashboard.confirm-create-dashboard'),
confirm: async (modal, done) => {
modal.startLoading();

// Get the name from the modal options
const { name } = modal.getOptions();

await this.dashboard.createDashboard.perform(name);
done();
},
...options,
});
}

/**
* Deletes a dashboard.
* @param {Object} dashboard - The dashboard to be deleted.
* @param {Object} [options={}] - Optional parameters for dashboard deletion.
*/
@action deleteDashboard(dashboard, options = {}) {
if (this.dashboard.dashboards?.length === 1) {
return this.notifications.error(this.intl.t('component.dashboard.you-cannot-delete-this-dashboard'));
}

this.modalsManager.confirm({
title: this.intl.t('component.dashboard.are-you-sure-you-want-delete-dashboard', { dashboardName: dashboard.name }),
confirm: async (modal, done) => {
modal.startLoading();
await this.dashboard.deleteDashboard.perform(dashboard);
done();
},
...options,
});
}

/**
* Action to handle the addition of a widget.
* @param {boolean} [state=true] - The state to set for adding a widget.
*/
@action onAddingWidget(state = true) {
this.dashboard.onAddingWidget(state);
}

/**
* Sets the current dashboard.
* @param {Object} dashboard - The dashboard to be set as current.
*/
@action setCurrentDashboard(dashboard) {
this.dashboard.setCurrentDashboard.perform(dashboard);
}

/**
* Changes the editing state of the dashboard.
* @param {boolean} [state=true] - The state to set for editing the dashboard.
*/
@action onChangeEdit(state = true) {
this.dashboard.onChangeEdit(state);
}
}
16 changes: 16 additions & 0 deletions addon/components/dashboard/create.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="fleetbase-dashboard-grid" ...attributes>
<GridStack @options={{this.gridOptions}} @onChange={{this.onChangeGrid}}>
{{#each @dashboard.widgets as |widget|}}
{{#if (component-resolvable widget.component)}}
<GridStackItem id={{widget.id}} @options={{spread-widget-options (hash id=widget.id options=widget.grid_options)}} class="relative">
{{component widget.component options=widget.options}}
{{#if @isEdit}}
<div class="absolute top-2 right-2">
<Button @type="default" @icon="trash" @helpText={{"Remove widget from the dashboard"}} @onClick={{fn this.removeWidget widget}} />
</div>
{{/if}}
</GridStackItem>
{{/if}}
{{/each}}
</GridStack>
</div>
Loading

0 comments on commit 3e0a43d

Please sign in to comment.