mirror of
https://github.com/fleetbase/fleetbase.git
synced 2026-01-10 16:29:07 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e8f5638cad | ||
|
|
e216f11f7c | ||
|
|
41064be1ff | ||
|
|
ae17ccb199 | ||
|
|
0fbf901c9d | ||
|
|
00806d4f0c | ||
|
|
e8249adddd | ||
|
|
21ea3f5644 | ||
|
|
727b2e399f | ||
|
|
ec913f82d7 | ||
|
|
7acf97a5e0 | ||
|
|
914a5abacb | ||
|
|
fdcd3bb805 | ||
|
|
5a4d6846b5 | ||
|
|
f52c1a17b8 | ||
|
|
c44e9186d5 | ||
|
|
02408b3a12 | ||
|
|
a3d3cb05cf | ||
|
|
604365fc5f | ||
|
|
5d47dc676f | ||
|
|
50b58a5955 | ||
|
|
948db173c9 | ||
|
|
4f56e04166 | ||
|
|
d9705bf4f4 |
@@ -9,9 +9,9 @@
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"fleetbase/core-api": "^1.3.12",
|
||||
"fleetbase/fleetops-api": "^0.4.1",
|
||||
"fleetbase/storefront-api": "^0.2.8",
|
||||
"fleetbase/core-api": "^1.3.13",
|
||||
"fleetbase/fleetops-api": "^0.4.4",
|
||||
"fleetbase/storefront-api": "^0.2.9",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"laravel/framework": "^8.75",
|
||||
|
||||
699
api/composer.lock
generated
699
api/composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -13,7 +13,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
||||
'default' => env('FILESYSTEM_DRIVER', 'public'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -127,6 +127,15 @@ export default class AuthVerificationController extends Controller {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow user to manually trigger no code received prompt.
|
||||
*
|
||||
* @memberof AuthVerificationController
|
||||
*/
|
||||
@action onDidntReceiveCode() {
|
||||
this.stillWaiting = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the input
|
||||
*
|
||||
|
||||
21
console/app/instance-initializers/register-app-version.js
Normal file
21
console/app/instance-initializers/register-app-version.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import config from 'ember-get-config';
|
||||
|
||||
export function initialize(owner) {
|
||||
const universe = owner.lookup('service:universe');
|
||||
|
||||
if (universe) {
|
||||
universe.registerOrganizationMenuItem(`v${config.version}`, {
|
||||
index: 4,
|
||||
route: null,
|
||||
icon: 'code-branch',
|
||||
iconSize: 'xs',
|
||||
iconClass: 'mr-1.5',
|
||||
wrapperClass: 'app-version-in-nav',
|
||||
overwriteWrapperClass: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
initialize,
|
||||
};
|
||||
44
console/app/models/comment.js
Normal file
44
console/app/models/comment.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import Model, { attr, belongsTo, hasMany } from '@ember-data/model';
|
||||
import { computed } from '@ember/object';
|
||||
import { format, formatDistanceToNow } from 'date-fns';
|
||||
|
||||
export default class CommentModel extends Model {
|
||||
/** @ids */
|
||||
@attr('string') company_uuid;
|
||||
@attr('string') parent_comment_uuid;
|
||||
@attr('string') subject_uuid;
|
||||
@attr('string') subject_type;
|
||||
|
||||
/** @relationships */
|
||||
@belongsTo('user') author;
|
||||
@belongsTo('comment', { inverse: 'replies' }) parent;
|
||||
@hasMany('comment', { inverse: 'parent' }) replies;
|
||||
|
||||
/** @attributes */
|
||||
@attr('string') content;
|
||||
@attr('boolean') editable;
|
||||
@attr('raw') tags;
|
||||
@attr('raw') meta;
|
||||
|
||||
/** @dates */
|
||||
@attr('date') created_at;
|
||||
@attr('date') updated_at;
|
||||
@attr('date') deleted_at;
|
||||
|
||||
/** @computed */
|
||||
@computed('created_at') get createdAgo() {
|
||||
return formatDistanceToNow(this.created_at);
|
||||
}
|
||||
|
||||
@computed('created_at') get createdAt() {
|
||||
return format(this.created_at, 'PPP p');
|
||||
}
|
||||
|
||||
@computed('updated_at') get updatedAgo() {
|
||||
return formatDistanceToNow(this.updated_at);
|
||||
}
|
||||
|
||||
@computed('updated_at') get updatedAt() {
|
||||
return format(this.updated_at, 'PPP p');
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ Router.map(function () {
|
||||
this.route('auth', function () {
|
||||
this.route('login', { path: '/' });
|
||||
this.route('forgot-password');
|
||||
this.route('reset-password');
|
||||
this.route('reset-password', { path: '/reset-password/:id' });
|
||||
this.route('two-fa');
|
||||
this.route('verification');
|
||||
});
|
||||
@@ -50,26 +50,6 @@ Router.map(function () {
|
||||
this.route('two-fa-settings');
|
||||
this.route('virtual', { path: '/:slug/:view' });
|
||||
});
|
||||
|
||||
this.mount('@fleetbase/dev-engine', {
|
||||
as: 'developers',
|
||||
path: 'developers'
|
||||
});
|
||||
|
||||
this.mount('@fleetbase/fleetops-engine', {
|
||||
as: 'fleet-ops',
|
||||
path: 'fleet-ops'
|
||||
});
|
||||
|
||||
this.mount('@fleetbase/iam-engine', {
|
||||
as: 'iam',
|
||||
path: 'iam'
|
||||
});
|
||||
|
||||
this.mount('@fleetbase/storefront-engine', {
|
||||
as: 'storefront',
|
||||
path: 'storefront'
|
||||
});
|
||||
});
|
||||
this.route('install');
|
||||
});
|
||||
|
||||
@@ -4,7 +4,14 @@ import { inject as service } from '@ember/service';
|
||||
export default class AuthResetPasswordRoute extends Route {
|
||||
@service store;
|
||||
|
||||
model() {
|
||||
return this.store.findRecord('brand', 1);
|
||||
async model(params) {
|
||||
return params;
|
||||
}
|
||||
|
||||
async setupController(controller) {
|
||||
super.setupController(...arguments);
|
||||
|
||||
// set brand to controller
|
||||
this.brand = await this.store.findRecord('brand', 1);
|
||||
}
|
||||
}
|
||||
|
||||
38
console/app/serializers/comment.js
Normal file
38
console/app/serializers/comment.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
|
||||
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
|
||||
|
||||
export default class CommentSerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
|
||||
/**
|
||||
* Embedded relationship attributes
|
||||
*
|
||||
* @var {Object}
|
||||
*/
|
||||
get attrs() {
|
||||
return {
|
||||
author: { embedded: 'always' },
|
||||
parent: { embedded: 'always' },
|
||||
replies: { embedded: 'always' },
|
||||
};
|
||||
}
|
||||
|
||||
serializeAttribute(snapshot, json, key, attributes) {
|
||||
if (key === 'editable') {
|
||||
return;
|
||||
}
|
||||
|
||||
super.serializeAttribute(...arguments);
|
||||
}
|
||||
|
||||
serializeHasMany(snapshot, json, relationship) {
|
||||
let key = relationship.key;
|
||||
if (key === 'replies') {
|
||||
return;
|
||||
} else {
|
||||
super.serializeHasMany(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
serializeBelongsTo() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,8 @@
|
||||
color: rgb(202 138 4);
|
||||
}
|
||||
|
||||
body[data-theme='dark'] .btn.btn-warning-alert.btn-warning,
|
||||
.btn.btn-warning-alert.btn-warning,
|
||||
.two-fa-enforcement-alert button#two-fa-setup-button.btn.btn-warning,
|
||||
body[data-theme='dark'] .two-fa-enforcement-alert button#two-fa-setup-button.btn.btn-warning {
|
||||
background-color: rgb(202 138 4);
|
||||
@@ -11,3 +13,13 @@ body[data-theme='dark'] .two-fa-enforcement-alert button#two-fa-setup-button.btn
|
||||
color: rgb(254 249 195);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.app-version-in-nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
|
||||
font-size: 0.8rem;
|
||||
line-height: 1rem;
|
||||
padding-left: 1rem;
|
||||
padding-top: 0.2rem;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<div class="bg-white dark:bg-gray-800 py-8 px-4 shadow rounded-lg">
|
||||
<div class="mb-4">
|
||||
<Image src={{@model.logo_url}} @fallbackSrc="/images/fleetbase-logo-svg.svg" alt={{t "app.name"}} width="160" height="56" class="w-40 h-14 mx-auto" />
|
||||
<Image src={{this.brand.logo_url}} @fallbackSrc="/images/fleetbase-logo-svg.svg" alt={{t "app.name"}} width="160" height="56" class="w-40 h-14 mx-auto" />
|
||||
<h2 class="text-center text-lg font-extrabold text-gray-900 dark:text-white truncate">
|
||||
{{t "auth.reset-password.title"}}
|
||||
</h2>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{{page-title "Account Verification"}}
|
||||
{{page-title (t "auth.verification.header-title")}}
|
||||
|
||||
<div class="bg-white dark:bg-gray-800 py-8 px-4 shadow rounded-lg w-full">
|
||||
<div class="mb-8">
|
||||
<img class="mx-auto h-12 w-auto " src="/images/fleetbase-logo-svg.svg" alt={{t "app.name"}}>
|
||||
<h2 class="mt-6 text-center text-lg font-extrabold text-gray-900 dark:text-white truncate">
|
||||
Verify your email address
|
||||
{{t "auth.verification.title"}}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
@@ -12,15 +13,16 @@
|
||||
<FaIcon @icon="shield-check" @size="lg" class="text-blue-900 mr-4" />
|
||||
</div>
|
||||
<p class="flex-1 text-sm text-blue-900 dark:text-blue-900">
|
||||
<strong>Almost done!</strong><br> Check your email for a verification code.
|
||||
{{t "auth.verification.message-text" htmlSafe=true}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form class="mt-8 space-y-6" {{on "submit" this.verifyCode}}>
|
||||
<InputGroup @type="tel" @name="Verification Code" @value={{this.code}} @helpText="Enter the verification code you received via email." @inputClass="input-lg" {{on "input" this.validateInput}} />
|
||||
<InputGroup @type="tel" @name={{t "auth.verification.verification-input-label"}} @value={{this.code}} @helpText={{t "auth.verification.verification-code-text"}} @inputClass="input-lg" {{on "input" this.validateInput}} />
|
||||
|
||||
<div>
|
||||
<div class="flex flex-row items-center space-x-4">
|
||||
<Button @icon="check" @iconPrefix="fas" @buttonType="submit" @type="primary" @size="lg" @text="Verify & Continue" @isLoading={{this.isLoading}} @disabled={{this.isNotReadyToSubmit}} @onClick={{this.verifyCode}} />
|
||||
<a href="#" {{on "click" this.onDidntReceiveCode}} class="text-sm text-blue-400 hover:text-blue-300">{{t "auth.verification.didnt-receive-a-code"}}</a>
|
||||
</div>
|
||||
|
||||
{{#if this.stillWaiting}}
|
||||
@@ -30,14 +32,14 @@
|
||||
<FaIcon @icon="exclamation-triangle" @size="lg" class="text-yellow-400" />
|
||||
</div>
|
||||
<div class="ml-3 flex items-center">
|
||||
<span class="text-lg font-extrabold text-yellow-800">Didn't receive an email yet?</span>
|
||||
<span class="text-lg font-extrabold text-yellow-800">{{t "auth.verification.didnt-receive-a-code"}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<p class="text-yellow-700">Use alternaitve options below to verify your account.</p>
|
||||
<div class="py-1">
|
||||
<p class="text-yellow-700 text-sm">{{t "auth.verification.not-sent.alternative-choice"}}</p>
|
||||
<div class="flex items-center mt-3">
|
||||
<Button @type="default" class="mr-2" @onClick={{this.resendEmail}}>Resend Email</Button>
|
||||
<Button @type="default" @onClick={{this.resendBySms}}>Send by SMS</Button>
|
||||
<Button @buttonType="button" @type="warning" @wrapperClass="mr-2" @onClick={{this.resendEmail}} class="btn-warning-alert">{{t "auth.verification.not-sent.resend-email"}}</Button>
|
||||
<Button @buttonType="button" @type="warning" @onClick={{this.resendBySms}} class="btn-warning-alert">{{t "auth.verification.not-sent.send-by-sms"}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -6,12 +6,20 @@
|
||||
<Layout::Sidebar::Item @route="console.admin.notifications" @icon="bell">{{t "common.notifications"}}</Layout::Sidebar::Item>
|
||||
<Layout::Sidebar::Item @route="console.admin.two-fa-settings" @icon="shield-halved">{{t "common.2fa-config"}}</Layout::Sidebar::Item>
|
||||
{{#each this.universe.adminMenuItems as |menuItem|}}
|
||||
<Layout::Sidebar::Item @onClick={{fn this.universe.transitionMenuItem "console.admin.virtual" menuItem}} @item={{menuItem}} @icon={{menuItem.icon}}>{{menuItem.title}}</Layout::Sidebar::Item>
|
||||
<Layout::Sidebar::Item
|
||||
@onClick={{fn this.universe.transitionMenuItem "console.admin.virtual" menuItem}}
|
||||
@item={{menuItem}}
|
||||
@icon={{menuItem.icon}}
|
||||
>{{menuItem.title}}</Layout::Sidebar::Item>
|
||||
{{/each}}
|
||||
{{#each this.universe.adminMenuPanels as |menuPanel|}}
|
||||
<Layout::Sidebar::Panel @open={{menuPanel.open}} @title={{menuPanel.title}}>
|
||||
{{#each menuPanel.items as |menuItem|}}
|
||||
<Layout::Sidebar::Item @onClick={{fn this.universe.transitionMenuItem "console.admin.virtual" menuItem}} @item={{menuItem}} @icon={{menuItem.icon}}>{{menuItem.title}}</Layout::Sidebar::Item>
|
||||
<Layout::Sidebar::Item
|
||||
@onClick={{fn this.universe.transitionMenuItem "console.admin.virtual" menuItem}}
|
||||
@item={{menuItem}}
|
||||
@icon={{menuItem.icon}}
|
||||
>{{menuItem.title}}</Layout::Sidebar::Item>
|
||||
{{/each}}
|
||||
</Layout::Sidebar::Panel>
|
||||
{{/each}}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<FaIcon @icon="hand-spock" @size="lg" class="text-blue-900 mr-4" />
|
||||
</div>
|
||||
<p class="flex-1 text-sm text-blue-900 dark:text-blue-900">
|
||||
{{t "onboard.index.welcome-title" htnmlSafe=true companyName=(t "app.name")}}
|
||||
{{t "onboard.index.welcome-title" htmlSafe=true companyName=(t "app.name")}}
|
||||
{{t "onboard.index.welcome-text"}}
|
||||
</p>
|
||||
</div>
|
||||
@@ -20,17 +20,17 @@
|
||||
{{#if this.error}}
|
||||
<InfoBlock @icon="exclamation-triangle" @text={{this.error}} class="mb-6 px-3 py-2 bg-red-300 text-red-900" @textClass="text-red-900" />
|
||||
{{/if}}
|
||||
<InputGroup @name={{t "onboard.index.full-name"}} @value={{this.name}} @helpText={{t "onboard.index.full-name"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.your-email"}} @type="email" @value={{this.email}} @helpText={{t "onboard.index.your-email"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "common.phone"}} @helpText={{t "onboard.index.phone"}}>
|
||||
<InputGroup @name={{t "onboard.index.full-name"}} @value={{this.name}} @helpText={{t "onboard.index.full-name-help-text"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.your-email"}} @type="email" @value={{this.email}} @helpText={{t "onboard.index.your-email-help-text"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.phone"}} @helpText={{t "onboard.index.phone-help-text"}}>
|
||||
<PhoneInput @onInput={{fn (mut this.phone)}} class="form-input input-lg w-full" />
|
||||
</InputGroup>
|
||||
<InputGroup @name={{t "onboard.index.organization-name"}} @value={{this.organization_name}} @helpText={{t "onboard.index.organization-name"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.password"}} @value={{this.password}} @type="password" @helpText={{t "onboard.index.password"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.confirm-password"}} @value={{this.password_confirmation}} @type="password" @helpText={{t "onboard.index.confirm-password"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.organization-name"}} @value={{this.organization_name}} @helpText={{t "onboard.index.organization-help-text"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.password"}} @value={{this.password}} @type="password" @helpText={{t "onboard.index.password-help-text"}} @inputClass="input-lg" />
|
||||
<InputGroup @name={{t "onboard.index.confirm-password"}} @value={{this.password_confirmation}} @type="password" @helpText={{t "onboard.index.confirm-password-help-text"}} @inputClass="input-lg" />
|
||||
|
||||
<div class="flex items-center justify-end mt-5">
|
||||
<Button @icon="check" @iconPrefix="fas" @type="primary" @size="lg" @text={{t "onboard.index.continue-button"}} @isLoading={{this.isLoading}} @disabled={{this.readyToSubmit}} @onClick={{this.startOnboard}} />
|
||||
<Button @icon="check" @iconPrefix="fas" @type="primary" @size="lg" @text={{t "onboard.index.continue-button-text"}} @isLoading={{this.isLoading}} @disabled={{this.readyToSubmit}} @onClick={{this.startOnboard}} />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,7 +1,8 @@
|
||||
{{page-title "Account Verification"}}
|
||||
{{page-title (t "onboard.verify-email.header-title")}}
|
||||
|
||||
<div class="bg-white dark:bg-gray-800 py-8 px-4 shadow rounded-lg w-full">
|
||||
<div class="mb-8">
|
||||
<img class="mx-auto h-12 w-auto" src="/images/fleetbase-logo-svg.svg" alt={{t "app.name"}}>
|
||||
<img class="mx-auto h-12 w-auto " src="/images/fleetbase-logo-svg.svg" alt={{t "app.name"}}>
|
||||
<h2 class="mt-6 text-center text-lg font-extrabold text-gray-900 dark:text-white truncate">
|
||||
{{t "onboard.verify-email.title"}}
|
||||
</h2>
|
||||
@@ -12,15 +13,16 @@
|
||||
<FaIcon @icon="shield-check" @size="lg" class="text-blue-900 mr-4" />
|
||||
</div>
|
||||
<p class="flex-1 text-sm text-blue-900 dark:text-blue-900">
|
||||
{{t "onboard.verify-email.message-text" htnmlSafe=true}}
|
||||
{{t "onboard.verify-email.message-text" htmlSafe=true}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<form class="mt-8 space-y-6" {{on "submit" this.verifyCode}}>
|
||||
<InputGroup @type="tel" @name="Verification Code" @value={{this.code}} @helpText={{t "onboard.verify-email.verification-code-text"}} @inputClass="input-lg" {{on "input" this.validateInput}} />
|
||||
<InputGroup @type="tel" @name={{t "onboard.verify-email.verification-input-label"}} @value={{this.code}} @helpText={{t "onboard.verify-email.verification-code-text"}} @inputClass="input-lg" {{on "input" this.validateInput}} />
|
||||
|
||||
<div>
|
||||
<Button @icon="check" @iconPrefix="fas" @buttonType="submit" @type="primary" @size="lg" @text={{t "onboard.verify-email.verify-button-text"}} @isLoading={{this.isLoading}} @disabled={{this.isNotReadyToSubmit}} @onClick={{this.verifyCode}} />
|
||||
<div class="flex flex-row items-center space-x-4">
|
||||
<Button @icon="check" @iconPrefix="fas" @buttonType="submit" @type="primary" @size="lg" @text="Verify & Continue" @isLoading={{this.isLoading}} @disabled={{this.isNotReadyToSubmit}} @onClick={{this.verifyCode}} />
|
||||
<a href="#" {{on "click" this.onDidntReceiveCode}} class="text-sm text-blue-400 hover:text-blue-300">{{t "onboard.verify-email.didnt-receive-a-code"}}</a>
|
||||
</div>
|
||||
|
||||
{{#if this.stillWaiting}}
|
||||
@@ -30,14 +32,14 @@
|
||||
<FaIcon @icon="exclamation-triangle" @size="lg" class="text-yellow-400" />
|
||||
</div>
|
||||
<div class="ml-3 flex items-center">
|
||||
<span class="text-lg font-extrabold text-yellow-800">{{t "onboard.verify-email.not-sent.message"}}</span>
|
||||
<span class="text-lg font-extrabold text-yellow-800">{{t "onboard.verify-email.didnt-receive-a-code"}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="py-3">
|
||||
<p class="text-yellow-700">{{t "onboard.verify-email.not-sent.alternative-choice"}}</p>
|
||||
<div class="py-1">
|
||||
<p class="text-yellow-700 text-sm">{{t "onboard.verify-email.not-sent.alternative-choice"}}</p>
|
||||
<div class="flex items-center mt-3">
|
||||
<Button @type="default" class="mr-2" @onClick={{this.resendEmail}}>{{t "onboard.verify-email.not-sent.resent-button-text"}}</Button>
|
||||
<Button @type="default" @onClick={{this.resendBySms}}>{{t "onboard.verify-email.not-sent.sms-button-text"}}</Button>
|
||||
<Button @buttonType="button" @type="warning" @wrapperClass="mr-2" @onClick={{this.resendEmail}} class="btn-warning-alert">{{t "onboard.verify-email.not-sent.resend-email"}}</Button>
|
||||
<Button @buttonType="button" @type="warning" @onClick={{this.resendBySms}} class="btn-warning-alert">{{t "onboard.verify-email.not-sent.send-by-sms"}}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
const toBoolean = require('./utils/to-boolean');
|
||||
const getenv = require('./utils/getenv');
|
||||
const fixApiHost = require('./utils/fix-api-host');
|
||||
const { version } = require('../package');
|
||||
|
||||
module.exports = function (environment) {
|
||||
const ENV = {
|
||||
modulePrefix: '@fleetbase/console',
|
||||
version,
|
||||
environment,
|
||||
rootURL: '/',
|
||||
locationType: 'history',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@fleetbase/console",
|
||||
"version": "0.3.8",
|
||||
"version": "0.3.10",
|
||||
"private": true,
|
||||
"description": "Fleetbase Console",
|
||||
"repository": "https://github.com/fleetbase/fleetbase",
|
||||
@@ -27,11 +27,11 @@
|
||||
"test:ember": "ember test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fleetbase/ember-core": "^0.2.0",
|
||||
"@fleetbase/ember-ui": "^0.2.9",
|
||||
"@fleetbase/storefront-engine": "^0.2.8",
|
||||
"@fleetbase/fleetops-engine": "^0.4.1",
|
||||
"@fleetbase/fleetops-data": "^0.1.7",
|
||||
"@fleetbase/ember-core": "^0.2.1",
|
||||
"@fleetbase/ember-ui": "^0.2.10",
|
||||
"@fleetbase/storefront-engine": "^0.2.9",
|
||||
"@fleetbase/fleetops-engine": "^0.4.4",
|
||||
"@fleetbase/fleetops-data": "^0.1.8",
|
||||
"@fleetbase/dev-engine": "^0.2.1",
|
||||
"@fleetbase/iam-engine": "^0.0.9",
|
||||
"@fleetbase/leaflet-routing-machine": "^3.2.16",
|
||||
@@ -137,9 +137,9 @@
|
||||
},
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"@fleetbase/fleetops-data": "^0.1.7",
|
||||
"@fleetbase/ember-core": "^0.2.0",
|
||||
"@fleetbase/ember-ui": "^0.2.9"
|
||||
"@fleetbase/fleetops-data": "^0.1.8",
|
||||
"@fleetbase/ember-core": "^0.2.1",
|
||||
"@fleetbase/ember-ui": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
|
||||
3243
console/pnpm-lock.yaml
generated
3243
console/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@ Router.map(function () {
|
||||
this.route('auth', function () {
|
||||
this.route('login', { path: '/' });
|
||||
this.route('forgot-password');
|
||||
this.route('reset-password');
|
||||
this.route('reset-password', { path: '/reset-password/:id' });
|
||||
this.route('two-fa');
|
||||
this.route('verification');
|
||||
});
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import Application from '@ember/application';
|
||||
|
||||
import config from '@fleetbase/console/config/environment';
|
||||
import { initialize } from '@fleetbase/console/instance-initializers/register-app-version';
|
||||
import { module, test } from 'qunit';
|
||||
import Resolver from 'ember-resolver';
|
||||
import { run } from '@ember/runloop';
|
||||
|
||||
module('Unit | Instance Initializer | register-app-version', function (hooks) {
|
||||
hooks.beforeEach(function () {
|
||||
this.TestApplication = class TestApplication extends Application {
|
||||
modulePrefix = config.modulePrefix;
|
||||
podModulePrefix = config.podModulePrefix;
|
||||
Resolver = Resolver;
|
||||
};
|
||||
|
||||
this.TestApplication.instanceInitializer({
|
||||
name: 'initializer under test',
|
||||
initialize,
|
||||
});
|
||||
|
||||
this.application = this.TestApplication.create({
|
||||
autoboot: false,
|
||||
});
|
||||
|
||||
this.instance = this.application.buildInstance();
|
||||
});
|
||||
hooks.afterEach(function () {
|
||||
run(this.instance, 'destroy');
|
||||
run(this.application, 'destroy');
|
||||
});
|
||||
|
||||
// TODO: Replace this with your real tests.
|
||||
test('it works', async function (assert) {
|
||||
await this.instance.boot();
|
||||
|
||||
assert.ok(true);
|
||||
});
|
||||
});
|
||||
14
console/tests/unit/models/comment-test.js
Normal file
14
console/tests/unit/models/comment-test.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
import { setupTest } from '@fleetbase/console/tests/helpers';
|
||||
|
||||
module('Unit | Model | comment', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let model = store.createRecord('comment', {});
|
||||
assert.ok(model);
|
||||
});
|
||||
});
|
||||
24
console/tests/unit/serializers/comment-test.js
Normal file
24
console/tests/unit/serializers/comment-test.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import { module, test } from 'qunit';
|
||||
|
||||
import { setupTest } from '@fleetbase/console/tests/helpers';
|
||||
|
||||
module('Unit | Serializer | comment', function (hooks) {
|
||||
setupTest(hooks);
|
||||
|
||||
// Replace this with your real tests.
|
||||
test('it exists', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let serializer = store.serializerFor('comment');
|
||||
|
||||
assert.ok(serializer);
|
||||
});
|
||||
|
||||
test('it serializes records', function (assert) {
|
||||
let store = this.owner.lookup('service:store');
|
||||
let record = store.createRecord('comment', {});
|
||||
|
||||
let serializedRecord = record.serialize();
|
||||
|
||||
assert.ok(serializedRecord);
|
||||
});
|
||||
});
|
||||
@@ -13,6 +13,9 @@ terms:
|
||||
search: Search
|
||||
search-input: Search Input
|
||||
common:
|
||||
edit: Edit
|
||||
save: Save
|
||||
cancel: Cancel
|
||||
2fa-config: 2FA Config
|
||||
account: Account
|
||||
admin: Admin
|
||||
@@ -46,11 +49,52 @@ common:
|
||||
two-factor: Two Factor
|
||||
uploading: Uploading...
|
||||
your-profile: Your Profile
|
||||
component:
|
||||
component:
|
||||
file:
|
||||
dropdown-label: File actions
|
||||
dropzone:
|
||||
file: file
|
||||
drop-to-upload: Drop to upload
|
||||
invalid: Invalid
|
||||
files-ready-for-upload: >-
|
||||
{numOfFiles} ready for upload.
|
||||
upload-images-videos: Upload Images & Videos
|
||||
upload-documents: Upload Documents
|
||||
upload-documents-files: Upload Documents & Files
|
||||
dropzone-supported-images-videos: Drag and drop image and video files onto this dropzone
|
||||
dropzone-supported-files: Drag and drop files onto this dropzone
|
||||
or-select-button-text: or select files to upload.
|
||||
upload-queue: Upload Queue
|
||||
uploading: Uploading...
|
||||
two-fa-enforcement-alert:
|
||||
message: To enhance the security of your account, your organization requires Two-Factor Authentication (2FA). Enable 2FA in your account settings for an additional layer of protection.
|
||||
button-text: Setup 2FA
|
||||
comment-thread:
|
||||
publish-comment-button-text: Publish comment
|
||||
publish-reply-button-text: Publish reply
|
||||
reply-comment-button-text: Reply
|
||||
edit-comment-button-text: Edit
|
||||
delete-comment-button-text: Delete
|
||||
comment-published-ago: >-
|
||||
{createdAgo} ago
|
||||
comment-input-placeholder: Input a new comment...
|
||||
comment-reply-placeholder: Input your reply...
|
||||
comment-input-empty-notification: You cannot publish empty comments...
|
||||
comment-min-length-notification: Comment must be atleast 2 characters
|
||||
auth:
|
||||
verification:
|
||||
header-title: Account Verification
|
||||
title: Verify your email address
|
||||
message-text: <strong>Almost done!</strong><br> Check your email for a verification code.
|
||||
verification-code-text: Enter the verification code you received via email.
|
||||
verification-input-label: Verification Code
|
||||
verify-button-text: Verify & Continue
|
||||
didnt-receive-a-code: Didn't receive a code yet?
|
||||
not-sent:
|
||||
message: Didn't receive a code yet?
|
||||
alternative-choice: Use alternaitve options below to verify your account.
|
||||
resend-email: Resend Email
|
||||
send-by-sms: Send by SMS
|
||||
two-fa:
|
||||
verify-code:
|
||||
invalid-session-error-notification: Invalid session. Please try again.
|
||||
@@ -174,23 +218,32 @@ onboard:
|
||||
title: Create your account
|
||||
welcome-title: <strong>Welcome to {companyName}!</strong><br />
|
||||
welcome-text: Complete the details required below to get started.
|
||||
full-name: Your full name.
|
||||
your-email: Your email address.
|
||||
phone: Your phone number.
|
||||
organization-name: Your organization name, all your services and resources will be managed under this organization, later you can create as many organizations as you want or need.
|
||||
password: Your password, make sure it's a good one.
|
||||
confirm-password: Just to confirm the password you entered above.
|
||||
continue-button: Continue
|
||||
full-name: Full name
|
||||
full-name-help-text: Your full name
|
||||
your-email: Email address
|
||||
your-email-help-text: Your email address
|
||||
phone: Phone number
|
||||
phone-help-text: Your phone number
|
||||
organization-name: Organization name
|
||||
organization-help-text: Your organization name, all your services and resources will be managed under this organization, later you can create as many organizations as you want or need.
|
||||
password: Enter a password
|
||||
password-help-text: Your password, make sure it's a good one.
|
||||
confirm-password: Confirm your password
|
||||
confirm-password-help-text: Just to confirm the password you entered above.
|
||||
continue-button-text: Continue
|
||||
verify-email:
|
||||
header-title: Account Verification
|
||||
title: Verify your email address
|
||||
message-text: <strong>Almost done!</strong><br> Check your email for a verification code.
|
||||
verification-code-text: Enter the verification code you received via email.
|
||||
verification-input-label: Verification Code
|
||||
verify-button-text: Verify & Continue
|
||||
didnt-receive-a-code: Didn't receive a code yet?
|
||||
not-sent:
|
||||
message: Didn't receive an email yet?
|
||||
message: Didn't receive a code yet?
|
||||
alternative-choice: Use alternaitve options below to verify your account.
|
||||
resent-button-text: Resend Email
|
||||
sms-button-text: Send by SMS
|
||||
resend-email: Resend Email
|
||||
send-by-sms: Send by SMS
|
||||
install:
|
||||
installer-header: Installer
|
||||
failed-message-sent: The install failed! Click the button below to retry the install.
|
||||
|
||||
@@ -50,6 +50,16 @@ app.kubernetes.io/name: {{ include "helm.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "helm.commonVariables" -}}
|
||||
- name: CACHE_URL
|
||||
value: $(REDIS_SERVICE_PORT)/1
|
||||
- name: CACHE_DRIVER
|
||||
value: redis
|
||||
- name: SOCKETCLUSTER_PORT
|
||||
value: "80"
|
||||
- name: SOCKETCLUSTER_HOST
|
||||
value: $(SOCKETCLUSTER_SERVICE_HOST)
|
||||
{{- end }}
|
||||
{{/*
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
{{- if .Values.gcp }}
|
||||
apiVersion: networking.gke.io/v1
|
||||
kind: ManagedCertificate
|
||||
metadata:
|
||||
@@ -15,3 +16,4 @@ spec:
|
||||
redirectToHttps:
|
||||
enabled: true
|
||||
responseCodeName: MOVED_PERMANENTLY_DEFAULT
|
||||
{{- end }}
|
||||
|
||||
@@ -3,6 +3,7 @@ kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "helm.fullname" . }}
|
||||
labels:
|
||||
service: app
|
||||
{{- include "helm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
@@ -10,6 +11,7 @@ spec:
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
service: app
|
||||
{{- include "helm.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
@@ -18,6 +20,7 @@ spec:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
service: app
|
||||
{{- include "helm.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
@@ -59,12 +62,7 @@ spec:
|
||||
- secretRef:
|
||||
name: infra-provided-secret
|
||||
env:
|
||||
- name: CACHE_URL
|
||||
value: $(REDIS_SERVICE_PORT)/1
|
||||
- name: SOCKETCLUSTER_PORT
|
||||
value: "8000"
|
||||
- name: SOCKETCLUSTER_HOST
|
||||
value: $(SOCKETCLUSTER_SERVICE_HOST)
|
||||
{{- include "helm.commonVariables" . | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
|
||||
116
infra/helm/templates/deployment_services.yaml
Normal file
116
infra/helm/templates/deployment_services.yaml
Normal file
@@ -0,0 +1,116 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "helm.fullname" . }}-events
|
||||
labels:
|
||||
service: events
|
||||
{{- include "helm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
service: events
|
||||
{{- include "helm.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
service: events
|
||||
{{- include "helm.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "helm.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: events
|
||||
command: ["php", "artisan", "queue:work"]
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}/events:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: infra-provided-secret
|
||||
env:
|
||||
{{- include "helm.commonVariables" . | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "helm.fullname" . }}-scheduler
|
||||
labels:
|
||||
service: scheduler
|
||||
{{- include "helm.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not .Values.autoscaling.enabled }}
|
||||
replicas: {{ .Values.replicaCount }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
service: scheduler
|
||||
{{- include "helm.selectorLabels" . | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
service: scheduler
|
||||
{{- include "helm.selectorLabels" . | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
serviceAccountName: {{ include "helm.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: scheduler
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 12 }}
|
||||
image: "{{ .Values.image.repository }}/scheduler:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: infra-provided-secret
|
||||
env:
|
||||
{{- include "helm.commonVariables" . | nindent 12 }}
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
45
infra/helm/templates/hooks.yaml
Normal file
45
infra/helm/templates/hooks.yaml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-deploy"
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name | quote }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion }}
|
||||
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
annotations:
|
||||
"helm.sh/hook": pre-install,pre-upgrade
|
||||
"helm.sh/hook-weight": "0"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
name: "{{ .Release.Name }}-deploy"
|
||||
labels:
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service | quote }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name | quote }}
|
||||
helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version }}"
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
containers:
|
||||
- name: deployment-job
|
||||
securityContext:
|
||||
{{- toYaml .Values.securityContext | nindent 10 }}
|
||||
image: "{{ .Values.image.repository }}/app:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
command: ["./deploy.sh"]
|
||||
env:
|
||||
{{- include "helm.commonVariables" . | nindent 12 }}
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: infra-provided-secret
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
@@ -13,3 +13,4 @@ spec:
|
||||
name: http
|
||||
selector:
|
||||
{{- include "helm.selectorLabels" . | nindent 4 }}
|
||||
service: app
|
||||
|
||||
@@ -78,3 +78,5 @@ nodeSelector: {}
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
gcp: true
|
||||
|
||||
Submodule packages/core-api updated: b1a6b5f461...9cbad09201
Submodule packages/ember-core updated: 4282fa8828...54a45bbdaa
Submodule packages/ember-ui updated: 1ee3606ea5...e532986a5b
Submodule packages/fleetops updated: 5881b878ce...7e8d80e9cb
Submodule packages/fleetops-data updated: 5ad2d8cfcb...9d92927c9b
Submodule packages/storefront updated: cd1bb7f73e...c141dfe527
Reference in New Issue
Block a user