Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
1f1db2e
test(ember): wire addon coverage gate and repair the test baseline
roncodes Sep 3, 2026
ddbd106
fix(ember): drop dead is-active-route helper and undeclared ember-con…
roncodes Sep 3, 2026
67117dd
test(ember): make the fleet-ops-sidebar rendering suite pass
roncodes Sep 3, 2026
bd2d63c
fix(ember): remove unreferenced format-duration re-export from addon/
roncodes Sep 3, 2026
a369e1e
test(ember): cover the sidebar driver and fleet listings
roncodes Sep 3, 2026
a3b9610
test(ember): finish fleet-ops-sidebar coverage
roncodes Sep 3, 2026
e7f9958
test(ember): finish operations-monitor coverage
roncodes Sep 3, 2026
64596eb
test(ember): cover every cell component
roncodes Sep 3, 2026
80f20a5
test(utils): make every unit-utility module green and cover 16 utils …
roncodes Sep 3, 2026
3adb90e
test(services): make every unit service suite green
roncodes Sep 3, 2026
f22dfc4
test(unit): relocate stale telematics tests and fix the red controlle…
roncodes Sep 3, 2026
0c62787
test(unit): fix the last red non-scaffold unit and helper tests
roncodes Sep 3, 2026
3da0c3c
test(components): real rendering suites for six details views; fix ma…
roncodes Sep 3, 2026
f460017
test(components): real rendering suites for six form components
roncodes Sep 3, 2026
db087dc
test(components): real suites for the map modals and small identity c…
roncodes Sep 3, 2026
d1d78f4
test(components): cover five small JS-bearing components
roncodes Sep 3, 2026
4b880e7
test(components): cover the vendor, sensor and contact forms and the …
roncodes Sep 3, 2026
6893505
test(components): cover the vendor, customer and driver details and t…
roncodes Sep 3, 2026
7df0e90
test(components): cover the onboarding settings, key-metrics widget a…
roncodes Sep 3, 2026
c99d16c
test(components): close the fetch spill and cover the device form, av…
roncodes Sep 3, 2026
d6c129f
fix(customer): disable the payments toggle until payments onboarding …
roncodes Sep 3, 2026
0d0c16d
test(components): cover the customer admin settings, device manager, …
roncodes Sep 3, 2026
c49f250
fix(vehicle,driver): pass the controller to registry components and g…
roncodes Sep 3, 2026
c8cd2a9
test(components): cover the vehicle form
roncodes Sep 3, 2026
af77c07
fix(driver,customer): link the new user's photo upload to the user
roncodes Sep 3, 2026
48a8959
test(components): cover the driver form
roncodes Sep 3, 2026
4451146
fix(i18n): spell the customer form's new address label correctly
roncodes Sep 3, 2026
39b5dfe
test(components): rewrite the customer form suite and drop its dead a…
roncodes Sep 3, 2026
16c2856
fix(order): match the active tracking stop only on identifiers both s…
roncodes Sep 3, 2026
68a95fa
test(components): make the order tracking suite green and cover the w…
roncodes Sep 3, 2026
662126b
test(components): rewrite the order service-rate suite as rendering t…
roncodes Sep 4, 2026
1b114a5
test(components): make the telematic details suite green and cover th…
roncodes Sep 4, 2026
f75d64c
fix(order): mark only the matching stop active in the tracking stop p…
roncodes Sep 4, 2026
78e759a
test(components): cover the tracking stop rail and the service-rate d…
roncodes Sep 4, 2026
da67fef
fix(order): stop the tracking lookup form from reloading the page
roncodes Sep 4, 2026
fb9359a
test(components): cover the order tracking lookup end to end
roncodes Sep 4, 2026
1f22567
fix(vehicle): join the vehicle skills with a separator in the details…
roncodes Sep 4, 2026
c96fd06
test(components): cover eight small scaffolded components
roncodes Sep 4, 2026
44b4c2a
fix(order): upload each selected document once
roncodes Sep 4, 2026
240adc2
test(components): cover six more scaffolded components
roncodes Sep 4, 2026
cff7b29
fix(components): label the contact phone, read pill fields from the r…
roncodes Sep 4, 2026
46a0dfc
test(components): green the 23 empty-class scaffolds, drop a dead ove…
roncodes Sep 4, 2026
4019861
fix(map): show the loaded device events in the drawer
roncodes Sep 4, 2026
33d8d53
fix(map): open the device panel for the event's device, not the event
roncodes Sep 4, 2026
c79f838
fix(fleet): debounce the listing search on typing, not on load
roncodes Sep 4, 2026
5687977
test(components): cover the map drawer and fleet listings, drop the f…
roncodes Sep 4, 2026
9bef934
fix(components): drop app-tree templates that shadow the addon's co-l…
roncodes Sep 4, 2026
9b63c72
fix(device): re-export the panel tabs instead of copying their classes
roncodes Sep 4, 2026
284f19e
test(connectivity): green the device, device-event and work-order suites
roncodes Sep 4, 2026
b6c4b6f
fix(components): re-export the seven components the app tree was missing
roncodes Sep 4, 2026
44fd174
test(components): cover the seven components missing from the app tree
roncodes Sep 4, 2026
8ac6fe9
test(order): green the telematic settings and order form suites
roncodes Sep 4, 2026
52df023
test(order): green the last red form suites, drop order/form's dead a…
roncodes Sep 4, 2026
ae25375
fix(order): inject intl into the route form so optimization errors re…
roncodes Sep 4, 2026
c6d52e7
fix(order): point the route-optimization error at the key that exists
roncodes Sep 4, 2026
e431af3
test(order): cover the order route form's waypoint and optimization p…
roncodes Sep 4, 2026
62e28db
test(order): finish the route form's reorder, customer and optimizati…
roncodes Sep 4, 2026
645ec40
test(order): complete the details and route form suites
roncodes Sep 4, 2026
50ec058
test(work-order): complete the work-order and telematic settings forms
roncodes Sep 4, 2026
a3bdddc
test(map): give the dummy app Leaflet, and cover the adapter's core
roncodes Sep 4, 2026
3dcb15c
test(map): cover the Leaflet adapter's routing controls and layer vis…
roncodes Sep 4, 2026
5a31734
test(map): finish the Leaflet adapter's statements and functions
roncodes Sep 4, 2026
b5b1a92
test(map): complete the Leaflet adapter at 100% on all four metrics
roncodes Sep 4, 2026
ce0e492
fix(map): give a layer its pane name, not the whole pane pair
roncodes Sep 4, 2026
5eac249
test(map): complete the layer visibility manager, and drop what canno…
roncodes Sep 4, 2026
f306c6e
test(map): cover the Google adapter's viewport and markers
roncodes Sep 4, 2026
1e3fb24
test(map): cover the Google adapter's overlays, routing and visibility
roncodes Sep 4, 2026
e35bc47
test(map): cover the Google adapter's popups, menus, events and utili…
roncodes Sep 4, 2026
5fef0aa
test(map): cover the Google adapter's draw toolbar
roncodes Sep 4, 2026
f3c9d34
test(map): cover the Google adapter's polygon labels and marker tooltips
roncodes Sep 4, 2026
bad9caf
test(map): cover the Google adapter's draft editing and deletion
roncodes Sep 4, 2026
6ab09c1
fix(map): detach and forget GeoJSON layers when the map is destroyed
roncodes Sep 4, 2026
37e3623
test(map): cover the Google adapter's drawing bridge and lifecycle
roncodes Sep 4, 2026
a479293
fix(map): let the draw toolbar toggle actually close it
roncodes Sep 4, 2026
758b11c
test(map): sweep the Google adapter's branch residue
roncodes Sep 4, 2026
83c19ca
test(map): cover the Google adapter's editPolygon, tooltips and defaults
roncodes Sep 4, 2026
1a7080f
test(map): cover the Google adapter's polygon label overlay
roncodes Sep 4, 2026
0a0c9b1
test(map): finish the Google adapter at 100%
roncodes Sep 4, 2026
bb34605
test(orchestrator): stand up the workbench and cover its run flow
roncodes Sep 4, 2026
83ef9a3
test(orchestrator): cover the workbench's selections, drag-drop and p…
roncodes Sep 4, 2026
609734e
test(orchestrator): render the workbench map block and cover it
roncodes Sep 4, 2026
efb55f8
test(orchestrator): sweep the workbench's branch residue
roncodes Sep 4, 2026
896278c
test(orchestrator): finish the workbench's branches and functions
roncodes Sep 4, 2026
f68a6da
test(orchestrator): take the workbench to 100%
roncodes Sep 4, 2026
ed58737
test(customer): open the create-order form and retire its scaffold
roncodes Sep 4, 2026
acdd9d9
test(customer): unblock the order form's disabled controls
roncodes Sep 4, 2026
4fc5e62
test(customer): give the order form harness a real Leaflet map
roncodes Sep 4, 2026
20c1d17
test(customer): cover the order form's multi-drop and POD toggles
roncodes Sep 4, 2026
1115290
test(customer): cover the order form's creation path
roncodes Sep 4, 2026
aff0339
test(customer): cover the order form's quoting path
roncodes Sep 4, 2026
35ecbe9
test(customer): cover the completing-purchase dialog; payment block b…
roncodes Sep 4, 2026
2a7ad7f
test(customer): cover the order form's files and item photos
roncodes Sep 5, 2026
3051c08
test(customer): cover restoring an order after checkout
roncodes Sep 5, 2026
c9ad5d5
test(customer): cover the order form's map, type select and reorder
roncodes Sep 5, 2026
453736d
fix(joint-graph): remove the responsive resize listener on destroy
roncodes Sep 5, 2026
9bdd519
test(order-config): cover the activity flow, and let the dummy app lo…
roncodes Sep 5, 2026
b9bceca
test(order-config): cover the activity flow's editing surface
roncodes Sep 5, 2026
8cf3c7e
test(scheduler): cover the dispatch board's read model and view state
roncodes Sep 5, 2026
44f3658
test(scheduler): cover drag-and-drop, sockets and the event helpers
roncodes Sep 5, 2026
b1eae18
test(scheduler): cover the modals, finishing the file at 100%
roncodes Sep 5, 2026
2592cc9
test(map): cover the live map's Google branch
roncodes Sep 5, 2026
532f8f7
test(map): cover the live map's Leaflet branch and context menus
roncodes Sep 5, 2026
4ffab38
test(map): cover the live map's menu callbacks and geofence flashes
roncodes Sep 5, 2026
9353fed
test(map): cover the live map's layer registration and boundary menus
roncodes Sep 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 3 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ module.exports = {
'n/no-unpublished-require': [
'error',
{
allowModules: ['resolve'],
// devDependencies required from index.js: `resolve` for asset paths, ember-cli-code-coverage
// only behind `COVERAGE=true` (see coverageBabelPlugin in index.js).
allowModules: ['resolve', 'ember-cli-code-coverage'],
},
],
},
Expand Down
50 changes: 48 additions & 2 deletions .github/workflows/ember.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,62 +37,108 @@
- name: Build
run: pnpm run build

test:
name: Test with coverage
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}

- name: Setup pnpm
uses: pnpm/action-setup@v2.0.1
with:
version: latest

- name: Install Dependencies
run: pnpm install

- name: Coverage gate self-test
run: pnpm run coverage:selftest

- name: Run full test suite with coverage
run: pnpm run test:coverage

- name: Enforce 100% coverage gate
run: pnpm run coverage:check

- name: Verify LCOV report exists
if: always()
run: test -s coverage/lcov.info || (echo 'coverage/lcov.info missing or empty' && exit 1)

# `if: always()` is deliberate: the gate above fails the build, but Codecov must still receive
# this run's report. The backend workflow gates before uploading without it, and Codecov saw
# nothing at all for this repo until that suite went green.
- name: Upload coverage to Codecov
if: always()
uses: codecov/codecov-action@v5
with:
files: coverage/lcov.info
flags: frontend
fail_ci_if_error: false
disable_search: true
token: ${{ secrets.CODECOV_TOKEN }}

npm_publish:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
needs: build
needs: [build, test]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v2

- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}

- name: Setup pnpm
uses: pnpm/action-setup@v2.0.1
with:
version: latest

- name: Install Dependencies
run: pnpm install

- name: Build
run: pnpm run build

- name: Set up npm
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_AUTH_TOKEN }}" > ~/.npmrc

- name: Publish
run: npm publish --access public

github_publish:

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
needs: build
needs: [build, test]
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/')
steps:
- uses: actions/checkout@v2

- name: Setup Node.js ${{ env.NODE_VERSION }}
uses: actions/setup-node@v2
with:
node-version: ${{ env.NODE_VERSION }}

- name: Setup pnpm
uses: pnpm/action-setup@v2.0.1
with:
version: latest

- name: Install Dependencies
run: pnpm install

- name: Build
run: pnpm run build

- name: Configure npm for GitHub registry
run: |
echo "@fleetbase:registry=https://npm.pkg.github.com/" >> ~/.npmrc
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> ~/.npmrc

- name: Publish to GitHub registry
run: npm publish

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,15 @@ composer.lock
*.swp
*.swo
.DS_Store

# coverage
# `/coverage/` above covers the normal case; these guard the reports istanbul writes for
# workspace-linked siblings, whose relative paths resolve out of the coverage folder and into the
# package root (see tests/dummy/config/coverage.js).
/ember-core/
/ember-ui/
/fleetops-data/
/*/addon/**/*.js.html

# Written by scripts/stamp-coverage-run.js; proves the coverage artifacts belong to the last run
.coverage-run-stamp.json
3 changes: 3 additions & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@
# server
/server/
/server_vendor/

# generated coverage report
/coverage/
521 changes: 521 additions & 0 deletions COVERAGE-PROGRESS.md

Large diffs are not rendered by default.

1,268 changes: 1,268 additions & 0 deletions DEFECTS.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<a href="https://codecov.io/gh/fleetbase/fleetops">
<img src="https://codecov.io/gh/fleetbase/fleetops/branch/main/graph/badge.svg" alt="Coverage">
</a>
<a href="https://codecov.io/gh/fleetbase/fleetops?flags%5B0%5D=frontend">
<img src="https://codecov.io/gh/fleetbase/fleetops/branch/main/graph/badge.svg?flag=frontend" alt="Frontend coverage">
</a>
<a href="https://www.npmjs.com/package/@fleetbase/fleetops-engine">
<img src="https://img.shields.io/badge/npm-%40fleetbase%2Ffleetops--engine-CB3837?style=flat-square" alt="NPM package">
</a>
Expand Down
10 changes: 5 additions & 5 deletions addon/components/activity/event-selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export default class ActivityEventSelectorComponent extends Component {
*
* @type {Array}
*/
@tracked events = [];
@tracked events;

/**
* An object representing available events, each with a name and description.
Expand All @@ -25,19 +25,19 @@ export default class ActivityEventSelectorComponent extends Component {
return {
'order.dispatched': {
name: 'order.dispatched',
description: this.intl?.t?.('activity.form.event-selector.events.order.dispatched') ?? 'Triggers when an order is successfully dispatched.',
description: this.intl.t('activity.form.event-selector.events.order.dispatched'),
},
'order.failed': {
name: 'order.failed',
description: this.intl?.t?.('activity.form.event-selector.events.order.failed') ?? 'Triggers when an order fails due to an error or exception.',
description: this.intl.t('activity.form.event-selector.events.order.failed'),
},
'order.canceled': {
name: 'order.canceled',
description: this.intl?.t?.('activity.form.event-selector.events.order.canceled') ?? 'Triggers when an order is canceled by a user, driver, or system process.',
description: this.intl.t('activity.form.event-selector.events.order.canceled'),
},
'order.completed': {
name: 'order.completed',
description: this.intl?.t?.('activity.form.event-selector.events.order.completed') ?? 'Triggers when an order is completed by a driver, or system process.',
description: this.intl.t('activity.form.event-selector.events.order.completed'),
},
};
}
Expand Down
12 changes: 0 additions & 12 deletions addon/components/activity/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { underscore, capitalize, w } from '@ember/string';
import { task } from 'ember-concurrency';

export default class ActivityFormComponent extends Component {
/**
Expand All @@ -12,17 +11,6 @@ export default class ActivityFormComponent extends Component {
*/
@tracked podOptions = ['scan', 'signature', 'photo'];

/**
* Task to save the activity. It triggers an optional onSave callback
* with the current state of the activity.
* @task
*/
@task *save() {
if (typeof this.onSave === 'function') {
yield this.onSave(this.args.resource);
}
}

/**
* Sets the proof of delivery method to be used for this activity.
*
Expand Down
2 changes: 1 addition & 1 deletion addon/components/admin/avatar-management.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
{{#if dropzone.supported}}
<p class="text-sm my-5">{{t "dropzone.dropzone-supported-avatars"}}</p>
{{/if}}
<FileUpload @name="files" @for="files" @accept={{join "," this.acceptedFileTypes}} @multiple={{true}} @onFileAdded={{this.queueFile}}>
<FileUpload @name="files" @for="files" @accept={{join "," this.acceptedFileTypes}} @multiple={{true}}>
<a tabindex={{0}} class="btn btn-magic cursor-pointer ml-1">{{t "dropzone.or-select-button-text"}}</a>
</FileUpload>
</div>
Expand Down
2 changes: 1 addition & 1 deletion addon/components/avatar-manager.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
{{#if dropzone.supported}}
<p class="text-sm my-5">{{t "dropzone.dropzone-supported-avatars"}}</p>
{{/if}}
<FileUpload @name="files" @for="files" @accept={{join "," this.acceptedFileTypes}} @multiple={{true}} @onFileAdded={{this.queueFile}}>
<FileUpload @name="files" @for="files" @accept={{join "," this.acceptedFileTypes}} @multiple={{true}}>
<a tabindex={{0}} class="btn btn-magic cursor-pointer ml-1">{{t "dropzone.or-select-button-text"}}</a>
</FileUpload>
</div>
Expand Down
2 changes: 0 additions & 2 deletions addon/components/avatar-picker.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,9 @@ export default class AvatarPickerComponent extends Component {
try {
file = await this.store.findRecord('file', id);
} catch (e) {
// Optional: surface a toast here if you want
return;
}
}
if (!file) return;

// No-op fast path
if (this.model.avatar_url === file.id && this.model.avatar_custom_url === file.url) {
Expand Down
4 changes: 0 additions & 4 deletions addon/components/cell/attached-vehicle.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ export default class CellAttachedVehicleComponent extends Component {
@action onClick(_vehicle, event) {
const { column, onClick } = this.args;

if (!this.hasVehicle) {
return;
}

if (typeof onClick === 'function') {
onClick(this.device, event);
}
Expand Down
3 changes: 2 additions & 1 deletion addon/components/cell/driver-identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ export default class CellDriverIdentityComponent extends Component {
}

get assignedVehicleLabel() {
const column = this.args.column ?? {};
// only read by the compact template, which `this.args.column.compact` already required
const column = this.args.column;
const driver = this.resource;

if (typeof column.assignedVehicleLabel === 'function') {
Expand Down
4 changes: 2 additions & 2 deletions addon/components/cell/telematic-provider.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ export default class CellTelematicProviderComponent extends Component {
}

@action onClick(event) {
const { row, column, onClick } = this.args;
const resource = this.telematic ?? row;
const { column, onClick } = this.args;
const resource = this.telematic;

if (typeof onClick === 'function') {
onClick(resource, event);
Expand Down
2 changes: 1 addition & 1 deletion addon/components/contact/details.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</div>

<div class="field-info-container">
<div class="field-name">{{t "common.email"}}</div>
<div class="field-name">{{t "common.phone"}}</div>
<ClickToCopy @value={{@resource.phone}} class="field-value">{{n-a @resource.phone}}</ClickToCopy>
</div>

Expand Down
11 changes: 0 additions & 11 deletions addon/components/custom-entity/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,6 @@ export default class CustomEntityFormComponent extends Component {
@service fetch;
@tracked config;

/**
* Action method to save the custom entity. It triggers an optional onSave callback
* with the current state of the custom entity.
* @action
*/
@action save() {
if (typeof this.onSave === 'function') {
this.onSave(this.args.resource);
}
}

/**
* Action method called when a file is added. It uploads the file
* and updates the custom entity's photo information.
Expand Down
2 changes: 1 addition & 1 deletion addon/components/customer/admin-settings.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
@onToggle={{perform this.togglePayments}}
@label="Enable customer to make payments through portal"
@wrapperClass={{if (or this.togglePayments.isRunning this.loadOrderConfigs.isRunning) "pointer-events-none opacity-50" ""}}
@disable={{not this.paymentsOnboardCompleted}}
@disabled={{not this.paymentsOnboardCompleted}}
/>
{{#if this.toggleOrderConfig.isIdle}}
<div class="space-y-4 mt-4">
Expand Down
2 changes: 1 addition & 1 deletion addon/components/customer/admin-settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { inject as service } from '@ember/service';
import { isEmpty } from '@ember/utils';
import { task } from 'ember-concurrency';
import config from 'ember-get-config';
import window from 'ember-window-mock';

export default class CustomerAdminSettingsComponent extends Component {
@service fetch;
Expand All @@ -13,7 +14,6 @@ export default class CustomerAdminSettingsComponent extends Component {
@tracked enabledOrderConfigs = [];
@tracked paymentsEnabled = false;
@tracked paymentsOnboardCompleted = false;
@tracked paymentGateway = 'stripe';

get isStripeEnabled() {
return window.stripeInstance !== undefined || !isEmpty(config.stripe.publishableKey);
Expand Down
1 change: 0 additions & 1 deletion addon/components/customer/create-order-form.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@
@for="files"
@accept={{join "," this.acceptedFileTypes}}
@multiple={{true}}
@onFileAdded={{perform this.queueFile}}
@disabled={{cannot "fleet-ops create order"}}
>
<a tabindex={{0}} class="btn btn-magic cursor-pointer ml-1">{{t "component.dropzone.or-select-button-text"}}</a>
Expand Down
11 changes: 7 additions & 4 deletions addon/components/customer/create-order-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,6 @@ export default class CustomerCreateOrderFormComponent extends Component {
'application/x-tar',
];

@computed('payloadCoordinates.length', 'waypoints.[]') get isServicable() {
return this.payloadCoordinates.length >= 2;
}

@computed('routePreviewArray.[]') get routePreviewCoordinates() {
return this.routePreviewArray.map((place) => place.get('latlng'));
}
Expand Down Expand Up @@ -438,6 +434,13 @@ export default class CustomerCreateOrderFormComponent extends Component {
return routePreviewArray;
}

// Nothing can reach this. `create-order-form.hbs` never names `createPlace`, the class never
// calls it, and the template has no `{{yield}}`, so it cannot be handed to a child either.
// The `createPlace` the contact/customer/vendor forms call is a *service* method on
// `contact-actions` / `customer-actions` / `vendor-actions` — a different thing that happens
// to share the name. See DEFECTS #100: whether the order form should offer "new address" at
// all is a product call, so this stays until that is answered.
/* istanbul ignore next -- no template reference, no caller, and the component yields nothing */
@action createPlace() {
const place = this.store.createRecord('place', {
owner_uuid: this.customer.id,
Expand Down
2 changes: 1 addition & 1 deletion addon/components/customer/details.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<ClickToCopy @value={{@resource.email}} class="field-value">{{n-a @resource.email}}</ClickToCopy>
</div>
<div class="field-info-container">
<div class="field-name">{{t "common.email"}}</div>
<div class="field-name">{{t "common.phone"}}</div>
<ClickToCopy @value={{@resource.phone}} class="field-value">{{n-a @resource.phone}}</ClickToCopy>
</div>
<div class="field-info-container">
Expand Down
56 changes: 0 additions & 56 deletions addon/components/customer/form.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,15 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { task } from 'ember-concurrency';

export default class CustomerFormComponent extends Component {
@service customerActions;
@service store;
@service fetch;
@service currentUser;
@service notifications;
@service modalsManager;
@service('universe/extension-manager') extensionManager;

@tracked userAccountActionButtons = [
{
icon: 'user-plus',
size: 'xs',
permission: 'iam create user',
onClick: async () => {
// Load IAM engine for user-form modal component
await this.extensionManager.ensureEngineLoaded('@fleetbase/iam-engine');

const user = this.store.createRecord('user', {
status: 'pending',
type: 'user',
});

this.modalsManager.show('modals/user-form', {
title: 'Create a new user',
user,
formPermission: 'iam create user',
uploadNewPhoto: (file) => {
this.fetch.uploadFile.perform(
file,
{
path: `uploads/${this.currentUser.companyId}/users/${user.slug}`,
subject_uui: user.id,
subject_type: 'user',
type: 'user_photo',
},
(uploadedFile) => {
user.setProperties({
avatar_uuid: uploadedFile.id,
avatar_url: uploadedFile.url,
avatar: uploadedFile,
});
}
);
},
confirm: async (modal) => {
modal.startLoading();

try {
await user.save();
this.notifications.success('New user created successfully!');
modal.done();
} catch (error) {
this.notifications.serverError(error);
modal.stopLoading();
}
},
});
},
},
];

get showWelcomeEmailOption() {
return this.args.resource?.isNew && this.extensionManager.isInstalled('@fleetbase/customer-portal-engine');
}
Expand Down
Loading
Loading