mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 14:20:31 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
171091e0e0 | ||
|
|
78032d7bfc | ||
|
|
06b8a836c5 | ||
|
|
37fa9f9bc6 | ||
|
|
17deeb18e3 | ||
|
|
8416b45f4e | ||
|
|
3cc5aab80e | ||
|
|
93711a7bf4 |
@@ -20,7 +20,7 @@ export class AuthenticationMailMesssages {
|
|||||||
* @returns {Mail}
|
* @returns {Mail}
|
||||||
*/
|
*/
|
||||||
resetPasswordMessage(user: ModelObject<SystemUser>, token: string) {
|
resetPasswordMessage(user: ModelObject<SystemUser>, token: string) {
|
||||||
const baseURL = this.configService.get('baseURL');
|
const baseURL = this.configService.get('app.baseUrl');
|
||||||
|
|
||||||
return new Mail()
|
return new Mail()
|
||||||
.setSubject('Bigcapital - Password Reset')
|
.setSubject('Bigcapital - Password Reset')
|
||||||
@@ -54,7 +54,7 @@ export class AuthenticationMailMesssages {
|
|||||||
* @returns {Mail}
|
* @returns {Mail}
|
||||||
*/
|
*/
|
||||||
signupVerificationMail(email: string, fullName: string, token: string) {
|
signupVerificationMail(email: string, fullName: string, token: string) {
|
||||||
const baseURL = this.configService.get('baseURL');
|
const baseURL = this.configService.get('app.baseUrl');
|
||||||
const verifyUrl = `${baseURL}/auth/email_confirmation?token=${token}&email=${email}`;
|
const verifyUrl = `${baseURL}/auth/email_confirmation?token=${token}&email=${email}`;
|
||||||
|
|
||||||
return new Mail()
|
return new Mail()
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export enum CASHFLOW_DIRECTION {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum CASHFLOW_TRANSACTION_TYPE {
|
export enum CASHFLOW_TRANSACTION_TYPE {
|
||||||
ONWERS_DRAWING = 'OwnerDrawing',
|
OWNERS_DRAWING = 'OwnerDrawing',
|
||||||
OWNER_CONTRIBUTION = 'OwnerContribution',
|
OWNER_CONTRIBUTION = 'OwnerContribution',
|
||||||
OTHER_INCOME = 'OtherIncome',
|
OTHER_INCOME = 'OtherIncome',
|
||||||
TRANSFER_FROM_ACCOUNT = 'TransferFromAccount',
|
TRANSFER_FROM_ACCOUNT = 'TransferFromAccount',
|
||||||
@@ -36,7 +36,7 @@ export enum CASHFLOW_TRANSACTION_TYPE {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const CASHFLOW_TRANSACTION_TYPE_META = {
|
export const CASHFLOW_TRANSACTION_TYPE_META = {
|
||||||
[`${CASHFLOW_TRANSACTION_TYPE.ONWERS_DRAWING}`]: {
|
[`${CASHFLOW_TRANSACTION_TYPE.OWNERS_DRAWING}`]: {
|
||||||
type: 'OwnerDrawing',
|
type: 'OwnerDrawing',
|
||||||
direction: CASHFLOW_DIRECTION.OUT,
|
direction: CASHFLOW_DIRECTION.OUT,
|
||||||
creditType: [ACCOUNT_TYPE.EQUITY],
|
creditType: [ACCOUNT_TYPE.EQUITY],
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { CommonMailOptionsDTO } from '@/modules/MailNotification/MailNotificatio
|
|||||||
import { CommonMailOptions } from '@/modules/MailNotification/MailNotification.types';
|
import { CommonMailOptions } from '@/modules/MailNotification/MailNotification.types';
|
||||||
import { EditSaleEstimateDto } from '../dtos/SaleEstimate.dto';
|
import { EditSaleEstimateDto } from '../dtos/SaleEstimate.dto';
|
||||||
|
|
||||||
export const SendSaleEstimateMailQueue = 'SendSaleEstimateMailProcessor';
|
export const SendSaleEstimateMailQueue = 'SendSaleEstimateMailQueue';
|
||||||
export const SendSaleEstimateMailJob = 'SendSaleEstimateMailProcess';
|
export const SendSaleEstimateMailJob = 'SendSaleEstimateMailProcess';
|
||||||
|
|
||||||
export interface ISaleEstimateDTO {
|
export interface ISaleEstimateDTO {
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
// import config from '@/config';
|
|
||||||
|
|
||||||
export const SendSaleInvoiceQueue = 'SendSaleInvoiceQueue';
|
export const SendSaleInvoiceQueue = 'SendSaleInvoiceQueue';
|
||||||
export const SendSaleInvoiceMailJob = 'SendSaleInvoiceMailJob';
|
export const SendSaleInvoiceMailJob = 'SendSaleInvoiceMailJob';
|
||||||
|
|
||||||
|
|
||||||
export const DEFAULT_INVOICE_MAIL_SUBJECT =
|
export const DEFAULT_INVOICE_MAIL_SUBJECT =
|
||||||
'Invoice {Invoice Number} from {Company Name} for {Customer Name}';
|
'Invoice {Invoice Number} from {Company Name} for {Customer Name}';
|
||||||
export const DEFAULT_INVOICE_MAIL_CONTENT = `Hi {Customer Name},
|
export const DEFAULT_INVOICE_MAIL_CONTENT = `Hi {Customer Name},
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { GetUsersService } from './queries/GetUsers.service';
|
|||||||
import { AcceptInviteUserService } from './commands/AcceptInviteUser.service';
|
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 { UsersInvitePublicController } from './UsersInvitePublic.controller';
|
||||||
import { InjectSystemModel } from '../System/SystemModels/SystemModels.module';
|
import { InjectSystemModel } from '../System/SystemModels/SystemModels.module';
|
||||||
import { SendInviteUserMailQueue } from './Users.constants';
|
import { SendInviteUserMailQueue } from './Users.constants';
|
||||||
import InviteSendMainNotificationSubscribe from './subscribers/InviteSendMailNotification.subscriber';
|
import InviteSendMainNotificationSubscribe from './subscribers/InviteSendMailNotification.subscriber';
|
||||||
@@ -60,6 +61,6 @@ const models = [InjectSystemModel(UserInvite)];
|
|||||||
SendInviteUsersMailMessage,
|
SendInviteUsersMailMessage,
|
||||||
UsersApplication
|
UsersApplication
|
||||||
],
|
],
|
||||||
controllers: [UsersController, UsersInviteController],
|
controllers: [UsersController, UsersInviteController, UsersInvitePublicController],
|
||||||
})
|
})
|
||||||
export class UsersModule {}
|
export class UsersModule {}
|
||||||
|
|||||||
@@ -1,40 +1,13 @@
|
|||||||
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common';
|
import { Body, Controller, Param, Patch, Post } from '@nestjs/common';
|
||||||
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
import { UsersApplication } from './Users.application';
|
import { UsersApplication } from './Users.application';
|
||||||
import { InviteUserDto, SendInviteUserDto } from './dtos/InviteUser.dto';
|
import { SendInviteUserDto } from './dtos/InviteUser.dto';
|
||||||
|
|
||||||
@Controller('invite')
|
@Controller('invite')
|
||||||
@ApiTags('Users')
|
@ApiTags('Users')
|
||||||
export class UsersInviteController {
|
export class UsersInviteController {
|
||||||
constructor(private readonly usersApplication: UsersApplication) {}
|
constructor(private readonly usersApplication: UsersApplication) {}
|
||||||
|
|
||||||
/**
|
|
||||||
* Accept a user invitation.
|
|
||||||
*/
|
|
||||||
@Post('accept/:token')
|
|
||||||
@ApiOperation({ summary: 'Accept a user invitation.' })
|
|
||||||
async acceptInvite(
|
|
||||||
@Param('token') token: string,
|
|
||||||
@Body() inviteUserDTO: InviteUserDto,
|
|
||||||
) {
|
|
||||||
await this.usersApplication.acceptInvite(token, inviteUserDTO);
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: 'The invitation has been accepted successfully.',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if an invitation token is valid.
|
|
||||||
*/
|
|
||||||
@Get('check/:token')
|
|
||||||
@ApiOperation({ summary: 'Check if an invitation token is valid.' })
|
|
||||||
async checkInvite(@Param('token') token: string) {
|
|
||||||
const inviteDetails = await this.usersApplication.checkInvite(token);
|
|
||||||
|
|
||||||
return inviteDetails;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send an invitation to a new user.
|
* Send an invitation to a new user.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
|
||||||
|
import { ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||||
|
import { PublicRoute } from '@/modules/Auth/guards/jwt.guard';
|
||||||
|
import { UsersApplication } from './Users.application';
|
||||||
|
import { InviteUserDto } from './dtos/InviteUser.dto';
|
||||||
|
|
||||||
|
@Controller('invite')
|
||||||
|
@ApiTags('Users')
|
||||||
|
@PublicRoute()
|
||||||
|
export class UsersInvitePublicController {
|
||||||
|
constructor(private readonly usersApplication: UsersApplication) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept a user invitation.
|
||||||
|
*/
|
||||||
|
@Post('accept/:token')
|
||||||
|
@ApiOperation({ summary: 'Accept a user invitation.' })
|
||||||
|
async acceptInvite(
|
||||||
|
@Param('token') token: string,
|
||||||
|
@Body() inviteUserDTO: InviteUserDto,
|
||||||
|
) {
|
||||||
|
await this.usersApplication.acceptInvite(token, inviteUserDTO);
|
||||||
|
|
||||||
|
return {
|
||||||
|
message: 'The invitation has been accepted successfully.',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an invitation token is valid.
|
||||||
|
*/
|
||||||
|
@Get('check/:token')
|
||||||
|
@ApiOperation({ summary: 'Check if an invitation token is valid.' })
|
||||||
|
async checkInvite(@Param('token') token: string) {
|
||||||
|
const inviteDetails = await this.usersApplication.checkInvite(token);
|
||||||
|
|
||||||
|
return inviteDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||||
|
import { ClsService } from 'nestjs-cls';
|
||||||
import {
|
import {
|
||||||
IAcceptInviteEventPayload,
|
IAcceptInviteEventPayload,
|
||||||
ICheckInviteEventPayload,
|
ICheckInviteEventPayload,
|
||||||
@@ -15,6 +16,11 @@ import { UserInvite } from '../models/InviteUser.model';
|
|||||||
import { ModelObject } from 'objection';
|
import { ModelObject } from 'objection';
|
||||||
import { InviteUserDto } from '../dtos/InviteUser.dto';
|
import { InviteUserDto } from '../dtos/InviteUser.dto';
|
||||||
|
|
||||||
|
interface InviteAcceptResponseDto {
|
||||||
|
inviteToken: { email: string, token: string, createdAt: Date };
|
||||||
|
orgName: string
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AcceptInviteUserService {
|
export class AcceptInviteUserService {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -27,6 +33,7 @@ export class AcceptInviteUserService {
|
|||||||
@Inject(UserInvite.name)
|
@Inject(UserInvite.name)
|
||||||
private readonly userInviteModel: typeof UserInvite,
|
private readonly userInviteModel: typeof UserInvite,
|
||||||
private readonly eventEmitter: EventEmitter2,
|
private readonly eventEmitter: EventEmitter2,
|
||||||
|
private readonly cls: ClsService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,6 +69,16 @@ export class AcceptInviteUserService {
|
|||||||
// Clear invite token by the given user id.
|
// Clear invite token by the given user id.
|
||||||
await this.clearInviteTokensByUserId(inviteToken.userId);
|
await this.clearInviteTokensByUserId(inviteToken.userId);
|
||||||
|
|
||||||
|
// Retrieve the tenant to get the organizationId for CLS.
|
||||||
|
const tenant = await this.tenantModel
|
||||||
|
.query()
|
||||||
|
.findById(inviteToken.tenantId);
|
||||||
|
|
||||||
|
// Set CLS values for tenant context before triggering sync events.
|
||||||
|
this.cls.set('tenantId', inviteToken.tenantId);
|
||||||
|
this.cls.set('userId', systemUser.id);
|
||||||
|
this.cls.set('organizationId', tenant.organizationId);
|
||||||
|
|
||||||
// Triggers `onUserAcceptInvite` event.
|
// Triggers `onUserAcceptInvite` event.
|
||||||
await this.eventEmitter.emitAsync(events.inviteUser.acceptInvite, {
|
await this.eventEmitter.emitAsync(events.inviteUser.acceptInvite, {
|
||||||
inviteToken,
|
inviteToken,
|
||||||
@@ -77,7 +94,7 @@ export class AcceptInviteUserService {
|
|||||||
*/
|
*/
|
||||||
public async checkInvite(
|
public async checkInvite(
|
||||||
token: string,
|
token: string,
|
||||||
): Promise<{ inviteToken: ModelObject<UserInvite>; orgName: string }> {
|
): Promise<InviteAcceptResponseDto> {
|
||||||
const inviteToken = await this.getInviteTokenOrThrowError(token);
|
const inviteToken = await this.getInviteTokenOrThrowError(token);
|
||||||
|
|
||||||
// Find the tenant that associated to the given token.
|
// Find the tenant that associated to the given token.
|
||||||
@@ -92,7 +109,16 @@ export class AcceptInviteUserService {
|
|||||||
tenant,
|
tenant,
|
||||||
} as ICheckInviteEventPayload);
|
} as ICheckInviteEventPayload);
|
||||||
|
|
||||||
return { inviteToken, orgName: tenant.metadata.name };
|
// Explicitly convert to plain object to ensure all fields are serialized
|
||||||
|
const result = {
|
||||||
|
inviteToken: {
|
||||||
|
email: inviteToken.email,
|
||||||
|
token: inviteToken.token,
|
||||||
|
createdAt: inviteToken.createdAt,
|
||||||
|
},
|
||||||
|
orgName: tenant.metadata.name,
|
||||||
|
};
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export class SendInviteUsersMailMessage {
|
|||||||
) {
|
) {
|
||||||
const tenant = await this.tenancyContext.getTenant(true);
|
const tenant = await this.tenancyContext.getTenant(true);
|
||||||
const root = path.join(global.__images_dirname, '/bigcapital.png');
|
const root = path.join(global.__images_dirname, '/bigcapital.png');
|
||||||
const baseURL = this.configService.get('baseURL');
|
const baseURL = this.configService.get('app.baseUrl');
|
||||||
|
|
||||||
const mail = new Mail()
|
const mail = new Mail()
|
||||||
.setSubject(`${fromUser.firstName} has invited you to join a Bigcapital`)
|
.setSubject(`${fromUser.firstName} has invited you to join a Bigcapital`)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export class UserInvite extends BaseModel {
|
|||||||
userId!: number;
|
userId!: number;
|
||||||
tenantId!: number;
|
tenantId!: number;
|
||||||
email!: string;
|
email!: string;
|
||||||
|
createdAt!: Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table name.
|
* Table name.
|
||||||
@@ -32,4 +33,11 @@ export class UserInvite extends BaseModel {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called before inserting a new record.
|
||||||
|
*/
|
||||||
|
$beforeInsert() {
|
||||||
|
this.createdAt = new Date();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default class InviteSendMainNotificationSubscribe {
|
|||||||
const organizationId = tenant.organizationId;
|
const organizationId = tenant.organizationId;
|
||||||
const userId = authedUser.id;
|
const userId = authedUser.id;
|
||||||
|
|
||||||
this.sendInviteMailQueue.add(SendInviteUserMailJob, {
|
await this.sendInviteMailQueue.add(SendInviteUserMailJob, {
|
||||||
fromUser: invitingUser,
|
fromUser: invitingUser,
|
||||||
invite,
|
invite,
|
||||||
userId,
|
userId,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { omit } from 'lodash';
|
import { pick } from 'lodash';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
import { Inject, Injectable } from '@nestjs/common';
|
import { Inject, Injectable } from '@nestjs/common';
|
||||||
import { OnEvent } from '@nestjs/event-emitter';
|
import { OnEvent } from '@nestjs/event-emitter';
|
||||||
@@ -22,13 +22,12 @@ export class SyncTenantAcceptInviteSubscriber {
|
|||||||
async syncTenantAcceptInvite({
|
async syncTenantAcceptInvite({
|
||||||
inviteToken,
|
inviteToken,
|
||||||
user,
|
user,
|
||||||
inviteUserDTO,
|
|
||||||
}: IAcceptInviteEventPayload) {
|
}: IAcceptInviteEventPayload) {
|
||||||
await this.tenantUserModel()
|
await this.tenantUserModel()
|
||||||
.query()
|
.query()
|
||||||
.where('systemUserId', inviteToken.userId)
|
.where('systemUserId', inviteToken.userId)
|
||||||
.update({
|
.update({
|
||||||
...omit(inviteUserDTO, ['password']),
|
...pick(user, ['firstName', 'lastName', 'email', 'active']),
|
||||||
inviteAcceptedAt: moment().format('YYYY-MM-DD'),
|
inviteAcceptedAt: moment().format('YYYY-MM-DD'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const getAddMoneyInOptions = () => [
|
|||||||
export const getAddMoneyOutOptions = () => [
|
export const getAddMoneyOutOptions = () => [
|
||||||
{
|
{
|
||||||
name: intl.get('banking.owner_drawings'),
|
name: intl.get('banking.owner_drawings'),
|
||||||
value: 'OwnerDrawing',
|
value: 'owner_drawing',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: intl.get('banking.expenses'),
|
name: intl.get('banking.expenses'),
|
||||||
@@ -31,11 +31,11 @@ export const getAddMoneyOutOptions = () => [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const TRANSACRIONS_TYPE = [
|
export const TRANSACTIONS_TYPE = [
|
||||||
'OwnerContribution',
|
'OwnerContribution',
|
||||||
'OtherIncome',
|
'OtherIncome',
|
||||||
'TransferFromAccount',
|
'TransferFromAccount',
|
||||||
'OnwersDrawing',
|
'OwnerDrawing',
|
||||||
'OtherExpense',
|
'OtherExpense',
|
||||||
'TransferToAccount',
|
'TransferToAccount',
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export default function InviteAcceptForm() {
|
|||||||
data: { errors },
|
data: { errors },
|
||||||
},
|
},
|
||||||
}) => {
|
}) => {
|
||||||
if (errors.find((e) => e.type === 'INVITE.TOKEN.NOT.FOUND')) {
|
if (errors.find((e) => e.type === 'INVITE_TOKEN_INVALID')) {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: intl.get('an_unexpected_error_occurred'),
|
message: intl.get('an_unexpected_error_occurred'),
|
||||||
intent: Intent.DANGER,
|
intent: Intent.DANGER,
|
||||||
@@ -71,14 +71,6 @@ export default function InviteAcceptForm() {
|
|||||||
phone_number: 'This phone number is used in another account.',
|
phone_number: 'This phone number is used in another account.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (errors.find((e) => e.type === 'INVITE.TOKEN.NOT.FOUND')) {
|
|
||||||
AppToaster.show({
|
|
||||||
message: intl.get('an_unexpected_error_occurred'),
|
|
||||||
intent: Intent.DANGER,
|
|
||||||
position: Position.BOTTOM,
|
|
||||||
});
|
|
||||||
history.push('/auth/login');
|
|
||||||
}
|
|
||||||
setSubmitting(false);
|
setSubmitting(false);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -29,14 +29,22 @@ function InviteAcceptProvider({ token, ...props }) {
|
|||||||
if (inviteMetaError) { history.push('/auth/login'); }
|
if (inviteMetaError) { history.push('/auth/login'); }
|
||||||
}, [history, inviteMetaError]);
|
}, [history, inviteMetaError]);
|
||||||
|
|
||||||
|
// Transform the backend response to match frontend expectations.
|
||||||
|
const transformedInviteMeta = inviteMeta
|
||||||
|
? {
|
||||||
|
email: inviteMeta.inviteToken?.email,
|
||||||
|
organizationName: inviteMeta.orgName,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
// Provider payload.
|
// Provider payload.
|
||||||
const provider = {
|
const provider = {
|
||||||
token,
|
token,
|
||||||
inviteMeta,
|
inviteMeta: transformedInviteMeta,
|
||||||
inviteMetaError,
|
inviteMetaError,
|
||||||
isInviteMetaError,
|
isInviteMetaError,
|
||||||
isInviteMetaLoading,
|
isInviteMetaLoading,
|
||||||
inviteAcceptMutate
|
inviteAcceptMutate,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (inviteMetaError) {
|
if (inviteMetaError) {
|
||||||
@@ -45,7 +53,6 @@ function InviteAcceptProvider({ token, ...props }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<InviteAcceptLoading isLoading={isInviteMetaLoading}>
|
<InviteAcceptLoading isLoading={isInviteMetaLoading}>
|
||||||
{ isInviteMetaError }
|
|
||||||
<InviteAcceptContext.Provider value={provider} {...props} />
|
<InviteAcceptContext.Provider value={provider} {...props} />
|
||||||
</InviteAcceptLoading>
|
</InviteAcceptLoading>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ function CategorizeTransactionFormSubContent() {
|
|||||||
} else if (values.transactionType === 'transfer_to_account') {
|
} else if (values.transactionType === 'transfer_to_account') {
|
||||||
return <CategorizeTransactionToAccount />;
|
return <CategorizeTransactionToAccount />;
|
||||||
// Owner drawings.
|
// Owner drawings.
|
||||||
} else if (values.transactionType === 'OwnerDrawing') {
|
} else if (values.transactionType === 'owner_drawing') {
|
||||||
return <CategorizeTransactionOwnerDrawings />;
|
return <CategorizeTransactionOwnerDrawings />;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ import {
|
|||||||
FFormGroup,
|
FFormGroup,
|
||||||
FTextArea,
|
FTextArea,
|
||||||
FMoneyInputGroup,
|
FMoneyInputGroup,
|
||||||
|
Icon,
|
||||||
|
FDateInput,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { CLASSES, ACCOUNT_TYPE, Features } from '@/constants';
|
import { CLASSES, ACCOUNT_TYPE, Features } from '@/constants';
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
FTextArea,
|
FTextArea,
|
||||||
FInputGroup,
|
FInputGroup,
|
||||||
FDateInput,
|
FDateInput,
|
||||||
|
Icon,
|
||||||
} from '@/components';
|
} from '@/components';
|
||||||
import { ACCOUNT_TYPE, CLASSES, Features } from '@/constants';
|
import { ACCOUNT_TYPE, CLASSES, Features } from '@/constants';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -46,4 +46,8 @@ export const BranchRowDivider = styled.div`
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
background: #ebf1f6;
|
background: #ebf1f6;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
.bp4-dark & {
|
||||||
|
background: var(--color-dark-gray5);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ function MoneyOutContentFields() {
|
|||||||
|
|
||||||
const transactionType = useMemo(() => {
|
const transactionType = useMemo(() => {
|
||||||
switch (values.transaction_type) {
|
switch (values.transaction_type) {
|
||||||
case 'OwnerDrawing':
|
case 'owner_drawing':
|
||||||
return <OwnerDrawingsFormFields />;
|
return <OwnerDrawingsFormFields />;
|
||||||
|
|
||||||
case 'other_expense':
|
case 'other_expense':
|
||||||
|
|||||||
@@ -45,4 +45,8 @@ export const BranchRowDivider = styled.div`
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
background: #ebf1f6;
|
background: #ebf1f6;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
.bp4-dark & {
|
||||||
|
background: var(--color-dark-gray5);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { useMutation } from 'react-query';
|
import { useMutation } from 'react-query';
|
||||||
import { useRequestQuery } from '../useQueryRequest';
|
import { useRequestQuery } from '../useQueryRequest';
|
||||||
import useApiRequest from '../useRequest';
|
import useApiRequest from '../useRequest';
|
||||||
|
import { transformToCamelCase } from '@/utils';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Authentication invite accept.
|
* Authentication invite accept.
|
||||||
@@ -22,9 +23,9 @@ export const useAuthInviteAccept = (props) => {
|
|||||||
export const useInviteMetaByToken = (token, props) => {
|
export const useInviteMetaByToken = (token, props) => {
|
||||||
return useRequestQuery(
|
return useRequestQuery(
|
||||||
['INVITE_META', token],
|
['INVITE_META', token],
|
||||||
{ method: 'get', url: `invite/invited/${token}` },
|
{ method: 'get', url: `invite/check/${token}` },
|
||||||
{
|
{
|
||||||
select: (res) => res.data,
|
select: (res) => transformToCamelCase(res.data),
|
||||||
...props
|
...props
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user