mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-14 03:40:31 +00:00
refactor(nestjs): contacts module
This commit is contained in:
@@ -88,6 +88,7 @@ import { ViewsModule } from '../Views/Views.module';
|
||||
import { CurrenciesModule } from '../Currencies/Currencies.module';
|
||||
import { MiscellaneousModule } from '../Miscellaneous/Miscellaneous.module';
|
||||
import { UsersModule } from '../UsersModule/Users.module';
|
||||
import { ContactsModule } from '../Contacts/Contacts.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -210,7 +211,8 @@ import { UsersModule } from '../UsersModule/Users.module';
|
||||
ViewsModule,
|
||||
CurrenciesModule,
|
||||
MiscellaneousModule,
|
||||
UsersModule
|
||||
UsersModule,
|
||||
ContactsModule
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
export const ERRORS = {
|
||||
CONTACT_ALREADY_ACTIVE: 'CONTACT_ALREADY_ACTIVE',
|
||||
CONTACT_ALREADY_INACTIVE: 'CONTACT_ALREADY_INACTIVE'
|
||||
}
|
||||
45
packages/server/src/modules/Contacts/Contacts.controller.ts
Normal file
45
packages/server/src/modules/Contacts/Contacts.controller.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import {
|
||||
Controller,
|
||||
Get,
|
||||
Query,
|
||||
Param,
|
||||
Post,
|
||||
ParseIntPipe,
|
||||
} from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiParam } from '@nestjs/swagger';
|
||||
import { GetContactsAutoCompleteQuery } from './dtos/GetContactsAutoCompleteQuery.dto';
|
||||
import { GetAutoCompleteContactsService } from './queries/GetAutoCompleteContacts.service';
|
||||
import { ActivateContactService } from './commands/ActivateContact.service';
|
||||
import { InactivateContactService } from './commands/InactivateContact.service';
|
||||
|
||||
@Controller('contacts')
|
||||
@ApiTags('contacts')
|
||||
export class ContactsController {
|
||||
constructor(
|
||||
private readonly getAutoCompleteService: GetAutoCompleteContactsService,
|
||||
private readonly activateContactService: ActivateContactService,
|
||||
private readonly inactivateContactService: InactivateContactService,
|
||||
) {}
|
||||
|
||||
@Get('auto-complete')
|
||||
@ApiOperation({ summary: 'Get the auto-complete contacts' })
|
||||
getAutoComplete(@Query() query: GetContactsAutoCompleteQuery) {
|
||||
return this.getAutoCompleteService.autocompleteContacts(query);
|
||||
}
|
||||
|
||||
@Post(':id/activate')
|
||||
@ApiOperation({ summary: 'Activate a contact' })
|
||||
@ApiParam({ name: 'id', type: 'number', description: 'Contact ID' })
|
||||
async activateContact(@Param('id', ParseIntPipe) contactId: number) {
|
||||
await this.activateContactService.activateContact(contactId);
|
||||
return { id: contactId, activated: true };
|
||||
}
|
||||
|
||||
@Post(':id/inactivate')
|
||||
@ApiOperation({ summary: 'Inactivate a contact' })
|
||||
@ApiParam({ name: 'id', type: 'number', description: 'Contact ID' })
|
||||
async inactivateContact(@Param('id', ParseIntPipe) contactId: number) {
|
||||
await this.inactivateContactService.inactivateContact(contactId);
|
||||
return { id: contactId, inactivated: true };
|
||||
}
|
||||
}
|
||||
15
packages/server/src/modules/Contacts/Contacts.module.ts
Normal file
15
packages/server/src/modules/Contacts/Contacts.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { GetAutoCompleteContactsService } from './queries/GetAutoCompleteContacts.service';
|
||||
import { ContactsController } from './Contacts.controller';
|
||||
import { ActivateContactService } from './commands/ActivateContact.service';
|
||||
import { InactivateContactService } from './commands/InactivateContact.service';
|
||||
|
||||
@Module({
|
||||
providers: [
|
||||
GetAutoCompleteContactsService,
|
||||
ActivateContactService,
|
||||
InactivateContactService,
|
||||
],
|
||||
controllers: [ContactsController],
|
||||
})
|
||||
export class ContactsModule {}
|
||||
14
packages/server/src/modules/Contacts/Contacts.types.ts
Normal file
14
packages/server/src/modules/Contacts/Contacts.types.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { IFilterRole } from '../DynamicListing/DynamicFilter/DynamicFilter.types';
|
||||
|
||||
export interface IContactsAutoCompleteFilter {
|
||||
limit: number;
|
||||
keyword: string;
|
||||
filterRoles?: IFilterRole[];
|
||||
columnSortBy: string;
|
||||
sortOrder: string;
|
||||
}
|
||||
|
||||
export interface IContactAutoCompleteItem {
|
||||
displayName: string;
|
||||
contactService: string;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { Contact } from '../models/Contact';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { ERRORS } from '../Contacts.constants';
|
||||
|
||||
@Injectable()
|
||||
export class ActivateContactService {
|
||||
constructor(
|
||||
@Inject(Contact.name)
|
||||
private readonly contactModel: TenantModelProxy<typeof Contact>,
|
||||
) {}
|
||||
|
||||
async activateContact(contactId: number) {
|
||||
const contact = await this.contactModel()
|
||||
.query()
|
||||
.findById(contactId)
|
||||
.throwIfNotFound();
|
||||
|
||||
if (contact.active) {
|
||||
throw new ServiceError(ERRORS.CONTACT_ALREADY_ACTIVE);
|
||||
}
|
||||
await this.contactModel()
|
||||
.query()
|
||||
.findById(contactId)
|
||||
.update({ active: true });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { ServiceError } from '@/modules/Items/ServiceError';
|
||||
import { Contact } from '../models/Contact';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
import { ERRORS } from '../Contacts.constants';
|
||||
|
||||
@Injectable()
|
||||
export class InactivateContactService {
|
||||
constructor(
|
||||
@Inject(Contact.name)
|
||||
private readonly contactModel: TenantModelProxy<typeof Contact>,
|
||||
) {}
|
||||
|
||||
async inactivateContact(contactId: number) {
|
||||
const contact = await this.contactModel()
|
||||
.query()
|
||||
.findById(contactId)
|
||||
.throwIfNotFound();
|
||||
|
||||
if (!contact.active) {
|
||||
throw new ServiceError(ERRORS.CONTACT_ALREADY_INACTIVE);
|
||||
}
|
||||
await this.contactModel()
|
||||
.query()
|
||||
.findById(contactId)
|
||||
.update({ active: false });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { IsNumber, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
export class GetContactsAutoCompleteQuery {
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
limit: number;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
keyword: string;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
import { Contact } from '../models/Contact';
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { IContactsAutoCompleteFilter } from '../Contacts.types';
|
||||
import { GetContactsAutoCompleteQuery } from '../dtos/GetContactsAutoCompleteQuery.dto';
|
||||
|
||||
@Injectable()
|
||||
export class GetAutoCompleteContactsService {
|
||||
constructor(
|
||||
@Inject(Contact.name)
|
||||
private readonly contactModel: TenantModelProxy<typeof Contact>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieve auto-complete contacts list.
|
||||
* @param {number} tenantId -
|
||||
* @param {IContactsAutoCompleteFilter} contactsFilter -
|
||||
* @return {IContactAutoCompleteItem}
|
||||
*/
|
||||
async autocompleteContacts(queryDto: GetContactsAutoCompleteQuery) {
|
||||
const _queryDto = {
|
||||
filterRoles: [],
|
||||
sortOrder: 'asc',
|
||||
columnSortBy: 'display_name',
|
||||
limit: 10,
|
||||
...queryDto,
|
||||
};
|
||||
// Retrieve contacts list by the given query.
|
||||
const contacts = await this.contactModel()
|
||||
.query()
|
||||
.onBuild((builder) => {
|
||||
if (_queryDto.keyword) {
|
||||
builder.where('display_name', 'LIKE', `%${_queryDto.keyword}%`);
|
||||
}
|
||||
builder.limit(_queryDto.limit);
|
||||
});
|
||||
return contacts;
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,6 @@ function DisconnectBankAccountDialogContent({
|
||||
values: DisconnectFormValues,
|
||||
{ setErrors, setSubmitting }: FormikHelpers<DisconnectFormValues>,
|
||||
) => {
|
||||
debugger;
|
||||
setSubmitting(true);
|
||||
|
||||
if (values.label !== 'DISCONNECT ACCOUNT') {
|
||||
|
||||
@@ -38,7 +38,7 @@ export function useAutoCompleteContacts(props) {
|
||||
['CONTACTS', 'AUTO-COMPLETE'],
|
||||
() => apiRequest.get('contacts/auto-complete'),
|
||||
{
|
||||
select: (res) => res.data.contacts,
|
||||
select: (res) => res.data,
|
||||
defaultData: [],
|
||||
...props,
|
||||
},
|
||||
|
||||
@@ -67,7 +67,7 @@ export function useCurrencies(props) {
|
||||
[t.CURRENCIES],
|
||||
{ method: 'get', url: 'currencies' },
|
||||
{
|
||||
select: (res) => res.data.currencies,
|
||||
select: (res) => res.data,
|
||||
defaultData: [],
|
||||
...props
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ export const useResendInvitation = (props) => {
|
||||
const apiRequest = useApiRequest();
|
||||
|
||||
return useMutation(
|
||||
(userId) => apiRequest.post(`invite/resend/${userId}`),
|
||||
(userId) => apiRequest.post(`invite/users/${userId}/resend`),
|
||||
props
|
||||
)
|
||||
}
|
||||
@@ -101,7 +101,7 @@ export function useUpdateOrganization(props = {}) {
|
||||
export function useOrgBaseCurrencyMutateAbilities(props) {
|
||||
return useRequestQuery(
|
||||
[t.ORGANIZATION_MUTATE_BASE_CURRENCY_ABILITIES],
|
||||
{ method: 'get', url: `organization/base_currency_mutate` },
|
||||
{ method: 'get', url: `organization/base-currency-mutate` },
|
||||
{
|
||||
select: (res) => res.data.abilities,
|
||||
defaultData: [],
|
||||
|
||||
@@ -105,7 +105,7 @@ export function useUsers(props) {
|
||||
url: 'users',
|
||||
},
|
||||
{
|
||||
select: (res) => res.data.users,
|
||||
select: (res) => res.data,
|
||||
defaultData: [],
|
||||
...props,
|
||||
},
|
||||
@@ -123,7 +123,7 @@ export function useUser(id, props) {
|
||||
url: `users/${id}`,
|
||||
},
|
||||
{
|
||||
select: (response) => response.data.user,
|
||||
select: (response) => response.data,
|
||||
defaultData: {},
|
||||
...props,
|
||||
},
|
||||
@@ -143,7 +143,6 @@ export function useAuthenticatedAccount(props) {
|
||||
select: (response) => response.data,
|
||||
defaultData: {},
|
||||
onSuccess: (data) => {
|
||||
debugger;
|
||||
setEmailConfirmed(data.verified, data.email);
|
||||
},
|
||||
...props,
|
||||
|
||||
Reference in New Issue
Block a user