Compare commits

..

13 Commits

Author SHA1 Message Date
Ron
3b9a80866f Merge pull request #213 from fleetbase/dev-v0.4.5
v0.4.5
2024-02-17 18:26:25 +07:00
Ronald A. Richardson
76badbf949 patch admin organization browser; upgrade core-api; upgrade fleetops 2024-02-17 19:21:07 +08:00
Ronald A. Richardson
f968556585 hotfix organizations browsers in admin w/ more details, better querying and admin based view, upgrade of dependencies with major patches 2024-02-16 17:32:44 +07:00
Ronald A. Richardson
6d01eab305 use fixed fleetbase/laravel-mysql-spatial v1.0.2 2024-02-16 01:37:20 +07:00
Ronald A. Richardson
9406446db1 explicitly set production environment on gitlab cd workflow 2024-02-16 00:16:22 +07:00
Ronald A. Richardson
565db7bbce explicitly set production environment for cd workflows 2024-02-16 00:15:15 +07:00
Ron
003cb467e8 Merge pull request #212 from fleetbase/dev-v0.4.4
v0.4.4
2024-02-15 23:41:59 +07:00
Ronald A. Richardson
8e1b281e77 upgraded core-api v1.4.4 and fleetops v0.4.10 w/ critical patches for webhook and driver 2024-02-15 23:32:46 +07:00
Ronald A. Richardson
af4507cc87 added translations for create/join organization and migrated to use Dockerfile 2024-02-15 23:11:20 +07:00
Ronald A. Richardson
2a2c7d8426 use correct CONSOLE_HOST env variable in cors config 2024-02-14 17:05:59 +07:00
Ronald A. Richardson
077a4298b9 Update console Dockerfile to allow environment to be passed in build 2024-02-14 16:02:55 +07:00
Ron
af840d30d0 Merge pull request #211 from fleetbase/dev-v0.4.3
v0.4.3
2024-02-13 16:52:05 +08:00
Ronald A. Richardson
a253c0c6f7 Upgrade dependencies with critical patches 2024-02-13 16:50:21 +08:00
26 changed files with 670 additions and 550 deletions

View File

@@ -147,7 +147,7 @@ jobs:
run: |
set -eu
pnpm build
pnpm build --environment production
working-directory: ./console
- name: Deploy Console 🚀

View File

@@ -173,7 +173,7 @@ jobs:
run: |
set -eu
pnpm build
pnpm build --environment production
working-directory: ./console
- name: Deploy Console 🚀

View File

@@ -8,10 +8,10 @@
],
"license": "MIT",
"require": {
"php": "^7.3|^8.0",
"fleetbase/core-api": "^1.4.2",
"fleetbase/fleetops-api": "^0.4.8",
"fleetbase/storefront-api": "^0.2.11",
"php": "^8.0",
"fleetbase/core-api": "^1.4.5",
"fleetbase/fleetops-api": "^0.4.12",
"fleetbase/storefront-api": "^0.3.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^10.0",
"laravel/octane": "^2.3",

914
api/composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@ return [
'allowed_methods' => ['*'],
'allowed_origins' => array_filter(['http://localhost:4200', env('CONSOLE_HOST'), Utils::addWwwToUrl(env('CONSOLE_URL'))]),
'allowed_origins' => array_filter(['http://localhost:4200', env('CONSOLE_HOST'), Utils::addWwwToUrl(env('CONSOLE_HOST'))]),
'allowed_origins_patterns' => [],

View File

@@ -8,6 +8,9 @@ WORKDIR /app
RUN mkdir -p ~/.pnpm
ENV PNPM_HOME /root/.pnpm
# Set environment
ARG ENVIRONMENT=production
# Add the pnpm global bin to the PATH
ENV PATH /root/.pnpm/bin:$PATH
@@ -33,7 +36,7 @@ RUN pnpm install
COPY console .
# Build the application
RUN pnpm build
RUN pnpm build --environment $ENVIRONMENT
# ---- Serve Stage ----
FROM nginx:alpine

View File

@@ -2,6 +2,7 @@ import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
import { action } from '@ember/object';
import { inject as service } from '@ember/service';
/**
* Controller responsible for handling two-factor authentication.
* @class AuthTwoFaController
@@ -53,6 +54,8 @@ export default class AuthTwoFaController extends Controller {
/**
* The current 2FA identity in memory
* @property {string} identity
* @tracked
*/
@tracked identity;

View File

@@ -51,6 +51,13 @@ export default class ConsoleController extends Controller {
*/
@service router;
/**
* Inject the `intl` service.
*
* @var {Service}
*/
@service intl;
/**
* Inject the `universe` service.
*
@@ -205,8 +212,8 @@ export default class ConsoleController extends Controller {
const country = this.currentUser.country;
this.modalsManager.show('modals/create-or-join-org', {
title: 'Create or join a organization',
acceptButtonText: 'Confirm',
title: this.intl.t('console.create-or-join-organization.modal-title'),
acceptButtonText: this.intl.t('common.confirm'),
acceptButtonIcon: 'check',
acceptButtonIconPrefix: 'fas',
action: 'join',
@@ -226,13 +233,22 @@ export default class ConsoleController extends Controller {
const { action, next, name, description, phone, currency, country, timezone } = modal.getOptions();
if (action === 'join') {
return this.fetch.post('auth/join-organization', { next }).then(() => {
this.fetch.flushRequestCache('auth/organizations');
this.notifications.success('You have joined a new organization!');
setTimeout(() => {
window.location.reload();
}, 900);
});
return this.fetch
.post('auth/join-organization', { next })
.then(() => {
this.fetch.flushRequestCache('auth/organizations');
this.notifications.success(this.intl.t('console.create-or-join-organization.join-success-notification'));
later(
this,
() => {
window.location.reload();
},
900
);
})
.catch((error) => {
this.notifications.serverError(error);
});
}
return this.fetch
@@ -246,7 +262,7 @@ export default class ConsoleController extends Controller {
})
.then(() => {
this.fetch.flushRequestCache('auth/organizations');
this.notifications.success('You have created a new organization!');
this.notifications.success(this.intl.t('console.create-or-join-organization.create-success-notification'));
later(
this,
() => {
@@ -254,6 +270,9 @@ export default class ConsoleController extends Controller {
},
900
);
})
.catch((error) => {
this.notifications.serverError(error);
});
},
});
@@ -270,9 +289,9 @@ export default class ConsoleController extends Controller {
}
this.modalsManager.confirm({
title: `Are you sure you want to switch organization to ${organization.name}?`,
body: `By confirming your account will remain logged in, but your primary organization will be switched.`,
acceptButtonText: `Yes, I want to switch organization`,
title: this.intl.t('console.switch-organization.modal-title', { organizationName: organization.name }),
body: this.intl.t('console.switch-organization.modal-body'),
acceptButtonText: this.intl.t('console.switch-organization.modal-accept-button-text'),
acceptButtonScheme: 'primary',
confirm: (modal) => {
modal.startLoading();
@@ -281,10 +300,14 @@ export default class ConsoleController extends Controller {
.post('auth/switch-organization', { next: organization.uuid })
.then(() => {
this.fetch.flushRequestCache('auth/organizations');
this.notifications.success('You have switched organizations');
setTimeout(() => {
window.location.reload();
}, 900);
this.notifications.success(this.intl.t('console.switch-organization.success-notification'));
later(
this,
() => {
window.location.reload();
},
900
);
})
.catch((error) => {
this.notifications.serverError(error);
@@ -295,8 +318,8 @@ export default class ConsoleController extends Controller {
@action viewChangelog() {
this.modalsManager.show('modals/changelog', {
title: 'Changelog',
acceptButtonText: 'OK',
title: this.intl.t('common.changelog'),
acceptButtonText: this.intl.t('common.ok'),
hideDeclineButton: true,
});
}

View File

@@ -1,8 +1,7 @@
import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { task } from 'ember-concurrency';
/**
* Controller for managing organizations in the admin console.
@@ -41,6 +40,13 @@ export default class ConsoleAdminOrganizationsController extends Controller {
*/
@service filters;
/**
* The search query param value.
*
* @var {String|null}
*/
@tracked query;
/**
* The current page of data being viewed
*
@@ -104,14 +110,36 @@ export default class ConsoleAdminOrganizationsController extends Controller {
filterable: true,
filterComponent: 'filter/string',
},
{
label: this.intl.t('console.admin.organizations.index.owner-name-column'),
valuePath: 'owner.name',
width: '200px',
resizable: true,
sortable: true,
},
{
label: this.intl.t('console.admin.organizations.index.owner-email-column'),
valuePath: 'owner.email',
width: '200px',
resizable: true,
sortable: true,
filterable: true,
},
{
label: this.intl.t('console.admin.organizations.index.phone-column'),
valuePath: 'phone',
valuePath: 'owner.phone',
width: '200px',
resizable: true,
sortable: true,
filterable: true,
filterComponent: 'filter/string',
},
{
label: this.intl.t('console.admin.organizations.index.users-count-column'),
valuePath: 'users_count',
resizable: true,
sortable: true,
},
{
label: this.intl.t('common.created-at'),
valuePath: 'createdAt',
@@ -119,15 +147,14 @@ export default class ConsoleAdminOrganizationsController extends Controller {
];
/**
* `search` is a task that performs a search query on the 'company' model in the store.
* Update search query param and reset page to 1
*
* @method search
* @param {string} query - The search query.
* @returns {Promise} A promise that resolves with the search results.
* @public
* @param {Event} event
* @memberof ConsoleAdminOrganizationsController
*/
@task({ restartable: true }) *search(event) {
this.companies = yield this.store.query('company', { query: event.target.value });
@action search(event) {
this.query = event.target.value ?? '';
this.page = 1;
}
/**

View File

@@ -2,9 +2,6 @@ import Controller from '@ember/controller';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { isBlank } from '@ember/utils';
import { task } from 'ember-concurrency-decorators';
import { timeout } from 'ember-concurrency';
export default class ConsoleAdminOrganizationsIndexUsersController extends Controller {
/**
@@ -95,6 +92,17 @@ export default class ConsoleAdminOrganizationsIndexUsersController extends Contr
},
];
/**
* Update search query param and reset page to 1
*
* @param {Event} event
* @memberof ConsoleAdminOrganizationsController
*/
@action search(event) {
this.nestedQuery = event.target.value ?? '';
this.nestedPage = 1;
}
/**
* Set the overlay component context object.
*
@@ -118,22 +126,4 @@ export default class ConsoleAdminOrganizationsIndexUsersController extends Contr
return this.router.transitionTo('console.admin.organizations.index');
}
/**
* `search` is a task that performs a search query on the 'company' model in the store.
*
* @method search
* @param {string} query - The search query.
* @returns {Promise} A promise that resolves with the search results.
* @public
*/
@task({ restartable: true }) *search(event) {
const searchQuery = event.target.value ?? '';
if (isBlank(searchQuery)) {
return;
}
yield timeout(600);
this.nestedQuery = searchQuery;
}
}

View File

@@ -13,6 +13,7 @@ export default class Company extends Model {
@attr('string') place_uuid;
/** @relationships */
@belongsTo('user') owner;
@belongsTo('file') logo;
@belongsTo('file') backdrop;
@@ -23,6 +24,7 @@ export default class Company extends Model {
@attr('string') backdrop_url;
@attr('string') description;
@attr('raw') options;
@attr('number') users_count;
@attr('string') type;
@attr('string') currency;
@attr('string') country;

View File

@@ -14,11 +14,6 @@ export default class ConsoleAdminOrganizationsRoute extends Route {
};
model(params) {
return this.store.query('company', params);
}
setupController(controller, model) {
super.setupController(controller, model);
controller.companies = model;
return this.store.query('company', { view: 'admin', ...params });
}
}

View File

@@ -0,0 +1,15 @@
import ApplicationSerializer from '@fleetbase/ember-core/serializers/application';
import { EmbeddedRecordsMixin } from '@ember-data/serializer/rest';
export default class CompanySerializer extends ApplicationSerializer.extend(EmbeddedRecordsMixin) {
/**
* Embedded relationship attributes
*
* @var {Object}
*/
get attrs() {
return {
owner: { embedded: 'always' },
};
}
}

View File

@@ -44,3 +44,7 @@ body[data-theme='dark'] .two-fa-enforcement-alert button#two-fa-setup-button.btn
padding-left: 0 !important;
padding-right: 0 !important;
}
body.console-admin-organizations-index-index .next-table-wrapper > table {
table-layout: auto;
}

View File

@@ -10,8 +10,8 @@
<FaIcon @icon="check-circle" @size="lg" class="text-green-900 mr-4" />
</div>
<p class="flex-1 text-sm text-green-900 dark:text-green-900">
<strong>Check your {{this.selectedMethod}}</strong><br />
We've sent you a verification code. Enter the code below to complete the login process.
<strong>{{t "auth.two-fa.verify-code.check-title"}}</strong><br />
{{t "auth.two-fa.verify-code.check-subtitle"}}
</p>
</div>
@@ -26,22 +26,22 @@
{{/if}}
{{#if this.isCodeExpired}}
<InfoBlock>
<div>Your 2FA authentication code has expired. You can request another code if you need more time.</div>
<Button @type="primary" @wrapperClass="mt-2" @text="Resend Code" @icon="arrow-rotate-right" @onClick={{this.resendCode}} />
<div>{{t "auth.two-fa.verify-code.expired-help-text"}}</div>
<Button @type="primary" @wrapperClass="mt-2" @text={{t "auth.two-fa.verify-code.resend-code"}} @icon="arrow-rotate-right" @onClick={{this.resendCode}} />
</InfoBlock>
{{/if}}
</div>
<div class="mt-4">
<Button @buttonType="submit" @type="primary" @text="Verify Code" @icon="check-circle" @wrapperClass="btn-block" @isLoading={{this.isLoading}} />
<Button @buttonType="submit" @type="primary" @text={{t "auth.two-fa.verify-code.verify-code"}} @icon="check-circle" @wrapperClass="btn-block" @isLoading={{this.isLoading}} />
</div>
<div class="text-center flex flex-row items-center justify-center space-x-4 mt-3.5">
<a href="#" class="text-sm text-blue-500 hover:underline inline-block" {{on "click" this.resendCode}}>
Resend Code
{{t "auth.two-fa.verify-code.resend-code"}}
</a>
<a href="#" class="text-sm text-danger hover:underline inline-block" {{on "click" this.cancelTwoFactor}}>
Cancel Two-Factor
{{t "auth.two-fa.verify-code.cancel-two-factor"}}
</a>
</div>
</form>

View File

@@ -1,15 +1,16 @@
{{page-title (t "console.admin.organizations.index.title")}}
<Layout::Section::Header @title={{t "console.admin.organizations.index.title"}} @searchQuery={{this.query}} @onSearch={{perform this.search}} />
{{!-- template-lint-disable no-unbound --}}
<Layout::Section::Header @title={{t "console.admin.organizations.index.title"}} @searchQuery={{unbound this.query}} @onSearch={{this.search}} />
<Layout::Section::Body>
<Table
@rows={{this.companies}}
@rows={{@model}}
@columns={{this.columns}}
@selectable={{true}}
@canSelectAll={{true}}
@selectable={{false}}
@canSelectAll={{false}}
@onSetup={{fn (mut this.table)}}
@pagination={{true}}
@paginationMeta={{this.companies}}
@paginationMeta={{@model.meta}}
@page={{this.page}}
@onPageChange={{fn (mut this.page)}}
@tfootVerticalOffset="53"

View File

@@ -1,5 +1,5 @@
{{page-title (t "common.users")}}
<Overlay @isOpen={{@isOpen}} @onLoad={{this.setOverlayContext}} @position="right" @noBackdrop={{true}} @fullHeight={{true}} @width={{or this.width @width "600px"}}>
<Overlay @isOpen={{@isOpen}} @onLoad={{this.setOverlayContext}} @position="right" @noBackdrop={{true}} @fullHeight={{true}} @width="600px" @isResizable={{true}}>
<Overlay::Header @title={{concat this.company.name " - " (t "common.users")}} @hideStatusDot={{true}} @titleWrapperClass="leading-5">
<div class="flex flex-1 justify-end">
<Button @type="default" @icon="times" @helpText={{t "common.close-and-save"}} @onClick={{this.onPressClose}} />
@@ -7,12 +7,13 @@
</Overlay::Header>
<Overlay::Body class="without-padding">
<Layout::Section::Header @title={{t "console.admin.organizations.users.title"}} @searchQuery={{this.nestedQuery}} @onSearch={{perform this.search}}>
{{!-- template-lint-disable no-unbound --}}
<Layout::Section::Header @title={{t "console.admin.organizations.users.title"}} @searchQuery={{unbound this.nestedQuery}} @onSearch={{this.search}}>
<Pagination @meta={{@model.meta}} @page={{this.nestedPage}} @onPageChange={{fn (mut this.nestedPage)}} @metaInfoClass="hidden" @metaInfoWrapperClass="within-layout-section-header" />
</Layout::Section::Header>
<Layout::Section::Body>
<Table @rows={{@model}} @columns={{this.columns}} @selectable={{true}} @canSelectAll={{true}} @onSetup={{fn (mut this.table)}} />
<Table @rows={{@model}} @columns={{this.columns}} @selectable={{false}} @canSelectAll={{false}} @onSetup={{fn (mut this.table)}} />
</Layout::Section::Body>
</Overlay::Body>
</Overlay>

View File

@@ -1,6 +1,6 @@
{
"name": "@fleetbase/console",
"version": "0.4.2",
"version": "0.4.5",
"private": true,
"description": "Fleetbase Console",
"repository": "https://github.com/fleetbase/fleetbase",
@@ -12,7 +12,7 @@
},
"scripts": {
"prebuild": "node prebuild.js",
"build": "pnpm run prebuild && ember build --environment=production",
"build": "pnpm run prebuild && ember build",
"lint": "concurrently \"npm:lint:*(!fix)\" --names \"lint:\"",
"lint:css": "stylelint \"**/*.css\"",
"lint:css:fix": "concurrently \"npm:lint:css -- --fix\"",
@@ -24,14 +24,15 @@
"postinstall": "patch-package",
"lint:intl": "fleetbase-intl-lint",
"start": "pnpm run prebuild && ember serve",
"start:dev": "pnpm run prebuild && ember serve --environment development",
"test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"",
"test:ember": "ember test"
},
"dependencies": {
"@fleetbase/ember-core": "^0.2.4",
"@fleetbase/ember-ui": "^0.2.10",
"@fleetbase/storefront-engine": "^0.2.11",
"@fleetbase/fleetops-engine": "^0.4.8",
"@fleetbase/storefront-engine": "^0.3.0",
"@fleetbase/fleetops-engine": "^0.4.12",
"@fleetbase/fleetops-data": "^0.1.8",
"@fleetbase/dev-engine": "^0.2.1",
"@fleetbase/iam-engine": "^0.0.9",

16
console/pnpm-lock.yaml generated
View File

@@ -22,8 +22,8 @@ dependencies:
specifier: ^0.1.8
version: 0.1.8
'@fleetbase/fleetops-engine':
specifier: ^0.4.8
version: 0.4.8(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0)
specifier: ^0.4.12
version: 0.4.12(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0)
'@fleetbase/iam-engine':
specifier: ^0.0.9
version: 0.0.9(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0)
@@ -31,8 +31,8 @@ dependencies:
specifier: ^3.2.16
version: 3.2.16
'@fleetbase/storefront-engine':
specifier: ^0.2.11
version: 0.2.11(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0)
specifier: ^0.3.0
version: 0.3.0(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0)
'@fortawesome/ember-fontawesome':
specifier: ^0.4.1
version: 0.4.1(rollup@4.9.6)
@@ -2784,8 +2784,8 @@ packages:
- supports-color
dev: false
/@fleetbase/fleetops-engine@0.4.8(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0):
resolution: {integrity: sha512-RIlOFSWV/TOJspB/peqaoLCpUyt46M2Wt97m4+pNPiZyz4t3WYBu02owH64X33uBQXmEp2RaaP8MZEZFa8w+yg==}
/@fleetbase/fleetops-engine@0.4.12(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0):
resolution: {integrity: sha512-HWAc7B4YL3kc7FwwNgH0SvbWfA0JgtcSXbT3Xs5xPqBmhtfHyzP4YthgvaASu792SC9yTBnEr/FQxDjXXTYilQ==}
engines: {node: '>= 18'}
peerDependencies:
ember-engines: ^0.9.0
@@ -2900,8 +2900,8 @@ packages:
osrm-text-instructions: 0.13.4
dev: false
/@fleetbase/storefront-engine@0.2.11(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0):
resolution: {integrity: sha512-JnuLWn771GAT+ap60Iyw2KBXpYUqG1XD+t931sbdLUQ7XkdFW3/pOIjIAn6/JcmAziz9M9PF0+IPMrQGyBYz8A==}
/@fleetbase/storefront-engine@0.3.0(@ember/test-helpers@3.2.0)(@glimmer/component@1.1.2)(@glimmer/tracking@1.1.2)(ember-engines@0.8.23)(ember-source@5.4.0)(postcss@8.4.21)(rollup@4.9.6)(tracked-built-ins@3.3.0)(webpack@5.89.0):
resolution: {integrity: sha512-YZhvSMg80zRnIL/QCWrryHUahBFNOdkTcoikds8za3WdKrrW01iaZMoeG2FblzSi8+NMz879niNyFLrl1PieUw==}
engines: {node: '>= 18'}
peerDependencies:
ember-engines: ^0.9.0

View File

@@ -0,0 +1,24 @@
import { module, test } from 'qunit';
import { setupTest } from '@fleetbase/console/tests/helpers';
module('Unit | Serializer | company', 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('company');
assert.ok(serializer);
});
test('it serializes records', function (assert) {
let store = this.owner.lookup('service:store');
let record = store.createRecord('company', {});
let serializedRecord = record.serialize();
assert.ok(serializedRecord);
});
});

View File

@@ -13,6 +13,7 @@ terms:
search: Search
search-input: Search Input
common:
confirm: Confirm
edit: Edit
save: Save
cancel: Cancel
@@ -56,6 +57,8 @@ common:
status: Status
close-and-save: Close and Save
users: Users
changelog: Changelog
ok: OK
component:
file:
dropdown-label: File actions
@@ -124,6 +127,13 @@ auth:
send-by-sms: Send by SMS
two-fa:
verify-code:
verification-code: Verification Code
check-title: Check your email or phone
check-subtitle: We've sent you a verification code. Enter the code below to complete the login process.
expired-help-text: Your 2FA authentication code has expired. You can request another code if you need more time.
resend-code: Resend Code
verify-code: Verify Code
cancel-two-factor: Cancel Two-Factor
invalid-session-error-notification: Invalid session. Please try again.
verification-successful-notification: Verification successful!
verification-code-expired-notification: Verification code has expired. Please request a new one.
@@ -175,6 +185,15 @@ auth:
submit-button: Reset Password
back-button: Back
console:
create-or-join-organization:
modal-title: Create or join a organization
join-success-notification: You have joined a new organization!
create-success-notification: You have created a new organization!
switch-organization:
modal-title: Are you sure you want to switch organization to {organizationName}?
modal-body: By confirming your account will remain logged in, but your primary organization will be switched.
modal-accept-button-text: Yes, I want to switch organization
success-notification: You have switched organizations
account:
index:
upload-new: Upload new
@@ -213,6 +232,10 @@ console:
organizations:
index:
title: Organizations
owner-name-column: Owner
owner-phone-column: Owner Phone
owner-email-column: Owner Phone
users-count-column: Users
phone-column: Phone
email-column: Email
users:

View File

@@ -1,9 +1,9 @@
# syntax = docker/dockerfile:1.2
# Base stage
FROM dunglas/frankenphp:sha-7454826-php8.2-alpine as base
FROM dunglas/frankenphp:1.1.0-php8.2-bookworm as base
# Install packages
RUN apk update && apk add git openssh bind-tools mycli nodejs npm \
RUN apt-get update && apt-get install -y git bind9-utils mycli nodejs npm \
&& mkdir -p /root/.ssh \
&& ssh-keyscan github.com >> /root/.ssh/known_hosts

View File

@@ -62,7 +62,7 @@ deploy:
# build the builder
- docker buildx build -t frontend-${STACK}-${VERSION} --load --target builder -f console/Dockerfile .
- docker run -i --rm --env-file /tmp/dotenv.file -v "$(pwd)/console_dist:/app/dist" frontend-${STACK}-${VERSION} pnpm build
- docker run -i --rm --env-file /tmp/dotenv.file -v "$(pwd)/console_dist:/app/dist" frontend-${STACK}-${VERSION} pnpm build --environment production
- |-
DEPLOY_BUCKET=${PROJECT}-${STACK}
wget -O- https://github.com/bep/s3deploy/releases/download/v2.11.0/s3deploy_2.11.0_linux-amd64.tar.gz | tar xzv -f - s3deploy