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
23 changes: 23 additions & 0 deletions addon/components/admin/vroom-settings.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<ContentPanel @title="Configure VROOM" @open={{true}} @wrapperClass="bordered-classic">
<InputGroup @name="VROOM API Key" @helpText="Optional API key for the system-wide VROOM service.">
<Input @value={{this.apiKey}} placeholder="Enter system VROOM API key" class="w-full form-input" />
</InputGroup>
<InputGroup @name="VROOM API Host" @helpText="Base URL for the default VROOM service used by organizations that do not define an override.">
<Input @value={{this.apiHost}} placeholder="https://api.verso-optim.com/vrp/v1" class="w-full form-input" />
</InputGroup>
<InputGroup @name="VROOM Endpoint Mode" @helpText="Use SaaS for services that expose /solve and /plan, or Binary for self-hosted HTTP servers that receive requests directly at the configured host.">
<Select
@value={{this.endpointMode}}
@options={{array (hash label="SaaS / Express" value="saas") (hash label="Open Source Binary" value="binary")}}
@optionLabel="label"
@optionValue="value"
@onSelect={{fn (mut this.endpointMode)}}
@placeholder="Select default endpoint mode"
class="w-full"
/>
</InputGroup>

<div class="mt-4">
<Button @text="Save VROOM Settings" @type="primary" @size="sm" @icon="save" @onClick={{perform this.saveVroomSettings}} @isLoading={{this.saveVroomSettings.isRunning}} />
</div>
</ContentPanel>
47 changes: 47 additions & 0 deletions addon/components/admin/vroom-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { debug } from '@ember/debug';
import { task } from 'ember-concurrency';

export default class AdminVroomSettingsComponent extends Component {
@service fetch;
@service notifications;
@tracked apiKey;
@tracked apiHost;
@tracked endpointMode = 'saas';

constructor() {
super(...arguments);
this.loadVroomSettings.perform();
}

@task *loadVroomSettings() {
try {
const { api_key, api_host, endpoint_mode } = yield this.fetch.get('admin-settings', {}, { namespace: 'vroom/int/v1' });
this.apiKey = api_key;
this.apiHost = api_host;
this.endpointMode = endpoint_mode ?? 'saas';
} catch (err) {
debug(`VROOM : Error fetching admin vroom settings: ${err.message}`);
}
}

@task *saveVroomSettings() {
try {
yield this.fetch.post(
'admin-settings',
{
api_key: this.apiKey,
api_host: this.apiHost,
endpoint_mode: this.endpointMode,
},
{ namespace: 'vroom/int/v1' }
);
this.notifications.success('VROOM settings saved.');
} catch (err) {
debug(`VROOM : Error saving admin vroom settings: ${err.message}`);
this.notifications.serverError(err);
}
}
}
27 changes: 27 additions & 0 deletions addon/components/organization/vroom-settings.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{{#if this.isActive}}
<ContentPanel @title="Configure VROOM" @open={{true}} @wrapperClass="bordered-classic">
<InputGroup @name="Organization Override">
<Checkbox @value={{this.useOwnServer}} @label="Use my own VROOM server" @onToggle={{fn (mut this.useOwnServer)}} @alignItems="center" @labelClass="mb-0i" />
</InputGroup>

{{#if this.useOwnServer}}
<InputGroup @name="VROOM API Key" @helpText="Optional organization-specific API key override.">
<Input @value={{this.apiKey}} placeholder="Enter organization VROOM API key" class="w-full form-input" />
</InputGroup>
<InputGroup @name="VROOM API Host" @helpText="Organization-specific VROOM host override.">
<Input @value={{this.apiHost}} placeholder="https://your-vroom-host.example.com" class="w-full form-input" />
</InputGroup>
<InputGroup @name="VROOM Endpoint Mode" @helpText="Choose whether this organization uses a SaaS /solve endpoint or a direct binary host.">
<Select
@value={{this.endpointMode}}
@options={{array (hash label="SaaS / Express" value="saas") (hash label="Open Source Binary" value="binary")}}
@optionLabel="label"
@optionValue="value"
@onSelect={{fn (mut this.endpointMode)}}
@placeholder="Select organization endpoint mode"
class="w-full"
/>
</InputGroup>
{{/if}}
</ContentPanel>
{{/if}}
74 changes: 74 additions & 0 deletions addon/components/organization/vroom-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { debug } from '@ember/debug';
import { task } from 'ember-concurrency';

export default class OrganizationVroomSettingsComponent extends Component {
@service fetch;
@service notifications;
@tracked useOwnServer = false;
@tracked apiKey;
@tracked apiHost;
@tracked endpointMode = 'saas';

get saveTaskKey() {
return 'organization:vroom-settings';
}

constructor(owner, args) {
super(owner, args);
args?.controller?.registerSaveTask(this.saveTaskKey, this.saveVroomSettings);
this.loadVroomSettings.perform();
}

willDestroy() {
super.willDestroy(...arguments);
this.controller?.unregisterSaveTask(this.saveTaskKey);
}

get controller() {
return this.args.controller;
}

get isActive() {
return this.controller?.optimizationEngine === 'vroom';
}

@task *loadVroomSettings() {
try {
const { api_key, api_host, endpoint_mode } = yield this.fetch.get('settings', {}, { namespace: 'vroom/int/v1' });
this.apiKey = api_key;
this.apiHost = api_host;
this.endpointMode = endpoint_mode ?? 'saas';
this.useOwnServer = Boolean(
(typeof api_key === 'string' && api_key.trim() !== '') ||
(typeof api_host === 'string' && api_host.trim() !== '') ||
(typeof endpoint_mode === 'string' && endpoint_mode.trim() !== '')
);
} catch (err) {
debug(`VROOM : Error fetching organization vroom settings: ${err.message}`);
}
}

@task *saveVroomSettings() {
if (!this.isActive) {
return true;
}

try {
yield this.fetch.post(
'settings',
{
api_key: this.useOwnServer ? this.apiKey : null,
api_host: this.useOwnServer ? this.apiHost : null,
endpoint_mode: this.useOwnServer ? this.endpointMode : null,
},
{ namespace: 'vroom/int/v1' }
);
} catch (err) {
debug(`VROOM : Error saving organization vroom settings: ${err.message}`);
this.notifications.serverError(err);
}
}
}
3 changes: 0 additions & 3 deletions addon/components/vroom-settings.hbs

This file was deleted.

35 changes: 0 additions & 35 deletions addon/components/vroom-settings.js

This file was deleted.

5 changes: 3 additions & 2 deletions addon/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ export default {
// Register VROOM Route Optimization
universe.whenEngineLoaded('@fleetbase/fleetops-engine', this.registerVroom);

// Register settings component
universe.registerRenderableComponent('fleet-ops:template:settings:routing', new ExtensionComponent('@fleetbase/vroom-engine', 'vroom-settings'));
// Register settings components
universe.registerRenderableComponent('fleet-ops:template:settings:routing', new ExtensionComponent('@fleetbase/vroom-engine', 'organization/vroom-settings'));
universe.registerRenderableComponent('fleet-ops:component:admin:routing-settings', new ExtensionComponent('@fleetbase/vroom-engine', 'admin/vroom-settings'));
},

async registerVroom(fleetopsEngine, universe) {
Expand Down
1 change: 1 addition & 0 deletions app/components/admin/vroom-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@fleetbase/vroom-engine/components/admin/vroom-settings';
1 change: 1 addition & 0 deletions app/components/organization/vroom-settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@fleetbase/vroom-engine/components/organization/vroom-settings';
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fleetbase/vroom-api",
"version": "0.0.3",
"version": "0.0.4",
"description": "VROOM route optimization machine extension for Fleetbase",
"keywords": [
"fleetbase",
Expand Down
2 changes: 1 addition & 1 deletion extension.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vroom",
"version": "0.0.3",
"version": "0.0.4",
"description": "VROOM route optimization machine integration",
"repository": "https://github.com/fleetbase/vroom",
"license": "AGPL-3.0-or-later",
Expand Down
58 changes: 29 additions & 29 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fleetbase/vroom-engine",
"version": "0.0.3",
"version": "0.0.4",
"description": "VROOM route optimization machine extension for Fleetbase",
"keywords": [
"fleetbase-extension",
Expand Down Expand Up @@ -41,64 +41,64 @@
"publish:github": "npm config set '@fleetbase:registry' https://npm.pkg.github.com/ && npm publish"
},
"dependencies": {
"@babel/core": "^7.23.2",
"@fleetbase/ember-core": "^0.3.8",
"@fleetbase/ember-ui": "^0.3.14",
"@babel/core": "^7.27.1",
"@fleetbase/ember-core": "^0.3.18",
"@fleetbase/ember-ui": "^0.3.29",
"@fortawesome/ember-fontawesome": "^2.0.0",
"@fortawesome/fontawesome-svg-core": "6.4.0",
"@fortawesome/free-brands-svg-icons": "6.4.0",
"@fortawesome/free-solid-svg-icons": "6.4.0",
"broccoli-funnel": "^3.0.8",
"ember-auto-import": "^2.7.4",
"ember-auto-import": "^2.10.0",
"ember-cli-babel": "^8.2.0",
"ember-cli-htmlbars": "^6.3.0",
"ember-intl": "6.3.2",
"ember-radio-button": "^3.0.0-beta.1",
"ember-radio-button": "3.0.0-beta.1",
"ember-wormhole": "^0.6.0"
},
"devDependencies": {
"@babel/eslint-parser": "^7.22.15",
"@babel/plugin-proposal-decorators": "^7.23.2",
"@ember/optional-features": "^2.0.0",
"@ember/test-helpers": "^3.2.0",
"@embroider/test-setup": "^3.0.2",
"@babel/eslint-parser": "^7.27.1",
"@babel/plugin-proposal-decorators": "^7.27.1",
"@ember/optional-features": "^2.2.0",
"@ember/test-helpers": "^3.3.1",
"@embroider/test-setup": "^3.0.3",
"@glimmer/component": "^1.1.2",
"@glimmer/tracking": "^1.1.2",
"broccoli-asset-rev": "^3.0.0",
"concurrently": "^8.2.2",
"ember-cli": "~5.4.1",
"ember-cli": "~5.4.2",
"ember-cli-clean-css": "^3.0.0",
"ember-cli-dependency-checker": "^3.3.2",
"ember-cli-dependency-checker": "^3.3.3",
"ember-cli-inject-live-reload": "^2.1.0",
"ember-cli-sri": "^2.1.1",
"ember-cli-terser": "^4.0.2",
"ember-composable-helpers": "^5.0.0",
"ember-concurrency": "^4.0.4",
"ember-data": "^4.12.5",
"ember-data": "^4.12.8",
"ember-engines": "^0.9.0",
"ember-load-initializers": "^2.1.2",
"ember-math-helpers": "^4.0.0",
"ember-page-title": "^8.0.0",
"ember-qunit": "^8.0.1",
"ember-math-helpers": "^4.2.1",
"ember-page-title": "^8.2.4",
"ember-qunit": "^8.1.1",
"ember-resolver": "^11.0.1",
"ember-source": "~5.4.0",
"ember-source": "~5.4.1",
"ember-source-channel-url": "^3.0.0",
"ember-template-lint": "^5.11.2",
"ember-template-lint": "^5.13.0",
"ember-try": "^3.0.0",
"eslint": "^8.52.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-ember": "^11.11.1",
"eslint-plugin-n": "^16.2.0",
"eslint-plugin-prettier": "^5.0.1",
"eslint-plugin-qunit": "^8.0.1",
"eslint": "^8.57.1",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-ember": "^11.12.0",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-prettier": "^5.4.0",
"eslint-plugin-qunit": "^8.1.2",
"loader.js": "^4.7.0",
"prettier": "^3.0.3",
"qunit": "^2.20.0",
"prettier": "^3.5.3",
"qunit": "^2.24.1",
"qunit-dom": "^2.0.0",
"stylelint": "^15.11.0",
"stylelint-config-standard": "^34.0.0",
"stylelint-prettier": "^4.0.2",
"webpack": "^5.89.0"
"stylelint-prettier": "^4.1.0",
"webpack": "^5.99.9"
},
"peerDependencies": {
"ember-engines": "^0.9.0"
Expand Down
Loading
Loading