diff --git a/CHANGELOG.md b/CHANGELOG.md index e8a33af2a..228e9c377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Enabled the _Bull Dashboard_ in the admin control panel without requiring an environment variable (experimental) - Extracted the page tabs to a reusable component +- Upgraded `bull-board` from version `7.0.0` to `7.1.5` ### Fixed diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 3316f9ce4..4857c7e14 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -74,29 +74,25 @@ import { UserModule } from './user/user.module'; AuthDeviceModule, AuthModule, BenchmarksModule, - ...(process.env.ENABLE_FEATURE_BULL_BOARD === 'true' - ? [ - BullBoardModule.forRoot({ - adapter: ExpressAdapter, - boardOptions: { - uiConfig: { - boardLogo: { - height: 0, - path: '', - width: 0 - }, - boardTitle: 'Job Queues', - favIcon: { - alternative: '/assets/favicon-32x32.png', - default: '/assets/favicon-32x32.png' - } - } - }, - middleware: BullBoardAuthMiddleware, - route: BULL_BOARD_ROUTE - }) - ] - : []), + BullBoardModule.forRoot({ + adapter: ExpressAdapter, + boardOptions: { + uiConfig: { + boardLogo: { + height: 0, + path: '', + width: 0 + }, + boardTitle: 'Job Queues', + favIcon: { + alternative: '/assets/favicon-32x32.png', + default: '/assets/favicon-32x32.png' + } + } + }, + middleware: BullBoardAuthMiddleware, + route: BULL_BOARD_ROUTE + }), BullModule.forRoot({ redis: { db: parseInt(process.env.REDIS_DB ?? '0', 10), diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 0c73833f7..4ad22a043 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -532,7 +532,7 @@ export class UserService { } if (hasRole(user, Role.ADMIN)) { - if (this.configurationService.get('ENABLE_FEATURE_BULL_BOARD')) { + if ((user.settings.settings as UserSettings).isExperimentalFeatures) { currentPermissions.push(permissions.accessAdminControlBullBoard); } diff --git a/apps/api/src/services/configuration/configuration.service.ts b/apps/api/src/services/configuration/configuration.service.ts index ad8e84a99..b19508d3e 100644 --- a/apps/api/src/services/configuration/configuration.service.ts +++ b/apps/api/src/services/configuration/configuration.service.ts @@ -44,7 +44,6 @@ export class ConfigurationService { ENABLE_FEATURE_AUTH_GOOGLE: bool({ default: false }), ENABLE_FEATURE_AUTH_OIDC: bool({ default: false }), ENABLE_FEATURE_AUTH_TOKEN: bool({ default: true }), - ENABLE_FEATURE_BULL_BOARD: bool({ default: false }), ENABLE_FEATURE_FEAR_AND_GREED_INDEX: bool({ default: false }), ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: bool({ default: true }), ENABLE_FEATURE_READ_ONLY_MODE: bool({ default: false }), diff --git a/apps/api/src/services/interfaces/environment.interface.ts b/apps/api/src/services/interfaces/environment.interface.ts index 9664ae144..eb3ac86a3 100644 --- a/apps/api/src/services/interfaces/environment.interface.ts +++ b/apps/api/src/services/interfaces/environment.interface.ts @@ -20,7 +20,6 @@ export interface Environment extends CleanedEnvAccessors { ENABLE_FEATURE_AUTH_GOOGLE: boolean; ENABLE_FEATURE_AUTH_OIDC: boolean; ENABLE_FEATURE_AUTH_TOKEN: boolean; - ENABLE_FEATURE_BULL_BOARD: boolean; ENABLE_FEATURE_FEAR_AND_GREED_INDEX: boolean; ENABLE_FEATURE_GATHER_NEW_EXCHANGE_RATES: boolean; ENABLE_FEATURE_READ_ONLY_MODE: boolean; diff --git a/apps/api/src/services/queues/data-gathering/data-gathering.module.ts b/apps/api/src/services/queues/data-gathering/data-gathering.module.ts index d163f0d29..5672df5e8 100644 --- a/apps/api/src/services/queues/data-gathering/data-gathering.module.ts +++ b/apps/api/src/services/queues/data-gathering/data-gathering.module.ts @@ -19,18 +19,14 @@ import { DataGatheringProcessor } from './data-gathering.processor'; @Module({ imports: [ - ...(process.env.ENABLE_FEATURE_BULL_BOARD === 'true' - ? [ - BullBoardModule.forFeature({ - adapter: BullAdapter, - name: DATA_GATHERING_QUEUE, - options: { - displayName: 'Data Gathering', - readOnlyMode: process.env.BULL_BOARD_IS_READ_ONLY !== 'false' - } - }) - ] - : []), + BullBoardModule.forFeature({ + adapter: BullAdapter, + name: DATA_GATHERING_QUEUE, + options: { + displayName: 'Data Gathering', + readOnlyMode: process.env.BULL_BOARD_IS_READ_ONLY !== 'false' + } + }), BullModule.registerQueue({ limiter: { duration: ms('4 seconds'), diff --git a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts index 1260f1cf0..c90f826f6 100644 --- a/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts +++ b/apps/api/src/services/queues/portfolio-snapshot/portfolio-snapshot.module.ts @@ -25,18 +25,14 @@ import { PortfolioSnapshotProcessor } from './portfolio-snapshot.processor'; imports: [ AccountBalanceModule, ActivitiesModule, - ...(process.env.ENABLE_FEATURE_BULL_BOARD === 'true' - ? [ - BullBoardModule.forFeature({ - adapter: BullAdapter, - name: PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE, - options: { - displayName: 'Portfolio Snapshot Computation', - readOnlyMode: process.env.BULL_BOARD_IS_READ_ONLY !== 'false' - } - }) - ] - : []), + BullBoardModule.forFeature({ + adapter: BullAdapter, + name: PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE, + options: { + displayName: 'Portfolio Snapshot Computation', + readOnlyMode: process.env.BULL_BOARD_IS_READ_ONLY !== 'false' + } + }), BullModule.registerQueue({ name: PORTFOLIO_SNAPSHOT_COMPUTATION_QUEUE, settings: { diff --git a/apps/api/src/services/queues/statistics-gathering/statistics-gathering.module.ts b/apps/api/src/services/queues/statistics-gathering/statistics-gathering.module.ts index 1818dd4ec..60b963c69 100644 --- a/apps/api/src/services/queues/statistics-gathering/statistics-gathering.module.ts +++ b/apps/api/src/services/queues/statistics-gathering/statistics-gathering.module.ts @@ -13,7 +13,7 @@ import { StatisticsGatheringService } from './statistics-gathering.service'; @Module({ exports: [BullModule, StatisticsGatheringService], imports: [ - ...(process.env.ENABLE_FEATURE_BULL_BOARD === 'true' + ...(process.env.ENABLE_FEATURE_STATISTICS === 'true' ? [ BullBoardModule.forFeature({ adapter: BullAdapter, diff --git a/apps/api/src/services/queues/statistics-gathering/statistics-gathering.processor.ts b/apps/api/src/services/queues/statistics-gathering/statistics-gathering.processor.ts index 07fc32585..1312d49ea 100644 --- a/apps/api/src/services/queues/statistics-gathering/statistics-gathering.processor.ts +++ b/apps/api/src/services/queues/statistics-gathering/statistics-gathering.processor.ts @@ -93,12 +93,25 @@ export class StatisticsGatheringProcessor { @Process(GATHER_STATISTICS_UPTIME_PROCESS_JOB_NAME) public async gatherUptimeStatistics() { + const monitorId = await this.propertyService.getByKey( + PROPERTY_BETTER_UPTIME_MONITOR_ID + ); + + if (!monitorId) { + Logger.log( + `Uptime statistics gathering has been skipped as no ${PROPERTY_BETTER_UPTIME_MONITOR_ID} is configured`, + 'StatisticsGatheringProcessor' + ); + + return; + } + Logger.log( 'Uptime statistics gathering has been started', 'StatisticsGatheringProcessor' ); - const uptime = await this.getUptime(); + const uptime = await this.getUptime(monitorId); await this.propertyService.put({ key: PROPERTY_UPTIME, @@ -179,12 +192,8 @@ export class StatisticsGatheringProcessor { } } - private async getUptime(): Promise { + private async getUptime(monitorId: string): Promise { try { - const monitorId = await this.propertyService.getByKey( - PROPERTY_BETTER_UPTIME_MONITOR_ID - ); - const { data } = await fetch( `https://uptime.betterstack.com/api/v2/monitors/${monitorId}/sla?from=${format( subDays(new Date(), 90), diff --git a/apps/client/src/app/pages/pricing/pricing-page.scss b/apps/client/src/app/pages/pricing/pricing-page.scss index 64d4bba80..dc9317c81 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.scss +++ b/apps/client/src/app/pages/pricing/pricing-page.scss @@ -18,8 +18,12 @@ border-color 0.5s ease, box-shadow 0.5s ease; - &:hover, &.active { + border-color: currentColor; + box-shadow: 0 0 0 1px currentColor; + } + + &:hover { border-color: rgba(var(--palette-primary-500), 1); box-shadow: 0 0 0 1px rgba(var(--palette-primary-500), 1); } diff --git a/libs/ui/src/lib/page-tabs/page-tabs.component.scss b/libs/ui/src/lib/page-tabs/page-tabs.component.scss index bed3596bb..182d2eca1 100644 --- a/libs/ui/src/lib/page-tabs/page-tabs.component.scss +++ b/libs/ui/src/lib/page-tabs/page-tabs.component.scss @@ -14,13 +14,13 @@ ) ); - .fab-container { - @media (max-width: 575.98px) { - bottom: 5rem; + ::ng-deep { + .fab-container { + @media (max-width: 575.98px) { + bottom: 5rem; + } } - } - ::ng-deep { .mat-mdc-tab-nav-panel { padding: 2rem 0; } diff --git a/package-lock.json b/package-lock.json index 6cdce7353..f45993a67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,9 +21,9 @@ "@angular/platform-browser-dynamic": "21.2.7", "@angular/router": "21.2.7", "@angular/service-worker": "21.2.7", - "@bull-board/api": "7.0.0", - "@bull-board/express": "7.0.0", - "@bull-board/nestjs": "7.0.0", + "@bull-board/api": "7.1.5", + "@bull-board/express": "7.1.5", + "@bull-board/nestjs": "7.1.5", "@codewithdan/observable-store": "2.2.15", "@date-fns/utc": "2.1.1", "@internationalized/number": "3.6.6", @@ -3522,25 +3522,25 @@ "license": "(Apache-2.0 AND BSD-3-Clause)" }, "node_modules/@bull-board/api": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@bull-board/api/-/api-7.0.0.tgz", - "integrity": "sha512-ISNspLHVmUWUSq/eLw+wd1FuBBUnqpLbYP2xUNmehpfKhS+NoZWMbBvqjUYVeE/HLfUkRcR1edzMKpl5n9zlSw==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@bull-board/api/-/api-7.1.5.tgz", + "integrity": "sha512-EW0sbTtGIysu9vipdVpPQeToPqOpPgVZTt+pn1Ut3gbSS/GLWbEgIfFtMmSQDUoSL9WH00RzjgUY5K+43nWh0A==", "license": "MIT", "dependencies": { "redis-info": "^3.1.0" }, "peerDependencies": { - "@bull-board/ui": "7.0.0" + "@bull-board/ui": "7.1.5" } }, "node_modules/@bull-board/express": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@bull-board/express/-/express-7.0.0.tgz", - "integrity": "sha512-3Tc/EyU5PQMTcTzcafFSrmRDiEbJBEU/EaVQ5OVYcuJ7DZCp5Pkvm0/2VtaCe2uywdtwn0ZaynlSIpB27FKX6A==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@bull-board/express/-/express-7.1.5.tgz", + "integrity": "sha512-kp4SzhVjZlykryiQwcOhJjDhiLbBnZoAMoSgEstzqQ0raLw+jERRC6ryJ0MIQO+SO+Jv9EjjxrXCR8O2YSP/eg==", "license": "MIT", "dependencies": { - "@bull-board/api": "7.0.0", - "@bull-board/ui": "7.0.0", + "@bull-board/api": "7.1.5", + "@bull-board/ui": "7.1.5", "ejs": "^5.0.2", "express": "^5.2.1" } @@ -3558,12 +3558,12 @@ } }, "node_modules/@bull-board/nestjs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@bull-board/nestjs/-/nestjs-7.0.0.tgz", - "integrity": "sha512-ypXm0eJHIMQzjN+3fjf84cVxugBg/K4Bpo0eYcV4u/AsteR/dnr6e7F79ICRgg1WWoczqmSMl0JhlmykpyhAMg==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@bull-board/nestjs/-/nestjs-7.1.5.tgz", + "integrity": "sha512-1y+HkjnDaZoSCXJRsiYfBNBVx+PX3I8x3Uv+SSJuSpt2vHifMRwFbChO3XDxeWXetT1eR+yqPVq6ub5eJwNOYQ==", "license": "MIT", "peerDependencies": { - "@bull-board/api": "^7.0.0", + "@bull-board/api": "^7.1.5", "@nestjs/bull-shared": "^10.0.0 || ^11.0.0", "@nestjs/common": "^9.0.0 || ^10.0.0 || ^11.0.0", "@nestjs/core": "^9.0.0 || ^10.0.0 || ^11.0.0", @@ -3572,12 +3572,12 @@ } }, "node_modules/@bull-board/ui": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@bull-board/ui/-/ui-7.0.0.tgz", - "integrity": "sha512-AnKeklpDn0iMFgu4ukDU6uTNmw4oudl07G4k2Fh95SknKDrXSiWRV0N1TGUawMqyfG1Yi5P/W/8d7raBq/Uw6w==", + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/@bull-board/ui/-/ui-7.1.5.tgz", + "integrity": "sha512-2IkatKwNRx/1M9/lAZIptcxS1FPNq6icpp2M46Upwd4olVxs/ujF9Kvs+Ff9ExtIO/OgYfwx7mG2IprGZ+nQCg==", "license": "MIT", "dependencies": { - "@bull-board/api": "7.0.0" + "@bull-board/api": "7.1.5" } }, "node_modules/@cacheable/utils": { diff --git a/package.json b/package.json index 69c695889..dbbe0c3af 100644 --- a/package.json +++ b/package.json @@ -65,9 +65,9 @@ "@angular/platform-browser-dynamic": "21.2.7", "@angular/router": "21.2.7", "@angular/service-worker": "21.2.7", - "@bull-board/api": "7.0.0", - "@bull-board/express": "7.0.0", - "@bull-board/nestjs": "7.0.0", + "@bull-board/api": "7.1.5", + "@bull-board/express": "7.1.5", + "@bull-board/nestjs": "7.1.5", "@codewithdan/observable-store": "2.2.15", "@date-fns/utc": "2.1.1", "@internationalized/number": "3.6.6",