Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion addon/components/fuel-integration/hub.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</div>
<div class="flex flex-shrink-0 items-center gap-2 whitespace-nowrap">
<Button @icon="refresh" @size="sm" @helpText={{t "common.reload"}} @onClick={{@onRefresh}} />
<Button @icon="plus" @text="Connect Integration" @type="primary" @size="sm" @onClick={{this.createIntegration}} />
<Button @icon="plus" @text="Connect Integration" @type="primary" @size="sm" @permission="fleet-ops create fuel-provider-connection" @onClick={{this.createIntegration}} />
</div>
</div>
</section>
Expand Down
48 changes: 33 additions & 15 deletions addon/components/layout/fleet-ops-sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,14 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
this.createItem('menu.contacts', 'address-book', 'management.contacts', 'fleet-ops list contact', 'fleet-ops see contact'),
this.createItem('menu.places', 'location-dot', 'management.places', 'fleet-ops list place', 'fleet-ops see place'),
this.createItem('menu.fuel-reports', 'gas-pump', 'management.fuel-reports', 'fleet-ops list fuel-report', 'fleet-ops see fuel-report'),
this.createItem('menu.fuel-transactions', 'credit-card', 'management.fuel-transactions', 'fleet-ops list fuel-report', 'fleet-ops see fuel-report'),
this.createItem('menu.fuel-transactions', 'credit-card', 'management.fuel-transactions', 'fleet-ops list fuel-provider-transaction', 'fleet-ops see fuel-provider-transaction'),
this.createItem('menu.issues', 'triangle-exclamation', 'management.issues', 'fleet-ops list issue', 'fleet-ops see issue'),
]);
}

get maintenanceItems() {
return this.withRegistryItems('maintenance', [
this.createHubItem('Maintenance Hub', 'wrench', 'maintenance.index', 'fleet-ops list maintenance-schedule', 'fleet-ops see maintenance-schedule', [
this.createHubItem('Maintenance Hub', 'wrench', 'maintenance.index', 'fleet-ops list work-order', 'fleet-ops see work-order', [
'maintenance hub',
'service readiness',
'maintenance control panel',
Expand All @@ -182,7 +182,9 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
get connectivityItems() {
return this.withRegistryItems('connectivity', [
this.createHubItem(this.intl.t('menu.telematics'), 'satellite-dish', 'connectivity.telematics', 'fleet-ops list telematic', 'fleet-ops see telematic', ['connectivity hub']),
this.createItem('menu.fuel-providers', 'gas-pump', 'connectivity.fuel-providers', 'fleet-ops list fuel-report', 'fleet-ops see fuel-report', ['fuel integrations']),
this.createItem('menu.fuel-providers', 'gas-pump', 'connectivity.fuel-providers', 'fleet-ops list fuel-provider-connection', 'fleet-ops see fuel-provider-connection', [
'fuel integrations',
]),
this.createItem('menu.devices', 'hard-drive', 'connectivity.devices', 'fleet-ops list device', 'fleet-ops see device'),
this.createItem('menu.sensors', 'temperature-full', 'connectivity.sensors', 'fleet-ops list sensor', 'fleet-ops see sensor'),
this.createItem('menu.events', 'stream', 'connectivity.events', 'fleet-ops list device-event', 'fleet-ops see device-event'),
Expand All @@ -191,18 +193,14 @@ export default class LayoutFleetOpsSidebarComponent extends Component {

get analyticsItems() {
return this.withRegistryItems('analytics', [
this.createHubItem('Dashboard', 'chart-line', 'analytics.index', 'iam list report', 'fleet-ops see report', ['dashboard', 'fleetops dashboard', 'metrics']),
this.createItem('menu.reports', 'file-import', 'analytics.reports', 'iam list report', 'fleet-ops see report'),
this.createHubItem('Dashboard', 'chart-line', 'analytics.index', 'fleet-ops view analytics', 'fleet-ops see analytics', ['dashboard', 'fleetops dashboard', 'metrics']),
this.createItem('menu.reports', 'file-import', 'analytics.reports', 'iam list report', 'iam see report'),
]);
}

get settingsItems() {
return this.withRegistryItems('settings', [
this.createHubItem('Settings Hub', 'sliders', 'settings.index', 'fleet-ops view navigator-settings', 'fleet-ops see navigator-settings', [
'settings hub',
'configuration dashboard',
'setup focus',
]),
this.createHubItem('Settings Hub', 'sliders', 'settings.index', null, null, ['settings hub', 'configuration dashboard', 'setup focus']),
this.createItem('menu.navigator-app', 'location-arrow', 'settings.navigator-app', 'fleet-ops view navigator-settings', 'fleet-ops see navigator-settings'),
this.createItem('menu.map', 'map', 'settings.map', 'fleet-ops view map-settings', 'fleet-ops see map-settings'),
this.createItem('menu.payments', 'cash-register', 'settings.payments', 'fleet-ops view payments', 'fleet-ops see payments'),
Expand All @@ -211,8 +209,8 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
this.createItem('menu.orchestrator', 'circle-nodes', 'settings.orchestrator', 'fleet-ops view routing-settings', 'fleet-ops see routing-settings'),
this.createItem('menu.scheduling', 'calendar-days', 'settings.scheduling', 'fleet-ops view scheduling-settings', 'fleet-ops see scheduling-settings'),
this.createItem('menu.telematics-settings', 'database', 'settings.telematics', 'fleet-ops view telematics-settings', 'fleet-ops see telematics-settings'),
this.createItem('menu.custom-fields', 'pen-to-square', 'settings.custom-fields', 'fleet-ops view custom-field', 'fleet-ops see custom-field'),
this.createItem('menu.avatars', 'icons', 'settings.avatars', 'fleet-ops view avatar', 'fleet-ops see avatar'),
this.createItem('menu.custom-fields', 'pen-to-square', 'settings.custom-fields', 'fleet-ops list custom-field', 'fleet-ops see custom-field'),
this.createItem('menu.avatars', 'icons', 'settings.avatars', 'fleet-ops list avatar', 'fleet-ops see avatar'),
]);
}

Expand Down Expand Up @@ -266,18 +264,36 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
}

createBranch({ id, label, icon, route, defaultRoute, requiresVisibleChildren = false, children, keywords = [] }) {
const visibleChildren = children.filter((item) => item.visible !== false);

return {
id,
label,
icon,
route: this.fullRoute(route),
defaultRoute: this.fullRoute(defaultRoute),
defaultRoute: this.resolveDefaultRoute(this.fullRoute(defaultRoute), visibleChildren),
requiresVisibleChildren,
children: children.filter((item) => item.visible !== false),
children: visibleChildren,
keywords,
};
}

/**
* Keep the branch's default route when the user may open it; otherwise fall back to the
* first child route they are permitted to open, so clicking the branch does not land on a
* route guard that bounces them back out.
*/
resolveDefaultRoute(defaultRoute, children = []) {
const permitted = (item) => [item.visiblePermission, item.permission].every((permission) => !permission || this.abilities.can(permission));
const defaultChild = children.find((item) => item.route === defaultRoute);

if (!defaultChild || permitted(defaultChild)) {
return defaultRoute;
}

return children.find((item) => item.route && permitted(item))?.route ?? defaultRoute;
}

createItem(intl, icon, route, permission, ability, keywords = []) {
return {
priority: this.defaultPriorityForRoute(route),
Expand All @@ -291,14 +307,16 @@ export default class LayoutFleetOpsSidebarComponent extends Component {
};
}

createHubItem(label, icon, route, _permission, _ability, keywords = []) {
createHubItem(label, icon, route, permission, ability, keywords = []) {
return {
pinnedFirst: true,
priority: this.defaultPriorityForRoute(route),
label,
description: label,
icon,
route: this.fullRoute(route),
permission,
visiblePermission: ability,
isNavigationHub: true,
keywords: [label, route, ...keywords].filter(Boolean),
};
Expand Down
3 changes: 2 additions & 1 deletion addon/components/map/leaflet-live-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,8 @@ export default class MapLeafletLiveMapComponent extends Component {
}

@task *loadResource(path, options = {}) {
if (this.abilities.cannot(`fleet-ops list ${path}`)) return [];
// Permissions use the singular resource name (e.g. `fleet-ops list vehicle`), not the plural endpoint path.
if (this.abilities.cannot(`fleet-ops list ${singularize(path)}`)) return [];

if (path === 'service-areas') {
const serviceAreas = yield this.serviceAreaActions.loadAll.perform();
Expand Down
2 changes: 1 addition & 1 deletion addon/components/telematic/hub.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</div>
<div class="flex flex-shrink-0 items-center gap-2 whitespace-nowrap">
<Button @icon="refresh" @size="sm" @helpText={{t "common.reload"}} @onClick={{this.refresh}} />
<Button @icon="plus" @text="Connect Provider" @type="primary" @size="sm" @onClick={{this.telematicActions.transition.create}} />
<Button @icon="plus" @text="Connect Provider" @type="primary" @size="sm" @permission="fleet-ops create telematic" @onClick={{this.telematicActions.transition.create}} />
</div>
</div>
</section>
Expand Down
5 changes: 5 additions & 0 deletions addon/controllers/analytics/reports/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export default class AnalyticsReportsIndexController extends Controller {
type: 'primary',
icon: 'plus',
onClick: this.reportActions.transition.create,
permission: 'iam create report',
},
];
}
Expand All @@ -39,6 +40,7 @@ export default class AnalyticsReportsIndexController extends Controller {
label: 'Delete selected...',
class: 'text-red-500',
fn: this.reportActions.bulkDelete,
permission: 'iam delete report',
},
];
}
Expand Down Expand Up @@ -81,17 +83,20 @@ export default class AnalyticsReportsIndexController extends Controller {
{
label: 'View report...',
fn: this.reportActions.transition.view,
permission: 'iam view report',
},
{
label: 'Edit report...',
fn: this.reportActions.transition.edit,
permission: 'iam update report',
},
{
separator: true,
},
{
label: 'Delete report...',
fn: this.reportActions.delete,
permission: 'iam delete report',
},
],
sortable: false,
Expand Down
4 changes: 4 additions & 0 deletions addon/controllers/connectivity/devices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,22 @@ export default class ConnectivityDevicesIndexController extends Controller {
type: 'primary',
icon: 'plus',
onClick: this.deviceActions.transition.create,
permission: 'fleet-ops create device',
},
{
text: this.intl.t('common.import'),
type: 'magic',
icon: 'upload',
onClick: this.deviceActions.import,
permission: 'fleet-ops import device',
},
{
text: this.intl.t('common.export'),
icon: 'long-arrow-up',
iconClass: 'rotate-icon-45',
wrapperClass: 'hidden md:flex',
onClick: this.deviceActions.export,
permission: 'fleet-ops export device',
},
];

Expand All @@ -87,6 +90,7 @@ export default class ConnectivityDevicesIndexController extends Controller {
label: 'Delete selected...',
class: 'text-red-500',
fn: this.deviceActions.bulkDelete,
permission: 'fleet-ops delete device',
},
];

Expand Down
10 changes: 6 additions & 4 deletions addon/controllers/connectivity/fuel-providers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export default class ConnectivityFuelProvidersIndexController extends Controller
text: 'Connect Integration',
type: 'primary',
onClick: () => this.fuelIntegrationActions.transition.create(),
permission: 'fleet-ops create fuel-provider-connection',
},
];
}
Expand All @@ -51,6 +52,7 @@ export default class ConnectivityFuelProvidersIndexController extends Controller
{
label: `Sync ${selected.length} selected`,
fn: () => selected.forEach((connection) => this.syncConnection(connection)),
permission: 'fleet-ops sync fuel-provider-connection',
},
];
}
Expand Down Expand Up @@ -125,11 +127,11 @@ export default class ConnectivityFuelProvidersIndexController extends Controller
sticky: 'right',
width: 60,
actions: [
{ label: 'Open Integration', fn: this.openConnection },
{ label: 'Edit Settings', fn: this.editConnection },
{ label: 'Open Integration', fn: this.openConnection, permission: 'fleet-ops view fuel-provider-connection' },
{ label: 'Edit Settings', fn: this.editConnection, permission: 'fleet-ops update fuel-provider-connection' },
{ separator: true },
{ label: 'Test Connection', fn: this.testConnection },
{ label: 'Sync Transactions', fn: this.syncConnection },
{ label: 'Test Connection', fn: this.testConnection, permission: 'fleet-ops update fuel-provider-connection' },
{ label: 'Sync Transactions', fn: this.syncConnection, permission: 'fleet-ops sync fuel-provider-connection' },
],
sortable: false,
filterable: false,
Expand Down
4 changes: 4 additions & 0 deletions addon/controllers/connectivity/sensors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,19 +92,22 @@ export default class ConnectivitySensorsIndexController extends Controller {
type: 'primary',
icon: 'plus',
onClick: this.sensorActions.transition.create,
permission: 'fleet-ops create sensor',
},
{
text: this.intl.t('common.import'),
type: 'magic',
icon: 'upload',
onClick: this.sensorActions.import,
permission: 'fleet-ops import sensor',
},
{
text: this.intl.t('common.export'),
icon: 'long-arrow-up',
iconClass: 'rotate-icon-45',
wrapperClass: 'hidden md:flex',
onClick: this.sensorActions.export,
permission: 'fleet-ops export sensor',
},
];

Expand All @@ -114,6 +117,7 @@ export default class ConnectivitySensorsIndexController extends Controller {
label: 'Delete selected...',
class: 'text-red-500',
fn: this.sensorActions.bulkDelete,
permission: 'fleet-ops delete sensor',
},
];

Expand Down
4 changes: 4 additions & 0 deletions addon/controllers/connectivity/telematics/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,22 @@ export default class ConnectivityTelematicsIndexController extends Controller {
type: 'primary',
icon: 'plus',
onClick: this.telematicActions.transition.create,
permission: 'fleet-ops create telematic',
},
{
text: this.intl.t('common.import'),
type: 'magic',
icon: 'upload',
onClick: this.telematicActions.import,
permission: 'fleet-ops import telematic',
},
{
text: this.intl.t('common.export'),
icon: 'long-arrow-up',
iconClass: 'rotate-icon-45',
wrapperClass: 'hidden md:flex',
onClick: this.telematicActions.export,
permission: 'fleet-ops export telematic',
},
];

Expand All @@ -60,6 +63,7 @@ export default class ConnectivityTelematicsIndexController extends Controller {
label: 'Delete selected...',
class: 'text-red-500',
fn: this.telematicActions.bulkDelete,
permission: 'fleet-ops delete telematic',
},
];

Expand Down
15 changes: 11 additions & 4 deletions addon/controllers/maintenance/equipment/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,21 @@ export default class MaintenanceEquipmentIndexController extends Controller {
helpText: 'Change the layout',
},
{ icon: 'refresh', onClick: this.equipmentActions.refresh, helpText: this.intl.t('common.refresh') },
{ text: this.intl.t('common.new'), type: 'primary', icon: 'plus', onClick: this.equipmentActions.transition.create },
{ text: this.intl.t('common.import'), type: 'magic', icon: 'upload', onClick: this.equipmentActions.import },
{ text: this.intl.t('common.export'), icon: 'long-arrow-up', iconClass: 'rotate-icon-45', wrapperClass: 'hidden md:flex', onClick: this.equipmentActions.export },
{ text: this.intl.t('common.new'), type: 'primary', icon: 'plus', onClick: this.equipmentActions.transition.create, permission: 'fleet-ops create equipment' },
{ text: this.intl.t('common.import'), type: 'magic', icon: 'upload', onClick: this.equipmentActions.import, permission: 'fleet-ops import equipment' },
{
text: this.intl.t('common.export'),
icon: 'long-arrow-up',
iconClass: 'rotate-icon-45',
wrapperClass: 'hidden md:flex',
onClick: this.equipmentActions.export,
permission: 'fleet-ops export equipment',
},
];
}

get bulkActions() {
return [{ label: 'Delete selected...', class: 'text-red-500', fn: this.equipmentActions.bulkDelete }];
return [{ label: 'Delete selected...', class: 'text-red-500', fn: this.equipmentActions.bulkDelete, permission: 'fleet-ops delete equipment' }];
}

get columns() {
Expand Down
4 changes: 2 additions & 2 deletions addon/controllers/maintenance/inspection-forms/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ export default class MaintenanceInspectionFormsIndexController extends Controlle
get actionButtons() {
return [
{ icon: 'refresh', onClick: this.inspectionFormActions.refresh, helpText: this.intl.t('common.refresh') },
{ text: this.intl.t('common.new'), type: 'primary', icon: 'plus', onClick: this.inspectionFormActions.transition.create },
{ text: this.intl.t('common.new'), type: 'primary', icon: 'plus', onClick: this.inspectionFormActions.transition.create, permission: 'fleet-ops create inspection-form' },
];
}

get bulkActions() {
return [{ label: 'Delete selected...', class: 'text-red-500', fn: this.inspectionFormActions.bulkDelete }];
return [{ label: 'Delete selected...', class: 'text-red-500', fn: this.inspectionFormActions.bulkDelete, permission: 'fleet-ops delete inspection-form' }];
}

get columns() {
Expand Down
10 changes: 8 additions & 2 deletions addon/controllers/maintenance/inspection-submissions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@ export default class MaintenanceInspectionSubmissionsIndexController extends Con
get actionButtons() {
return [
{ icon: 'refresh', onClick: this.inspectionSubmissionActions.refresh, helpText: this.intl.t('common.refresh') },
{ text: this.intl.t('common.new'), type: 'primary', icon: 'plus', onClick: this.inspectionSubmissionActions.transition.create },
{
text: this.intl.t('common.new'),
type: 'primary',
icon: 'plus',
onClick: this.inspectionSubmissionActions.transition.create,
permission: 'fleet-ops create inspection-submission',
},
];
}

get bulkActions() {
return [{ label: 'Delete selected...', class: 'text-red-500', fn: this.inspectionSubmissionActions.bulkDelete }];
return [{ label: 'Delete selected...', class: 'text-red-500', fn: this.inspectionSubmissionActions.bulkDelete, permission: 'fleet-ops delete inspection-submission' }];
}

get columns() {
Expand Down
Loading
Loading