Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
70f5ac5
feat: add schedule, schedule-item and availability relationships to D…
Mar 30, 2026
b9e540c
fix(serializers): normalize personnels type discriminator in VendorSe…
Mar 31, 2026
10c4849
fix(serializers): resolve personnels hasMany as embedded contacts
Mar 31, 2026
93c0494
feat(models): add MaintenanceSchedule Ember Data model
roncodes Mar 31, 2026
913bb12
cleanup model spacing
roncodes Apr 1, 2026
1c8d253
feat(maintenance): implement polymorphic relationships for maintenanc…
roncodes Apr 1, 2026
0c2aa3e
fix(maintenance): correct PHP namespace type mapping and add _name fa…
roncodes Apr 1, 2026
50a4d02
feat(maintenance): re-enable embedded relationships now that resource…
roncodes Apr 1, 2026
6f170b9
fix(maintenance): update serializer type maps to use shorthand from b…
roncodes Apr 1, 2026
0a43ce7
revert(maintenance): restore PHP class name maps in normalizePolymorp…
roncodes Apr 1, 2026
fbe7934
fix: change monetary attributes to @attr('string') type on maintenanc…
roncodes Apr 1, 2026
d5bd42c
fix: remove slug attr from work-order Ember model (no DB column)
roncodes Apr 1, 2026
70581a0
feat: add all missing server-side fields to maintenance-related Ember…
roncodes Apr 1, 2026
2012f35
fix(serializers): expand type maps and prefer injected subject_type/f…
roncodes Apr 2, 2026
872ed5f
refactor(serializers): rewrite polymorphic serializers to mirror the …
roncodes Apr 4, 2026
63ee1c2
fix(serializers): correctly strip polymorphic subtype prefix on seria…
roncodes Apr 4, 2026
7fd98a8
feat(maintenance-schedule): add reminder_offsets raw attribute to Emb…
roncodes Apr 4, 2026
5becb7e
feat: add Manifest and ManifestStop models, serializers, adapters; ad…
Apr 9, 2026
537bbb3
feat(manifest): re-export manifest and manifest-stop models, adapters…
Apr 9, 2026
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
11 changes: 11 additions & 0 deletions addon/adapters/manifest-stop.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ApplicationAdapter from '@fleetbase/ember-core/adapters/application';

export default class ManifestStopAdapter extends ApplicationAdapter {
urlForFindRecord(id) {
return `${this.host}/${this.namespace}/fleet-ops/v1/manifest-stops/${id}`;
}

urlForUpdateRecord(id) {
return `${this.host}/${this.namespace}/fleet-ops/v1/manifest-stops/${id}`;
}
}
11 changes: 11 additions & 0 deletions addon/adapters/manifest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ApplicationAdapter from '@fleetbase/ember-core/adapters/application';

export default class ManifestAdapter extends ApplicationAdapter {
urlForQuery() {
return `${this.host}/${this.namespace}/fleet-ops/v1/manifests`;
}

urlForFindRecord(id) {
return `${this.host}/${this.namespace}/fleet-ops/v1/manifests/${id}`;
}
}
6 changes: 6 additions & 0 deletions addon/models/asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { format as formatDate, isValid as isValidDate, formatDistanceToNow } fro

export default class AssetModel extends Model {
/** @ids */
@attr('string') uuid;
@attr('string') public_id;
@attr('string') company_uuid;
@attr('string') category_uuid;
Expand Down Expand Up @@ -63,11 +64,16 @@ export default class AssetModel extends Model {
@attr('raw') attributes;
@attr('string') notes;
@attr('string') slug;
/** @server-computed (read-only appended attributes) */
@attr('string') photo_url;
@attr('string') display_name;
@attr('string') category_name;
@attr('string') vendor_name;
@attr('string') warranty_name;
@attr('string') current_location;
@attr('boolean') is_online;
@attr('date') last_maintenance;
@attr('date') next_maintenance_due;

/** @dates */
@attr('date') deleted_at;
Expand Down
9 changes: 9 additions & 0 deletions addon/models/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { format as formatDate, isValid as isValidDate, formatDistanceToNow } fro

export default class DeviceModel extends Model {
/** @ids */
@attr('string') uuid;
@attr('string') public_id;
@attr('string') company_uuid;
@attr('string') telematic_uuid;
Expand All @@ -30,7 +31,15 @@ export default class DeviceModel extends Model {
@attr('string') imsi;
@attr('string') firmware_version;
@attr('string') provider;

/** @server-computed (read-only appended attributes) */
@attr('string') photo_url;
@attr('string') warranty_name;
@attr('string') telematic_name;
@attr('boolean') is_online;
@attr('string') attached_to_name;
@attr('string') connection_status;

@attr('string') manufacturer;
@attr('string') serial_number;
@attr('point') last_position;
Expand Down
5 changes: 5 additions & 0 deletions addon/models/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ export default class DriverModel extends Model {
@belongsTo('vendor', { async: true }) vendor;
@hasMany('custom-field-value', { async: false }) custom_field_values;

/** @scheduling-relationships */
@hasMany('schedule', { async: true }) schedules;
@hasMany('schedule-item', { async: true }) schedule_items;
@hasMany('schedule-availability', { async: true }) availabilities;

/** @attributes */
@attr('string') name;
@attr('string') phone;
Expand Down
9 changes: 8 additions & 1 deletion addon/models/equipment.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { format as formatDate, isValid as isValidDate, formatDistanceToNow } fro

export default class EquipmentModel extends Model {
/** @ids */
@attr('string') uuid;
@attr('string') public_id;
@attr('string') company_uuid;
@attr('string') warranty_uuid;
Expand All @@ -25,11 +26,17 @@ export default class EquipmentModel extends Model {
@attr('string') serial_number;
@attr('string') manufacturer;
@attr('string') model;
@attr('number') purchase_price;
@attr('string') purchase_price;
@attr('string') currency;
@attr('raw') meta;
@attr('string') slug;
/** @server-computed (read-only appended attributes) */
@attr('string') warranty_name;
@attr('string') photo_url;
@attr('string') equipped_to_name;
@attr('boolean') is_equipped;
@attr('number') age_in_days;
@attr('string') depreciated_value;

/** @dates */
@attr('date') purchased_at;
Expand Down
133 changes: 133 additions & 0 deletions addon/models/maintenance-schedule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import Model, { attr, belongsTo } from '@ember-data/model';
import { computed } from '@ember/object';
import { format as formatDate, isValid as isValidDate, formatDistanceToNow } from 'date-fns';

export default class MaintenanceScheduleModel extends Model {
/** @ids */
@attr('string') uuid;
@attr('string') public_id;
@attr('string') company_uuid;

/** @polymorphic relationships */
@belongsTo('maintenance-subject', { polymorphic: true, async: false }) subject;
@belongsTo('facilitator', { polymorphic: true, async: false }) default_assignee;
/** @computed names — server-side convenience fields (read-only) */
@attr('string') subject_name;
@attr('string') default_assignee_name;

/** @attributes */
@attr('string') code;
@attr('string') title;
@attr('string') description;
@attr('string') name;
@attr('string') type;
@attr('string') status;
@attr('string') interval_method;

/** @interval — time-based */
@attr('string') interval_type;
@attr('number') interval_value;
@attr('string') interval_unit;

/** @interval — distance / engine-hours */
@attr('number') interval_distance;
@attr('number') interval_engine_hours;

/** @baseline readings */
@attr('number') last_service_odometer;
@attr('number') last_service_engine_hours;
@attr('date') last_service_date;

/** @next-due thresholds */
@attr('date') next_due_date;
@attr('number') next_due_odometer;
@attr('number') next_due_engine_hours;

/** @work-order defaults */
@attr('string') default_priority;

@attr('string') instructions;
@attr('raw') meta;
@attr('string') slug;

/** @reminders — array of integer day offsets, e.g. [15, 7, 3] */
@attr('raw') reminder_offsets;

/** @dates */
@attr('date') last_triggered_at;
@attr('date') deleted_at;
@attr('date') created_at;
@attr('date') updated_at;

/** @computed */
@computed('status') get isActive() {
return this.status === 'active';
}

@computed('status') get isPaused() {
return this.status === 'paused';
}

@computed('next_due_date') get nextDueAt() {
if (!isValidDate(this.next_due_date)) {
return null;
}
return formatDate(this.next_due_date, 'yyyy-MM-dd HH:mm');
}

@computed('next_due_date') get nextDueAtShort() {
if (!isValidDate(this.next_due_date)) {
return null;
}
return formatDate(this.next_due_date, 'dd, MMM yyyy');
}

@computed('next_due_date') get nextDueAgo() {
if (!isValidDate(this.next_due_date)) {
return null;
}
return formatDistanceToNow(this.next_due_date, { addSuffix: true });
}

@computed('updated_at') get updatedAgo() {
if (!isValidDate(this.updated_at)) {
return null;
}
return formatDistanceToNow(this.updated_at);
}

@computed('updated_at') get updatedAt() {
if (!isValidDate(this.updated_at)) {
return null;
}
return formatDate(this.updated_at, 'yyyy-MM-dd HH:mm');
}

@computed('updated_at') get updatedAtShort() {
if (!isValidDate(this.updated_at)) {
return null;
}
return formatDate(this.updated_at, 'dd, MMM');
}

@computed('created_at') get createdAgo() {
if (!isValidDate(this.created_at)) {
return null;
}
return formatDistanceToNow(this.created_at);
}

@computed('created_at') get createdAt() {
if (!isValidDate(this.created_at)) {
return null;
}
return formatDate(this.created_at, 'yyyy-MM-dd HH:mm');
}

@computed('created_at') get createdAtShort() {
if (!isValidDate(this.created_at)) {
return null;
}
return formatDate(this.created_at, 'dd, MMM');
}
}
26 changes: 26 additions & 0 deletions addon/models/maintenance-subject-equipment.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import MaintenanceSubjectModel from './maintenance-subject';
import { attr } from '@ember-data/model';

/**
* Concrete polymorphic model for Equipment acting as a maintenance subject.
* Resolved when the backend sends subject_type / target_type / maintainable_type = 'fleet-ops:equipment'.
*/
export default class MaintenanceSubjectEquipmentModel extends MaintenanceSubjectModel {
/** @ids */
@attr('string') warranty_uuid;
@attr('string') photo_uuid;
@attr('string') equipable_type;
@attr('string') equipable_uuid;

/** @attributes */
@attr('string') code;
@attr('string') serial_number;
@attr('string') manufacturer;
@attr('string') model;
@attr('number') purchase_price;
@attr('string') warranty_name;
@attr('raw') meta;

/** @dates */
@attr('date') purchased_at;
}
44 changes: 44 additions & 0 deletions addon/models/maintenance-subject-vehicle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import MaintenanceSubjectModel from './maintenance-subject';
import { attr } from '@ember-data/model';
import { get } from '@ember/object';
import config from 'ember-get-config';

/**
* Concrete polymorphic model for a Vehicle acting as a maintenance subject.
* Resolved when the backend sends subject_type / target_type / maintainable_type = 'fleet-ops:vehicle'.
*/
export default class MaintenanceSubjectVehicleModel extends MaintenanceSubjectModel {
/** @ids */
@attr('string') internal_id;
@attr('string') photo_uuid;
@attr('string') vendor_uuid;
@attr('string') category_uuid;
@attr('string') warranty_uuid;
@attr('string') telematic_uuid;

/** @attributes */
@attr('string', {
defaultValue: get(config, 'defaultValues.vehicleImage'),
})
photo_url;

@attr('string') make;
@attr('string') model;
@attr('string') year;
@attr('string') trim;
@attr('string') plate_number;
@attr('string') vin;
@attr('string') driver_name;
@attr('string') vendor_name;
@attr('string') display_name;
@attr('string', {
defaultValue: get(config, 'defaultValues.vehicleAvatar'),
})
avatar_url;
@attr('string') avatar_value;
@attr('string') color;
@attr('string') country;
@attr('number') odometer;
@attr('number') engine_hours;
@attr('raw') meta;
}
78 changes: 78 additions & 0 deletions addon/models/maintenance-subject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import Model, { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { format as formatDate, isValid as isValidDate, formatDistanceToNow } from 'date-fns';

/**
* Abstract base model for polymorphic maintenance subjects.
* Concrete types: maintenance-subject-vehicle, maintenance-subject-equipment
*
* The backend stores the type as a PolymorphicType cast string, e.g.:
* 'fleet-ops:vehicle' -> maintenance-subject-vehicle
* 'fleet-ops:equipment' -> maintenance-subject-equipment
*/
export default class MaintenanceSubjectModel extends Model {
/** @ids */
@attr('string') uuid;
@attr('string') public_id;
@attr('string') company_uuid;

/** @attributes */
@attr('string') name;
@attr('string') display_name;
@attr('string') type;
@attr('string') status;
@attr('string') photo_url;
@attr('string') slug;

/** @dates */
@attr('date') deleted_at;
@attr('date') created_at;
@attr('date') updated_at;

/** @computed */
@computed('name', 'display_name', 'public_id') get displayName() {
return this.display_name || this.name || this.public_id;
}

@computed('updated_at') get updatedAgo() {
if (!isValidDate(this.updated_at)) {
return null;
}
return formatDistanceToNow(this.updated_at);
}

@computed('updated_at') get updatedAt() {
if (!isValidDate(this.updated_at)) {
return null;
}
return formatDate(this.updated_at, 'yyyy-MM-dd HH:mm');
}

@computed('updated_at') get updatedAtShort() {
if (!isValidDate(this.updated_at)) {
return null;
}
return formatDate(this.updated_at, 'dd, MMM');
}

@computed('created_at') get createdAgo() {
if (!isValidDate(this.created_at)) {
return null;
}
return formatDistanceToNow(this.created_at);
}

@computed('created_at') get createdAt() {
if (!isValidDate(this.created_at)) {
return null;
}
return formatDate(this.created_at, 'yyyy-MM-dd HH:mm');
}

@computed('created_at') get createdAtShort() {
if (!isValidDate(this.created_at)) {
return null;
}
return formatDate(this.created_at, 'dd, MMM');
}
}
Loading
Loading