Compare commits

...

4 Commits

Author SHA1 Message Date
Ahmed Bouhuolia
af80afcf59 Merge pull request #955 from bigcapitalhq/fix/user-invite-email
fix: user invite email not sending and null variables
2026-02-14 00:34:08 +02:00
Ahmed Bouhuolia
66cb0521e5 fix: user invite email not sending and null variables
- Add missing BullModule queue registration and BullBoardModule to UsersModule
- Add invitingUser to event payloads to track who sent the invite
- Fix incorrect global variable in SendInviteUsersMailMessage (__views_dir -> __images_dirname)
- Use invitingUser as fromUser instead of invited user in email
- Update processors to use BullMQ pattern

Fixes issues:
1. Email not sending due to missing queue/processor registration
2. Null variables in email (firstName/lastName) because fromUser was the invited user
3. Image attachment failing due to wrong path
2026-02-14 00:31:28 +02:00
Ahmed Bouhuolia
9204b76346 Merge pull request #950 from bigcapitalhq/fix-tax-rates
fix(server): use `DrawerActionsBar` instead of `DashboardActionsBar` in drawer components
2026-02-12 23:21:28 +02:00
Ahmed Bouhuolia
36cbb1eef5 fix: use DrawerActionsBar instead of DashboardActionsBar in drawer components
Replace DashboardActionsBar with DrawerActionsBar in all drawer action bars
for consistency with the design system:
- ContactDetailActionsBar
- CustomerDetailsActionsBar
- VendorCreditDetailActionsBar
- TaxRateDetailsContentActionsBar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:19:16 +02:00
21 changed files with 107 additions and 89 deletions

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { BullBoardModule } from '@bull-board/nestjs'; import { BullBoardModule } from '@bull-board/nestjs';
import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
import { BullModule } from '@nestjs/bull'; import { BullModule } from '@nestjs/bullmq';
import { PaymentReceivesController } from './PaymentsReceived.controller'; import { PaymentReceivesController } from './PaymentsReceived.controller';
import { PaymentReceivesApplication } from './PaymentReceived.application'; import { PaymentReceivesApplication } from './PaymentReceived.application';
import { CreatePaymentReceivedService } from './commands/CreatePaymentReceived.serivce'; import { CreatePaymentReceivedService } from './commands/CreatePaymentReceived.serivce';
@@ -99,7 +99,7 @@ import { ValidateBulkDeletePaymentReceivedService } from './ValidateBulkDeletePa
BullModule.registerQueue({ name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE }), BullModule.registerQueue({ name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE }),
BullBoardModule.forFeature({ BullBoardModule.forFeature({
name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE, name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE,
adapter: BullAdapter, adapter: BullMQAdapter,
}), }),
], ],
}) })

View File

@@ -1,6 +1,6 @@
import { JOB_REF, Process, Processor } from '@nestjs/bull'; import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bull'; import { Job } from 'bullmq';
import { Inject, Scope } from '@nestjs/common'; import { Scope } from '@nestjs/common';
import { ClsService, UseCls } from 'nestjs-cls'; import { ClsService, UseCls } from 'nestjs-cls';
import { import {
SEND_PAYMENT_RECEIVED_MAIL_JOB, SEND_PAYMENT_RECEIVED_MAIL_JOB,
@@ -13,20 +13,18 @@ import { SendPaymentReceivedMailPayload } from '../types/PaymentReceived.types';
name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE, name: SEND_PAYMENT_RECEIVED_MAIL_QUEUE,
scope: Scope.REQUEST, scope: Scope.REQUEST,
}) })
export class SendPaymentReceivedMailProcessor { export class SendPaymentReceivedMailProcessor extends WorkerHost {
constructor( constructor(
private readonly sendPaymentReceivedMail: SendPaymentReceiveMailNotification, private readonly sendPaymentReceivedMail: SendPaymentReceiveMailNotification,
private readonly clsService: ClsService, private readonly clsService: ClsService,
) {
super();
}
@Inject(JOB_REF)
private readonly jobRef: Job<SendPaymentReceivedMailPayload>,
) { }
@Process(SEND_PAYMENT_RECEIVED_MAIL_JOB)
@UseCls() @UseCls()
async handleSendMail() { async process(job: Job<SendPaymentReceivedMailPayload>) {
const { messageOptions, paymentReceivedId, organizationId, userId } = const { messageOptions, paymentReceivedId, organizationId, userId } =
this.jobRef.data; job.data;
this.clsService.set('organizationId', organizationId); this.clsService.set('organizationId', organizationId);
this.clsService.set('userId', userId); this.clsService.set('userId', userId);

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { BullBoardModule } from '@bull-board/nestjs'; import { BullBoardModule } from '@bull-board/nestjs';
import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
import { BullModule } from '@nestjs/bull'; import { BullModule } from '@nestjs/bullmq';
import { TenancyContext } from '../Tenancy/TenancyContext.service'; import { TenancyContext } from '../Tenancy/TenancyContext.service';
import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module'; import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module';
import { TransformerInjectable } from '../Transformer/TransformerInjectable.service'; import { TransformerInjectable } from '../Transformer/TransformerInjectable.service';
@@ -58,7 +58,7 @@ import { SendSaleEstimateMailProcess } from './processes/SendSaleEstimateMail.pr
BullModule.registerQueue({ name: SendSaleEstimateMailQueue }), BullModule.registerQueue({ name: SendSaleEstimateMailQueue }),
BullBoardModule.forFeature({ BullBoardModule.forFeature({
name: SendSaleEstimateMailQueue, name: SendSaleEstimateMailQueue,
adapter: BullAdapter, adapter: BullMQAdapter,
}), }),
], ],
controllers: [SaleEstimatesController], controllers: [SaleEstimatesController],

View File

@@ -1,5 +1,5 @@
import { InjectQueue } from '@nestjs/bullmq'; import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bull'; import { Queue } from 'bullmq';
import { Inject, Injectable } from '@nestjs/common'; import { Inject, Injectable } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter'; import { EventEmitter2 } from '@nestjs/event-emitter';
import { ContactMailNotification } from '@/modules/MailNotification/ContactMailNotification'; import { ContactMailNotification } from '@/modules/MailNotification/ContactMailNotification';

View File

@@ -1,7 +1,6 @@
import { Process, Processor } from '@nestjs/bull'; import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bull'; import { Job } from 'bullmq';
import { Inject, Scope } from '@nestjs/common'; import { Scope } from '@nestjs/common';
import { JOB_REF } from '@nestjs/bull';
import { import {
SendSaleEstimateMailJob, SendSaleEstimateMailJob,
SendSaleEstimateMailQueue, SendSaleEstimateMailQueue,
@@ -13,18 +12,17 @@ import { ClsService, UseCls } from 'nestjs-cls';
name: SendSaleEstimateMailQueue, name: SendSaleEstimateMailQueue,
scope: Scope.REQUEST, scope: Scope.REQUEST,
}) })
export class SendSaleEstimateMailProcess { export class SendSaleEstimateMailProcess extends WorkerHost {
constructor( constructor(
private readonly sendEstimateMailService: SendSaleEstimateMail, private readonly sendEstimateMailService: SendSaleEstimateMail,
private readonly clsService: ClsService, private readonly clsService: ClsService,
@Inject(JOB_REF) ) {
private readonly jobRef: Job, super();
) { } }
@Process(SendSaleEstimateMailJob)
@UseCls() @UseCls()
async handleSendMail() { async process(job: Job) {
const { saleEstimateId, messageOptions, organizationId, userId } = this.jobRef.data; const { saleEstimateId, messageOptions, organizationId, userId } = job.data;
this.clsService.set('organizationId', organizationId); this.clsService.set('organizationId', organizationId);
this.clsService.set('userId', userId); this.clsService.set('userId', userId);

View File

@@ -46,8 +46,8 @@ import { DynamicListModule } from '../DynamicListing/DynamicList.module';
import { MailNotificationModule } from '../MailNotification/MailNotification.module'; import { MailNotificationModule } from '../MailNotification/MailNotification.module';
import { SendSaleInvoiceMailProcessor } from './processors/SendSaleInvoiceMail.processor'; import { SendSaleInvoiceMailProcessor } from './processors/SendSaleInvoiceMail.processor';
import { BullBoardModule } from '@bull-board/nestjs'; import { BullBoardModule } from '@bull-board/nestjs';
import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
import { BullModule } from '@nestjs/bull'; import { BullModule } from '@nestjs/bullmq';
import { SendSaleInvoiceQueue } from './constants'; import { SendSaleInvoiceQueue } from './constants';
import { InvoicePaymentIntegrationSubscriber } from './subscribers/InvoicePaymentIntegrationSubscriber'; import { InvoicePaymentIntegrationSubscriber } from './subscribers/InvoicePaymentIntegrationSubscriber';
import { InvoiceChangeStatusOnMailSentSubscriber } from './subscribers/InvoiceChangeStatusOnMailSentSubscriber'; import { InvoiceChangeStatusOnMailSentSubscriber } from './subscribers/InvoiceChangeStatusOnMailSentSubscriber';
@@ -85,7 +85,7 @@ import { ValidateBulkDeleteSaleInvoicesService } from './ValidateBulkDeleteSaleI
BullModule.registerQueue({ name: SendSaleInvoiceQueue }), BullModule.registerQueue({ name: SendSaleInvoiceQueue }),
BullBoardModule.forFeature({ BullBoardModule.forFeature({
name: SendSaleInvoiceQueue, name: SendSaleInvoiceQueue,
adapter: BullAdapter, adapter: BullMQAdapter,
}), }),
], ],
controllers: [SaleInvoicesController], controllers: [SaleInvoicesController],

View File

@@ -1,9 +1,8 @@
import { JOB_REF, Process, Processor } from '@nestjs/bull'; import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bull'; import { Job } from 'bullmq';
import { SendSaleInvoiceMailJob, SendSaleInvoiceQueue } from '../constants'; import { SendSaleInvoiceMailJob, SendSaleInvoiceQueue } from '../constants';
import { SendSaleInvoiceMail } from '../commands/SendSaleInvoiceMail'; import { SendSaleInvoiceMail } from '../commands/SendSaleInvoiceMail';
import { Inject, Scope } from '@nestjs/common'; import { Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { ClsService, UseCls } from 'nestjs-cls'; import { ClsService, UseCls } from 'nestjs-cls';
import { SendSaleInvoiceMailJobPayload } from '../SaleInvoice.types'; import { SendSaleInvoiceMailJobPayload } from '../SaleInvoice.types';
@@ -11,20 +10,18 @@ import { SendSaleInvoiceMailJobPayload } from '../SaleInvoice.types';
name: SendSaleInvoiceQueue, name: SendSaleInvoiceQueue,
scope: Scope.REQUEST, scope: Scope.REQUEST,
}) })
export class SendSaleInvoiceMailProcessor { export class SendSaleInvoiceMailProcessor extends WorkerHost {
constructor( constructor(
private readonly sendSaleInvoiceMail: SendSaleInvoiceMail, private readonly sendSaleInvoiceMail: SendSaleInvoiceMail,
@Inject(REQUEST) private readonly request: Request,
@Inject(JOB_REF)
private readonly jobRef: Job<SendSaleInvoiceMailJobPayload>,
private readonly clsService: ClsService, private readonly clsService: ClsService,
) { } ) {
super();
}
@Process(SendSaleInvoiceMailJob)
@UseCls() @UseCls()
async handleSendInvoice() { async process(job: Job<SendSaleInvoiceMailJobPayload>) {
const { messageOptions, saleInvoiceId, organizationId, userId } = const { messageOptions, saleInvoiceId, organizationId, userId } =
this.jobRef.data; job.data;
this.clsService.set('organizationId', organizationId); this.clsService.set('organizationId', organizationId);
this.clsService.set('userId', userId); this.clsService.set('userId', userId);

View File

@@ -1,7 +1,7 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { BullBoardModule } from '@bull-board/nestjs'; import { BullBoardModule } from '@bull-board/nestjs';
import { BullAdapter } from '@bull-board/api/bullAdapter'; import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
import { BullModule } from '@nestjs/bull'; import { BullModule } from '@nestjs/bullmq';
import { SaleReceiptApplication } from './SaleReceiptApplication.service'; import { SaleReceiptApplication } from './SaleReceiptApplication.service';
import { CreateSaleReceipt } from './commands/CreateSaleReceipt.service'; import { CreateSaleReceipt } from './commands/CreateSaleReceipt.service';
import { EditSaleReceipt } from './commands/EditSaleReceipt.service'; import { EditSaleReceipt } from './commands/EditSaleReceipt.service';
@@ -66,7 +66,7 @@ import { ValidateBulkDeleteSaleReceiptsService } from './ValidateBulkDeleteSaleR
BullModule.registerQueue({ name: SendSaleReceiptMailQueue }), BullModule.registerQueue({ name: SendSaleReceiptMailQueue }),
BullBoardModule.forFeature({ BullBoardModule.forFeature({
name: SendSaleReceiptMailQueue, name: SendSaleReceiptMailQueue,
adapter: BullAdapter, adapter: BullMQAdapter,
}), }),
], ],
providers: [ providers: [

View File

@@ -1,4 +1,4 @@
import { InjectQueue } from '@nestjs/bull'; import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq'; import { Queue } from 'bullmq';
import { import {
DEFAULT_RECEIPT_MAIL_CONTENT, DEFAULT_RECEIPT_MAIL_CONTENT,

View File

@@ -1,30 +1,26 @@
import { Process, Processor } from '@nestjs/bull'; import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bull'; import { Job } from 'bullmq';
import { Inject, Scope } from '@nestjs/common'; import { Scope } from '@nestjs/common';
import { JOB_REF } from '@nestjs/bull';
import { SendSaleReceiptMailQueue, SendSaleReceiptMailJob } from '../constants'; import { SendSaleReceiptMailQueue, SendSaleReceiptMailJob } from '../constants';
import { SaleReceiptMailNotification } from '../commands/SaleReceiptMailNotification'; import { SaleReceiptMailNotification } from '../commands/SaleReceiptMailNotification';
import { SaleReceiptSendMailPayload } from '../types/SaleReceipts.types';
import { ClsService, UseCls } from 'nestjs-cls'; import { ClsService, UseCls } from 'nestjs-cls';
@Processor({ @Processor({
name: SendSaleReceiptMailQueue, name: SendSaleReceiptMailQueue,
scope: Scope.REQUEST, scope: Scope.REQUEST,
}) })
export class SendSaleReceiptMailProcess { export class SendSaleReceiptMailProcess extends WorkerHost {
constructor( constructor(
private readonly saleReceiptMailNotification: SaleReceiptMailNotification, private readonly saleReceiptMailNotification: SaleReceiptMailNotification,
private readonly clsService: ClsService, private readonly clsService: ClsService,
) {
super();
}
@Inject(JOB_REF)
private readonly jobRef: Job<SaleReceiptSendMailPayload>,
) { }
@Process(SendSaleReceiptMailJob)
@UseCls() @UseCls()
async handleSendMailJob() { async process(job: Job) {
const { messageOpts, saleReceiptId, organizationId, userId } = const { messageOpts, saleReceiptId, organizationId, userId } =
this.jobRef.data; job.data;
this.clsService.set('organizationId', organizationId); this.clsService.set('organizationId', organizationId);
this.clsService.set('userId', userId); this.clsService.set('userId', userId);

View File

@@ -1,4 +1,7 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { BullModule } from '@nestjs/bullmq';
import { BullBoardModule } from '@bull-board/nestjs';
import { BullMQAdapter } from '@bull-board/api/bullMQAdapter';
import { ActivateUserService } from './commands/ActivateUser.service'; import { ActivateUserService } from './commands/ActivateUser.service';
import { DeleteUserService } from './commands/DeleteUser.service'; import { DeleteUserService } from './commands/DeleteUser.service';
import { EditUserService } from './commands/EditUser.service'; import { EditUserService } from './commands/EditUser.service';
@@ -18,11 +21,24 @@ import { AcceptInviteUserService } from './commands/AcceptInviteUser.service';
import { InviteTenantUserService } from './commands/InviteUser.service'; import { InviteTenantUserService } from './commands/InviteUser.service';
import { UsersInviteController } from './UsersInvite.controller'; import { UsersInviteController } from './UsersInvite.controller';
import { InjectSystemModel } from '../System/SystemModels/SystemModels.module'; import { InjectSystemModel } from '../System/SystemModels/SystemModels.module';
import { SendInviteUserMailQueue } from './Users.constants';
import InviteSendMainNotificationSubscribe from './subscribers/InviteSendMailNotification.subscriber';
import { SendInviteUserMailProcessor } from './processors/SendInviteUserMail.processor';
import { SendInviteUsersMailMessage } from './commands/SendInviteUsersMailMessage.service';
import { MailModule } from '../Mail/Mail.module';
const models = [InjectSystemModel(UserInvite)]; const models = [InjectSystemModel(UserInvite)];
@Module({ @Module({
imports: [TenancyModule], imports: [
TenancyModule,
MailModule,
BullModule.registerQueue({ name: SendInviteUserMailQueue }),
BullBoardModule.forFeature({
name: SendInviteUserMailQueue,
adapter: BullMQAdapter,
}),
],
exports: [...models], exports: [...models],
providers: [ providers: [
...models, ...models,
@@ -39,6 +55,9 @@ const models = [InjectSystemModel(UserInvite)];
SyncTenantUserMutateSubscriber, SyncTenantUserMutateSubscriber,
SyncSystemSendInviteSubscriber, SyncSystemSendInviteSubscriber,
SyncTenantAcceptInviteSubscriber, SyncTenantAcceptInviteSubscriber,
InviteSendMainNotificationSubscribe,
SendInviteUserMailProcessor,
SendInviteUsersMailMessage,
UsersApplication UsersApplication
], ],
controllers: [UsersController, UsersInviteController], controllers: [UsersController, UsersInviteController],

View File

@@ -32,10 +32,12 @@ export interface ITenantUserDeletedPayload {
export interface IUserInvitedEventPayload { export interface IUserInvitedEventPayload {
inviteToken: string; inviteToken: string;
user: ModelObject<TenantUser>; user: ModelObject<TenantUser>;
invitingUser: ModelObject<TenantUser>;
} }
export interface IUserInviteTenantSyncedEventPayload { export interface IUserInviteTenantSyncedEventPayload {
invite: ModelObject<UserInvite>; invite: ModelObject<UserInvite>;
user: ModelObject<TenantUser>; user: ModelObject<TenantUser>;
invitingUser: ModelObject<TenantUser>;
} }
export interface IUserInviteResendEventPayload { export interface IUserInviteResendEventPayload {

View File

@@ -15,11 +15,13 @@ import { events } from '@/common/events/events';
import { Role } from '@/modules/Roles/models/Role.model'; import { Role } from '@/modules/Roles/models/Role.model';
import { ModelObject } from 'objection'; import { ModelObject } from 'objection';
import { SendInviteUserDto } from '../dtos/InviteUser.dto'; import { SendInviteUserDto } from '../dtos/InviteUser.dto';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
@Injectable() @Injectable()
export class InviteTenantUserService { export class InviteTenantUserService {
constructor( constructor(
private readonly eventEmitter: EventEmitter2, private readonly eventEmitter: EventEmitter2,
private readonly tenancyContext: TenancyContext,
@Inject(TenantUser.name) @Inject(TenantUser.name)
private readonly tenantUserModel: TenantModelProxy<typeof TenantUser>, private readonly tenantUserModel: TenantModelProxy<typeof TenantUser>,
@@ -53,10 +55,18 @@ export class InviteTenantUserService {
active: true, active: true,
invitedAt: new Date(), invitedAt: new Date(),
}); });
// Retrieves the authorized user (inviting user).
const authorizedUser = await this.tenancyContext.getSystemUser();
const invitingUser = await this.tenantUserModel()
.query()
.findOne({ systemUserId: authorizedUser.id });
// Triggers `onUserSendInvite` event. // Triggers `onUserSendInvite` event.
await this.eventEmitter.emitAsync(events.inviteUser.sendInvite, { await this.eventEmitter.emitAsync(events.inviteUser.sendInvite, {
inviteToken, inviteToken,
user, user,
invitingUser,
} as IUserInvitedEventPayload); } as IUserInvitedEventPayload);
return { invitedUser: user }; return { invitedUser: user };

View File

@@ -27,7 +27,7 @@ export class SendInviteUsersMailMessage {
invite: ModelObject<UserInvite>, invite: ModelObject<UserInvite>,
) { ) {
const tenant = await this.tenancyContext.getTenant(true); const tenant = await this.tenancyContext.getTenant(true);
const root = path.join(global.__views_dir, '/images/bigcapital.png'); const root = path.join(global.__images_dirname, '/bigcapital.png');
const baseURL = this.configService.get('baseURL'); const baseURL = this.configService.get('baseURL');
const mail = new Mail() const mail = new Mail()

View File

@@ -1,7 +1,6 @@
import { JOB_REF, Process, Processor } from '@nestjs/bull'; import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bull'; import { Job } from 'bullmq';
import { Inject, Scope } from '@nestjs/common'; import { Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { ClsService, UseCls } from 'nestjs-cls'; import { ClsService, UseCls } from 'nestjs-cls';
import { import {
SendInviteUserMailJob, SendInviteUserMailJob,
@@ -14,19 +13,17 @@ import { SendInviteUsersMailMessage } from '../commands/SendInviteUsersMailMessa
name: SendInviteUserMailQueue, name: SendInviteUserMailQueue,
scope: Scope.REQUEST, scope: Scope.REQUEST,
}) })
export class SendInviteUserMailProcessor { export class SendInviteUserMailProcessor extends WorkerHost {
constructor( constructor(
private readonly sendInviteUsersMailService: SendInviteUsersMailMessage, private readonly sendInviteUsersMailService: SendInviteUsersMailMessage,
@Inject(REQUEST) private readonly request: Request,
@Inject(JOB_REF)
private readonly jobRef: Job<SendInviteUserMailJobPayload>,
private readonly clsService: ClsService, private readonly clsService: ClsService,
) { } ) {
super();
}
@Process(SendInviteUserMailJob)
@UseCls() @UseCls()
async handleSendInviteMail() { async process(job: Job<SendInviteUserMailJobPayload>) {
const { fromUser, invite, organizationId, userId } = this.jobRef.data; const { fromUser, invite, organizationId, userId } = job.data;
this.clsService.set('organizationId', organizationId); this.clsService.set('organizationId', organizationId);
this.clsService.set('userId', userId); this.clsService.set('userId', userId);

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { InjectQueue } from '@nestjs/bull'; import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bull'; import { Queue } from 'bullmq';
import { events } from '@/common/events/events'; import { events } from '@/common/events/events';
import { OnEvent } from '@nestjs/event-emitter'; import { OnEvent } from '@nestjs/event-emitter';
import { import {
@@ -29,6 +29,7 @@ export default class InviteSendMainNotificationSubscribe {
async sendMailNotification({ async sendMailNotification({
invite, invite,
user, user,
invitingUser,
}: IUserInviteTenantSyncedEventPayload) { }: IUserInviteTenantSyncedEventPayload) {
const tenant = await this.tenancyContext.getTenant(); const tenant = await this.tenancyContext.getTenant();
const authedUser = await this.tenancyContext.getSystemUser(); const authedUser = await this.tenancyContext.getSystemUser();
@@ -37,7 +38,7 @@ export default class InviteSendMainNotificationSubscribe {
const userId = authedUser.id; const userId = authedUser.id;
this.sendInviteMailQueue.add(SendInviteUserMailJob, { this.sendInviteMailQueue.add(SendInviteUserMailJob, {
fromUser: user, fromUser: invitingUser,
invite, invite,
userId, userId,
organizationId, organizationId,

View File

@@ -33,7 +33,7 @@ export class SyncSystemSendInviteSubscriber {
* @param {IUserInvitedEventPayload} payload - * @param {IUserInvitedEventPayload} payload -
*/ */
@OnEvent(events.inviteUser.sendInvite) @OnEvent(events.inviteUser.sendInvite)
async syncSendInviteSystem({ inviteToken, user }: IUserInvitedEventPayload) { async syncSendInviteSystem({ inviteToken, user, invitingUser }: IUserInvitedEventPayload) {
const authorizedUser = await this.tenancyContext.getSystemUser(); const authorizedUser = await this.tenancyContext.getSystemUser();
const tenantId = authorizedUser.tenantId; const tenantId = authorizedUser.tenantId;
@@ -63,6 +63,7 @@ export class SyncSystemSendInviteSubscriber {
{ {
invite, invite,
user, user,
invitingUser,
} as IUserInviteTenantSyncedEventPayload, } as IUserInviteTenantSyncedEventPayload,
); );
} }

View File

@@ -15,7 +15,7 @@ import { useContactDetailDrawerContext } from './ContactDetailDrawerProvider';
import { withAlertActions } from '@/containers/Alert/withAlertActions'; import { withAlertActions } from '@/containers/Alert/withAlertActions';
import { withDrawerActions } from '@/containers/Drawer/withDrawerActions'; import { withDrawerActions } from '@/containers/Drawer/withDrawerActions';
import { DashboardActionsBar, Icon, FormattedMessage as T } from '@/components'; import { DrawerActionsBar, Icon, FormattedMessage as T } from '@/components';
import { safeCallback, compose } from '@/utils'; import { safeCallback, compose } from '@/utils';
@@ -46,7 +46,7 @@ function ContactDetailActionsBar({
}; };
return ( return (
<DashboardActionsBar> <DrawerActionsBar>
<NavbarGroup> <NavbarGroup>
<Button <Button
className={Classes.MINIMAL} className={Classes.MINIMAL}
@@ -63,7 +63,7 @@ function ContactDetailActionsBar({
onClick={safeCallback(onDeleteContact)} onClick={safeCallback(onDeleteContact)}
/> />
</NavbarGroup> </NavbarGroup>
</DashboardActionsBar> </DrawerActionsBar>
); );
} }

View File

@@ -23,7 +23,6 @@ import { withDialogActions } from '@/containers/Dialog/withDialogActions';
import { withDrawerActions } from '@/containers/Drawer/withDrawerActions'; import { withDrawerActions } from '@/containers/Drawer/withDrawerActions';
import { import {
DashboardActionsBar,
Can, Can,
Icon, Icon,
FormattedMessage as T, FormattedMessage as T,

View File

@@ -20,7 +20,7 @@ import {
If, If,
Icon, Icon,
FormattedMessage as T, FormattedMessage as T,
DashboardActionsBar, DrawerActionsBar,
Can, Can,
} from '@/components'; } from '@/components';
@@ -63,7 +63,7 @@ function VendorCreditDetailActionsBar({
}; };
return ( return (
<DashboardActionsBar> <DrawerActionsBar>
<NavbarGroup> <NavbarGroup>
<Can I={VendorCreditAction.Edit} a={AbilitySubject.VendorCredit}> <Can I={VendorCreditAction.Edit} a={AbilitySubject.VendorCredit}>
<Button <Button
@@ -105,7 +105,7 @@ function VendorCreditDetailActionsBar({
</If> </If>
</Can> </Can>
</NavbarGroup> </NavbarGroup>
</DashboardActionsBar> </DrawerActionsBar>
); );
} }

View File

@@ -13,7 +13,7 @@ import {
Position, Position,
} from '@blueprintjs/core'; } from '@blueprintjs/core';
import * as R from 'ramda'; import * as R from 'ramda';
import { AppToaster, Can, DashboardActionsBar, Icon } from '@/components'; import { AppToaster, Can, DrawerActionsBar, Icon } from '@/components';
import { AbilitySubject, TaxRateAction } from '@/constants/abilityOption'; import { AbilitySubject, TaxRateAction } from '@/constants/abilityOption';
import { withDrawerActions } from '@/containers/Drawer/withDrawerActions'; import { withDrawerActions } from '@/containers/Drawer/withDrawerActions';
import { withAlertActions } from '@/containers/Alert/withAlertActions'; import { withAlertActions } from '@/containers/Alert/withAlertActions';
@@ -83,7 +83,7 @@ function TaxRateDetailsContentActionsBar({
}; };
return ( return (
<DashboardActionsBar> <DrawerActionsBar>
<NavbarGroup> <NavbarGroup>
<Can I={TaxRateAction.Edit} a={AbilitySubject.TaxRate}> <Can I={TaxRateAction.Edit} a={AbilitySubject.TaxRate}>
<Button <Button
@@ -137,7 +137,7 @@ function TaxRateDetailsContentActionsBar({
</Popover> </Popover>
</Can> </Can>
</NavbarGroup> </NavbarGroup>
</DashboardActionsBar> </DrawerActionsBar>
); );
} }