-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from fleetbase/dev-v0.3.3
v0.3.3
- Loading branch information
Showing
48 changed files
with
2,148 additions
and
916 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<Drawer @isMinimized={{true}} @notchEnabled={{true}} @onLoad={{this.setDrawerContext}}> | ||
<div class="ui-tabs pt-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 class="tab-content tab-{{this.tab.slug}}"> | ||
{{#if this.drawer}} | ||
{{component this.tab.component drivers=@drivers vehicles=@vehicles places=@places drawer=this.drawer liveMap=@liveMap tabOptions=this.tab options=this.tab.componentParams}} | ||
{{/if}} | ||
</div> | ||
</Drawer> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import Component from '@glimmer/component'; | ||
import { tracked } from '@glimmer/tracking'; | ||
import { action } from '@ember/object'; | ||
import { inject as service } from '@ember/service'; | ||
import { isArray } from '@ember/array'; | ||
import contextComponentCallback from '../utils/context-component-callback'; | ||
import applyContextComponentArguments from '../utils/apply-context-component-arguments'; | ||
import LiveMapDrawerVehicleListingComponent from './live-map-drawer/vehicle-listing'; | ||
import LiveMapDrawerDriverListingComponent from './live-map-drawer/driver-listing'; | ||
import LiveMapDrawerPlaceListingComponent from './live-map-drawer/place-listing'; | ||
|
||
export default class LiveMapDrawerComponent extends Component { | ||
/** | ||
* Universe service for managing global data and settings. | ||
* | ||
* @type {Service} | ||
*/ | ||
@service universe; | ||
|
||
/** | ||
* The current active tab. | ||
* | ||
* @type {Object} | ||
* @tracked | ||
*/ | ||
@tracked tab; | ||
|
||
/** | ||
* The drawer component context api. | ||
* | ||
* @type {Object} | ||
* @tracked | ||
*/ | ||
@tracked drawer; | ||
|
||
/** | ||
* Returns the array of tabs available for the drawer. | ||
* | ||
* @type {Array} | ||
*/ | ||
get tabs() { | ||
const registeredTabs = this.universe.getMenuItemsFromRegistry('component:live-map-drawer'); | ||
const defaultTabs = [ | ||
this.universe._createMenuItem('Vehicles', null, { icon: 'car', component: LiveMapDrawerVehicleListingComponent }), | ||
this.universe._createMenuItem('Drivers', null, { icon: 'id-card', component: LiveMapDrawerDriverListingComponent }), | ||
this.universe._createMenuItem('Places', null, { icon: 'building', component: LiveMapDrawerPlaceListingComponent }), | ||
]; | ||
|
||
if (isArray(registeredTabs)) { | ||
return [...defaultTabs, ...registeredTabs]; | ||
} | ||
|
||
return defaultTabs; | ||
} | ||
|
||
/** | ||
* Initializes the vehicle panel component. | ||
*/ | ||
constructor() { | ||
super(...arguments); | ||
this.tab = this.getTabUsingSlug(this.args.tab); | ||
applyContextComponentArguments(this); | ||
} | ||
|
||
/** | ||
* Sets the drawer component context api. | ||
* | ||
* @param {Object} drawerApi | ||
* @memberof LiveMapDrawerComponent | ||
*/ | ||
@action setDrawerContext(drawerApi) { | ||
this.drawer = drawerApi; | ||
|
||
if (typeof this.args.onDrawerReady === 'function') { | ||
this.args.onDrawerReady(...arguments); | ||
} | ||
} | ||
|
||
/** | ||
* Handles changing the active tab. | ||
* | ||
* @method | ||
* @param {String} tab - The new tab to switch to. | ||
* @action | ||
*/ | ||
@action onTabChanged(tab) { | ||
this.tab = this.getTabUsingSlug(tab); | ||
contextComponentCallback(this, 'onTabChanged', tab); | ||
} | ||
|
||
/** | ||
* Finds and returns a tab based on its slug. | ||
* | ||
* @param {String} tabSlug - The slug of the tab. | ||
* @returns {Object|null} The found tab or null. | ||
*/ | ||
getTabUsingSlug(tabSlug) { | ||
if (tabSlug) { | ||
return this.tabs.find(({ slug }) => slug === tabSlug); | ||
} | ||
|
||
return this.tabs[0]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<div class="flex flex-row items-center px-5 py-2 border-b border-gray-200 dark:border-gray-700"> | ||
<div> | ||
<Input @value={{this.query}} {{on "input" this.performSearch}} @type="text" class="form-input form-input-sm w-60" placeholder="Filter drivers by keyword..." /> | ||
</div> | ||
</div> | ||
<Table @rows={{this.drivers}} @columns={{this.columns}} @onSetup={{fn (mut this.table)}} /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
import Component from '@glimmer/component'; | ||
import { tracked } from '@glimmer/tracking'; | ||
import { inject as service } from '@ember/service'; | ||
import { action } from '@ember/object'; | ||
import { isBlank } from '@ember/utils'; | ||
import { later } from '@ember/runloop'; | ||
import getWithDefault from '@fleetbase/ember-core/utils/get-with-default'; | ||
|
||
/** | ||
* Represents a live map drawer driver listing component. | ||
* This component is responsible for displaying and interacting with a list of drivers on a live map. | ||
* | ||
* @extends Component | ||
*/ | ||
export default class LiveMapDrawerDriverListingComponent extends Component { | ||
/** | ||
* Service for managing context panels within the application. | ||
* @service | ||
*/ | ||
@service contextPanel; | ||
|
||
/** | ||
* Service for triggering notifications. | ||
* @service | ||
*/ | ||
@service notifications; | ||
|
||
/** | ||
* Service for triggering notifications. | ||
* @service | ||
*/ | ||
@service hostRouter; | ||
|
||
/** | ||
* Service for CRUD operations. | ||
* @service | ||
*/ | ||
@service crud; | ||
|
||
/** | ||
* The list of drivers to display, tracked for reactivity. | ||
* @tracked | ||
*/ | ||
@tracked drivers = []; | ||
|
||
/** | ||
* The internal list of drivers used for searching, tracked for reactivity. | ||
* @tracked | ||
*/ | ||
@tracked _drivers = []; | ||
|
||
/** | ||
* The current search query, tracked for reactivity. | ||
* @tracked | ||
*/ | ||
@tracked query = ''; | ||
|
||
/** | ||
* The table component reference, tracked for reactivity. | ||
* @tracked | ||
*/ | ||
@tracked table = null; | ||
|
||
/** | ||
* The configuration for table columns including details like label, valuePath, and cellComponent, | ||
* tracked for reactivity. | ||
* @tracked | ||
*/ | ||
@tracked columns = [ | ||
{ | ||
label: 'Driver', | ||
valuePath: 'name', | ||
photoPath: 'photo_url', | ||
width: '100px', | ||
cellComponent: 'cell/driver-name', | ||
onClick: this.focus, | ||
}, | ||
{ | ||
label: 'Location', | ||
valuePath: 'location', | ||
width: '80px', | ||
cellComponent: 'table/cell/point', | ||
onClick: this.locate, | ||
}, | ||
{ | ||
label: 'Current Job', | ||
valuePath: 'current_job_id', | ||
width: '80px', | ||
cellComponent: 'table/cell/anchor', | ||
onClick: this.job, | ||
}, | ||
{ | ||
label: 'Status', | ||
valuePath: 'status', | ||
cellComponent: 'table/cell/status', | ||
width: '60px', | ||
}, | ||
{ | ||
label: 'Last Seen', | ||
valuePath: 'updatedAgo', | ||
width: '60px', | ||
}, | ||
{ | ||
label: '', | ||
cellComponent: 'table/cell/dropdown', | ||
ddButtonText: false, | ||
ddButtonIcon: 'ellipsis-h', | ||
ddButtonIconPrefix: 'fas', | ||
ddMenuLabel: 'Actions', | ||
cellClassNames: 'overflow-visible', | ||
wrapperClass: 'flex items-center justify-end mx-2', | ||
width: '90px', | ||
actions: [ | ||
{ | ||
label: 'View driver details...', | ||
fn: this.focus, | ||
}, | ||
{ | ||
label: 'Edit driver...', | ||
fn: (driver) => { | ||
return this.focus(driver, 'editing'); | ||
}, | ||
}, | ||
{ | ||
label: 'Locate driver...', | ||
fn: this.locate, | ||
}, | ||
{ | ||
label: 'Delete driver...', | ||
fn: this.delete, | ||
}, | ||
], | ||
sortable: false, | ||
filterable: false, | ||
resizable: false, | ||
searchable: false, | ||
}, | ||
]; | ||
|
||
/** | ||
* Initializes the component with drivers passed in from `this.args` and sets up the live map reference. | ||
*/ | ||
constructor() { | ||
super(...arguments); | ||
this.drivers = getWithDefault(this.args, 'drivers', []); | ||
this._drivers = [...this.drivers]; | ||
this.liveMap = this.args.liveMap; | ||
} | ||
|
||
/** | ||
* Filters the drivers list based on a query. | ||
* | ||
* @param {string} query - The query string to filter the drivers list. | ||
*/ | ||
search(query) { | ||
if (typeof query !== 'string' && !isBlank(query)) { | ||
return; | ||
} | ||
|
||
this.drivers = [ | ||
...this._drivers.filter((driver) => { | ||
return typeof driver.name === 'string' && driver.name.toLowerCase().includes(query.toLowerCase()); | ||
}), | ||
]; | ||
} | ||
|
||
/** | ||
* Action to perform a search based on the input event's value. | ||
* | ||
* @param {Event} event - The input event containing the search value. | ||
*/ | ||
@action performSearch({ target: { value } }) { | ||
this.search(value); | ||
} | ||
|
||
/** | ||
* Action to focus on a driver in the live map and context panel. | ||
* | ||
* @param {object} driver - The driver object to focus on. | ||
* @param {string} intent - The intent for focusing, default is 'viewing'. | ||
*/ | ||
@action focus(driver, intent = 'viewing') { | ||
if (this.liveMap) { | ||
this.liveMap.focusLayerByRecord(driver, 16, { | ||
onAfterFocusWithRecord: () => { | ||
later( | ||
this, | ||
() => { | ||
this.contextPanel.focus(driver, intent); | ||
}, | ||
600 * 2 | ||
); | ||
}, | ||
}); | ||
} else { | ||
this.contextPanel.focus(driver, intent); | ||
} | ||
} | ||
|
||
/** | ||
* Action to locate a driver on the live map. | ||
* | ||
* @param {object} driver - The driver object to locate. | ||
*/ | ||
@action locate(driver) { | ||
if (this.liveMap) { | ||
this.liveMap.focusLayerByRecord(driver, 18); | ||
} else { | ||
this.notifications.warning('Unable to locate driver.'); | ||
} | ||
} | ||
|
||
/** | ||
* Transitino to view the drivers current job | ||
* | ||
* @param {DriverModel} driver | ||
* @memberof LiveMapDrawerDriverListingComponent | ||
*/ | ||
@action job(driver) { | ||
if (driver.current_job_id) { | ||
this.hostRouter.transitionTo('console.fleet-ops.operations.orders.index.view', driver.current_job_id); | ||
} | ||
} | ||
|
||
/** | ||
* Action to delete a driver from the list and perform cleanup. | ||
* | ||
* @param {object} driver - The driver object to delete. | ||
* @param {object} options - Additional options for the delete operation. | ||
*/ | ||
@action delete(driver, options = {}) { | ||
this.crud.delete(driver, { | ||
onSuccess: () => { | ||
this._drivers.removeObject(driver); | ||
this.drivers.removeObject(driver); | ||
}, | ||
...options, | ||
}); | ||
} | ||
} |
Oops, something went wrong.