feat(maintenance): Complete maintenance module — Maintenances, Work Orders, Equipment & Parts#215
Open
feat(maintenance): Complete maintenance module — Maintenances, Work Orders, Equipment & Parts#215
Conversation
…k orders, equipment & parts Completes the existing but incomplete maintenance section in FleetOps, enabling full CRUD for all four maintenance resources: Maintenances, Work Orders, Equipment, and Parts. Frontend: - Uncomment and activate the maintenance sidebar panel (fleet-ops-sidebar.js) - Add Maintenances as first sidebar item with wrench icon - Add maintenances route block to routes.js - New route files for maintenances (index, new, edit, details, details/index) - Fix all work-orders/equipment/parts details+edit routes: add model hook and permission guard - New controllers for maintenances (index, new, edit, details, details/index) - Complete controllers for work-orders, equipment, parts (full columns, save tasks, tabs, action buttons) - New panel-header components for all four resources (HBS + JS) - Fix all new.hbs templates: correct @resource binding (was this.place bug) - Fix all details.hbs: add @headerComponent, TabNavigation with outlet - Fix all edit.hbs: add @headerTitle with resource name - New maintenances templates (maintenances.hbs, index, new, edit, details, details/index) - Add 12 new Universe registries in extension.js for maintenance/work-order/equipment/part - Fix maintenance-actions.js: use maintenance.summary instead of maintenance.name Backend: - Add maintenance, work-order, equipment, part resources to FleetOps auth schema - Add MaintenanceManager policy with full CRUD on all four resources - Update OperationsAdmin policy to include all four maintenance resources - Add Maintenance Technician role - New ProcessMaintenanceTriggers artisan command (time-based + odometer/engine-hour triggers) - Register command and daily schedule in FleetOpsServiceProvider
… sections - work-order/form: split into Identification, Assignment (polymorphic target + assignee with type-driven ModelSelect), Scheduling, and Instructions panels. Added targetTypeOptions, assigneeTypeOptions, onTargetTypeChange, onAssigneeTypeChange, assignTarget, assignAssignee actions. Removed hardcoded 'user' model assumption. - maintenance/form: split into Identification, Asset & Work Order (polymorphic maintainable + performed-by), Scheduling & Readings (odometer, engine_hours, scheduled_at, started_at, completed_at), Costs (MoneyInput for labor_cost, parts_cost, tax, total_cost), and Notes panels. Added full polymorphic type handlers. - equipment/form: split into Photo, Identification (name, code, serial_number, manufacturer, model, type, status), Assignment (polymorphic equipable), and Purchase & Warranty panels. Fixed photo upload to use fetch.uploadFile.perform pattern. Added onEquipableTypeChange / assignEquipable actions. - part/form: split into Photo, Identification (name, sku, serial_number, barcode, manufacturer, model, type, status, description), Inventory (quantity_on_hand, unit_cost, msrp with MoneyInput), Compatibility (polymorphic asset), and Vendor & Warranty panels. Fixed photo upload to use fetch.uploadFile.perform pattern. Added onAssetTypeChange / assignAsset actions. All forms: added MetadataEditor panel, RegistryYield hooks, and CustomField::Yield. All option arrays cross-checked against PHP model fillable arrays and fleetops-data Ember models.
… equipment route name
… and part forms, fix all ContentPanel wrapperClass - equipment/form.hbs: remove standalone Photo ContentPanel; photo block (Image + UploadButton, matching vehicle/form structure) is now the first child of the Identification ContentPanel before the field grid. - part/form.hbs: same restructure as equipment. - All four forms (work-order, maintenance, equipment, part): every ContentPanel now carries @wrapperclass="bordered-top", including the first panel. Previously work-order and maintenance first panels had no wrapperClass at all. - equipment/form.js: equipableTypeOptions converted to { value, label } objects; added @Tracked selectedEquipableType; onEquipableTypeChange now receives option object and reads option.value. - part/form.js: assetTypeOptions converted to { value, label } objects; added @Tracked selectedAssetType; onAssetTypeChange updated similarly. - Both HBS files updated to bind @selected to the tracked option object and render {{option.label}} in the PowerSelect block.
…d-by type selectors
- maintainableTypeOptions: plain strings -> { value, label } objects
(Vehicle, Equipment)
- performedByTypeOptions: plain strings -> { value, label } objects
(Vendor, Driver, User) — added Vendor as a valid performer type
- Added selectedMaintainableType and selectedPerformedByType tracked
properties so the PowerSelect trigger shows the human-readable label
- Both onChange actions now receive the full option object and write
option.value to the model attribute
- Updated TYPE_TO_MODEL to include fleet-ops:vendor -> vendor
- HBS PowerSelect @selected bindings updated to use the tracked option
objects; block params renamed from |type| to |option| with {{option.label}}
…ems panel - Add migration to add public_id column to maintenances, work_orders, equipment, and parts tables (fixes SQLSTATE[42S22] unknown column error) - Replace flat cost ContentPanel with new Maintenance::CostPanel component - Invoice-style line items table with description, qty, unit cost, line total - Inline add/edit/remove rows with optimistic UI updates - Labour and Tax inputs remain as direct MoneyInput fields - Computed totals summary (Labour + Parts + Tax = Total) - All mutations hit dedicated API endpoints and reflect server-recomputed totals - Add addLineItem / updateLineItem / removeLineItem endpoints to MaintenanceController - Register POST/PUT/DELETE line-item sub-routes in routes.php
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR completes the existing but stub-only maintenance section in FleetOps. All four maintenance resources — Maintenances, Work Orders, Equipment, and Parts — now have fully functional CRUD flows, following the same conventions used throughout the rest of the extension (e.g. the
connectivitysection withLayout::Resource::Panel,TabNavigation, andpanel-headercomponents).The sidebar maintenance panel is also uncommented and activated.
Frontend Changes
Sidebar (
fleet-ops-sidebar.js)maintenance.maintenancesRoutes (
routes.js+ new route files)maintenancesroute block (index / new / edit / details / details.index)work-orders,equipment, andpartsdetails + edit routes: addedmodel()hook and permission guard (were empty stubs)Controllers
maintenances/index: full columns (summary, type, status, priority, scheduled_at, total_cost, created_at), action buttons, bulk delete, query paramsmaintenances/index/new: save task with event tracking and form resetmaintenances/index/edit: save task, unsaved-changes guard, cancel/view actionsmaintenances/index/details: tabs (Overview + registered extension tabs viamenuService.getMenuItems), edit/delete action buttonswork-orders/index,equipment/index,parts/index: full column definitions, action buttons, bulk actionsComponents
work-order/panel-header— displays code/subject, status badge, priority, assigned drivermaintenance/panel-header— displays summary, status badge, type, scheduled_atequipment/panel-header— displays photo, name, status badge, type, serial numberpart/panel-header— displays photo, name, status badge, type, part numberTemplates
new.hbsfiles: corrected@resource={{this.place}}bug → correct resource bindingdetails.hbsfiles: added@headerComponent(panel-header),TabNavigationwith{{outlet}}edit.hbsfiles: added@headerTitlewith resource namedetails/index.hbsfiles: wired to correct::Detailscomponentmaintenances(parent, index, new, edit, details, details/index)Extension Registries (
extension.js)Added 12 new Universe registries enabling downstream extensions to inject custom tabs and form sections:
Services
maintenance-actions.js: fixedmaintenance.name→maintenance.summaryin panel/modal titlesBackend Changes
Auth Schema (
server/src/Auth/Schemas/FleetOps.php)maintenance,work-order,equipment,part(each with standard CRUD + export/import actions)MaintenanceManagerpolicy: full CRUD on all four resourcesOperationsAdminpolicy: includes all four maintenance resourcesMaintenance Technicianrole: uses theMaintenanceManagerpolicyConsole Command (
server/src/Console/Commands/ProcessMaintenanceTriggers.php)New artisan command:
fleetops:process-maintenance-triggersscheduled_athas arrived and transitions them toin_progressodometerandengine_hoursagainstnext_service_odometer/next_service_engine_hourson scheduled maintenance recordsmaintenance.triggeredevent for downstream extension hooks (no hard-coded foreign keys to external modules)--sandboxand--dry-runflagsService Provider (
server/src/Providers/FleetOpsServiceProvider.php)ProcessMaintenanceTriggersin$commandsarrayfleetops:process-maintenance-triggersto run dailyExtensibility Design
All integration points are designed to be consumed by downstream extensions without modifying FleetOps core:
metaJSON column on all maintenance models accepts arbitrary key-value datamaintenance.triggeredevent can be listened to by any extension'sEventServiceProviderTesting Checklist
php artisan fleetops:process-maintenance-triggers --dry-runreports triggers without modifying recordsphp artisan fleetops:process-maintenance-triggerstransitions due maintenances toin_progress