From 66c34445f47923c7b861fe39d7b5ee6a8ac81a67 Mon Sep 17 00:00:00 2001 From: RAHUL RATHORE <41804588+rahul-rocket@users.noreply.github.com> Date: Fri, 5 Apr 2024 12:20:32 +0530 Subject: [PATCH 1/6] fix: default range should be false --- packages/core/src/shared/dto/filters-query.dto.ts | 4 ++-- .../statistic/dto/time-tracking-statistic-query.dto.ts | 6 +++--- .../statistic/dto/today-date-range-query.dto.ts | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/core/src/shared/dto/filters-query.dto.ts b/packages/core/src/shared/dto/filters-query.dto.ts index 4575d2620cd..462480029c5 100644 --- a/packages/core/src/shared/dto/filters-query.dto.ts +++ b/packages/core/src/shared/dto/filters-query.dto.ts @@ -1,6 +1,6 @@ -import { ITimeLogFilters, TimeLogSourceEnum, TimeLogType } from "@gauzy/contracts"; import { ApiPropertyOptional } from "@nestjs/swagger"; import { IsEnum, IsOptional } from "class-validator"; +import { ITimeLogFilters, TimeLogSourceEnum, TimeLogType } from "@gauzy/contracts"; import { IsBetweenActivty } from "./../../shared/validators"; /** @@ -25,4 +25,4 @@ export class FiltersQueryDTO implements ITimeLogFilters { start: number; end: number; }; -} \ No newline at end of file +} diff --git a/packages/core/src/time-tracking/statistic/dto/time-tracking-statistic-query.dto.ts b/packages/core/src/time-tracking/statistic/dto/time-tracking-statistic-query.dto.ts index 35655c19540..f7ae4cafcaa 100644 --- a/packages/core/src/time-tracking/statistic/dto/time-tracking-statistic-query.dto.ts +++ b/packages/core/src/time-tracking/statistic/dto/time-tracking-statistic-query.dto.ts @@ -1,8 +1,8 @@ -import { parseToBoolean } from "@gauzy/common"; -import { ITimeLogFilters, ITimeLogTodayFilters } from "@gauzy/contracts"; import { ApiPropertyOptional, IntersectionType } from "@nestjs/swagger"; import { Transform, TransformFnParams } from "class-transformer"; import { IsOptional } from "class-validator"; +import { parseToBoolean } from "@gauzy/common"; +import { ITimeLogFilters, ITimeLogTodayFilters } from "@gauzy/contracts"; import { FiltersQueryDTO, SelectorsQueryDTO } from "../../../shared/dto"; import { TodayDateRangeQueryDTO } from "./today-date-range-query.dto"; @@ -17,7 +17,7 @@ export class TimeTrackingStatisticQueryDTO extends IntersectionType( @ApiPropertyOptional({ type: () => Boolean }) @IsOptional() @Transform(({ value }: TransformFnParams) => value ? parseToBoolean(value) : false) - readonly defaultRange: boolean = true; + readonly defaultRange: boolean = false; @ApiPropertyOptional({ type: () => String, example: 'week' }) @IsOptional() diff --git a/packages/core/src/time-tracking/statistic/dto/today-date-range-query.dto.ts b/packages/core/src/time-tracking/statistic/dto/today-date-range-query.dto.ts index 996fe35dc84..db6972c5fa9 100644 --- a/packages/core/src/time-tracking/statistic/dto/today-date-range-query.dto.ts +++ b/packages/core/src/time-tracking/statistic/dto/today-date-range-query.dto.ts @@ -1,6 +1,6 @@ import { ApiPropertyOptional } from "@nestjs/swagger"; -import { ITimeLogTodayFilters } from "@gauzy/contracts"; import { IsDateString, IsOptional } from "class-validator"; +import { ITimeLogTodayFilters } from "@gauzy/contracts"; import { IsBeforeDate } from "./../../../shared/validators"; export class TodayDateRangeQueryDTO implements ITimeLogTodayFilters { From 9c8714e3f41556398cc410ce9a8f1937368f5f6b Mon Sep 17 00:00:00 2001 From: RAHUL RATHORE <41804588+rahul-rocket@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:15:05 +0530 Subject: [PATCH 2/6] fix: added missing virtual column for screenshot and timeslot entity --- packages/contracts/src/date-picker.model.ts | 8 ++++++- packages/core/src/core/utils.ts | 7 ++----- .../screenshot/screenshot.entity.ts | 8 +++++-- .../time-slot/time-slot.entity.ts | 21 ++++++++++++------- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/contracts/src/date-picker.model.ts b/packages/contracts/src/date-picker.model.ts index f59dfac4d35..8ee25240d65 100644 --- a/packages/contracts/src/date-picker.model.ts +++ b/packages/contracts/src/date-picker.model.ts @@ -2,4 +2,10 @@ export interface IDateRangePicker { startDate: Date; endDate: Date; isCustomDate?: boolean; -} \ No newline at end of file +} + +// +export type DateRange = { + start: string | Date; + end: string | Date; +}; diff --git a/packages/core/src/core/utils.ts b/packages/core/src/core/utils.ts index e14b923559d..65cea407961 100644 --- a/packages/core/src/core/utils.ts +++ b/packages/core/src/core/utils.ts @@ -10,7 +10,7 @@ import { sample } from 'underscore'; import * as path from 'path'; import * as fs from 'fs'; import * as os from 'os'; -import { IDateRange, IUser } from '@gauzy/contracts'; +import { DateRange, IDateRange, IUser } from '@gauzy/contracts'; import { IDBConnectionOptions } from '@gauzy/common'; import { getConfig, DatabaseTypeEnum } from '@gauzy/config'; import { moment } from './../core/moment-extend'; @@ -214,10 +214,7 @@ export function mergeOverlappingDateRanges(ranges: IDateRange[]): IDateRange[] { export function getDateRangeFormat( startDate: moment.Moment, endDate: moment.Moment -): { - start: string | Date; - end: string | Date; -} { +): DateRange { let start = moment(startDate); let end = moment(endDate); diff --git a/packages/core/src/time-tracking/screenshot/screenshot.entity.ts b/packages/core/src/time-tracking/screenshot/screenshot.entity.ts index f9f4f9163a2..6bb52fe6e20 100644 --- a/packages/core/src/time-tracking/screenshot/screenshot.entity.ts +++ b/packages/core/src/time-tracking/screenshot/screenshot.entity.ts @@ -1,5 +1,6 @@ -import { RelationId, JoinColumn } from 'typeorm'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { RelationId, JoinColumn } from 'typeorm'; +import { Property } from '@mikro-orm/core'; import { IsString, IsOptional, IsDateString, IsUUID, IsNotEmpty, IsEnum, IsBoolean } from 'class-validator'; import { Exclude } from 'class-transformer'; import { FileStorageProviderEnum, IScreenshot, ITimeSlot, IUser } from '@gauzy/contracts'; @@ -88,8 +89,11 @@ export class Screenshot extends TenantOrganizationBaseEntity implements IScreens }) apps?: string | string[]; - /** Additional fields */ + /** Additional virtual columns */ + @Property({ persist: false }) fullUrl?: string; + + @Property({ persist: false }) thumbUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts index b89f9137a5e..bd9f8a842c8 100644 --- a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts +++ b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts @@ -1,7 +1,10 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { RelationId, JoinTable } from 'typeorm'; +import { Property } from '@mikro-orm/core'; +import { IsNumber, IsDateString, IsUUID, IsNotEmpty, IsOptional } from 'class-validator'; import { ITimeSlot, ITimeSlotMinute, @@ -10,8 +13,6 @@ import { IEmployee, ITimeLog } from '@gauzy/contracts'; -import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { IsNumber, IsDateString, IsUUID, IsNotEmpty, IsOptional } from 'class-validator'; import { Activity, Employee, @@ -21,7 +22,7 @@ import { } from './../../core/entities/internal'; import { TimeSlotMinute } from './time-slot-minute.entity'; import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany } from './../../core/decorators/entity'; -import { MikroOrmTimeSlotRepository } from './repository/mikro-orm-time-slot.repository'; +import { MikroOrmTimeSlotRepository } from './repository'; @MultiORMEntity('time_slot', { mikroOrmRepository: () => MikroOrmTimeSlotRepository }) export class TimeSlot extends TenantOrganizationBaseEntity @@ -60,10 +61,17 @@ export class TimeSlot extends TenantOrganizationBaseEntity @MultiORMColumn() startedAt: Date; - /** Additional fields */ + /** Additional virtual columns */ + @Property({ persist: false }) stoppedAt?: Date; + + @Property({ persist: false }) percentage?: number; + + @Property({ persist: false }) keyboardPercentage?: number; + + @Property({ persist: false }) mousePercentage?: number; /* |-------------------------------------------------------------------------- @@ -120,7 +128,6 @@ export class TimeSlot extends TenantOrganizationBaseEntity | @ManyToMany |-------------------------------------------------------------------------- */ - /** * TimeLog */ @@ -132,8 +139,6 @@ export class TimeSlot extends TenantOrganizationBaseEntity joinColumn: 'timeSlotId', inverseJoinColumn: 'timeLogId', }) - @JoinTable({ - name: 'time_slot_time_logs' - }) + @JoinTable({ name: 'time_slot_time_logs' }) timeLogs?: ITimeLog[]; } From df2532a3df667ea6b1a935b2121770e0d02a8aa7 Mon Sep 17 00:00:00 2001 From: RAHUL RATHORE <41804588+rahul-rocket@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:24:45 +0530 Subject: [PATCH 3/6] fix: missing repository import path --- packages/core/src/time-tracking/time-slot/time-slot.entity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts index bd9f8a842c8..d25d8abdbe4 100644 --- a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts +++ b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts @@ -22,7 +22,7 @@ import { } from './../../core/entities/internal'; import { TimeSlotMinute } from './time-slot-minute.entity'; import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany } from './../../core/decorators/entity'; -import { MikroOrmTimeSlotRepository } from './repository'; +import { MikroOrmTimeSlotRepository } from './repository/mikro-orm-time-slot.repository'; @MultiORMEntity('time_slot', { mikroOrmRepository: () => MikroOrmTimeSlotRepository }) export class TimeSlot extends TenantOrganizationBaseEntity From 208b9b1e8ce4522ff16f63b546514292f724eb2b Mon Sep 17 00:00:00 2001 From: RAHUL RATHORE <41804588+rahul-rocket@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:14:24 +0530 Subject: [PATCH 4/6] feat: added virtual column decorator to support mikro to load additional fields --- packages/core/src/candidate/candidate.entity.ts | 7 ++++++- .../core/src/core/decorators/entity/index.ts | 1 + .../entity/virtual-column.decorator.ts | 17 +++++++++++++++++ .../core/src/email-reset/email-reset.entity.ts | 4 +++- .../src/email-template/email-template.entity.ts | 4 +++- packages/core/src/employee/employee.entity.ts | 10 ++++++---- .../import-history/import-history.entity.ts | 4 +++- .../import-record/import-record.entity.ts | 4 +++- packages/core/src/feature/feature.entity.ts | 6 +++++- .../core/src/image-asset/image-asset.entity.ts | 8 +++++--- .../core/src/integration/integration.entity.ts | 5 +++-- .../organization-team-join-request.entity.ts | 5 +++-- .../src/password-reset/password-reset.entity.ts | 5 +++-- packages/core/src/reports/report.entity.ts | 4 +++- .../src/tasks/issue-type/issue-type.entity.ts | 4 +++- .../src/tasks/priorities/priority.entity.ts | 4 +++- .../related-issue-type.entity.ts | 4 +++- packages/core/src/tasks/sizes/size.entity.ts | 4 +++- .../core/src/tasks/statuses/status.entity.ts | 7 +++---- packages/core/src/tasks/task.entity.ts | 10 ++++++---- .../core/src/tasks/versions/version.entity.ts | 4 +++- .../screenshot/screenshot.entity.ts | 6 +++--- .../time-tracking/time-log/time-log.entity.ts | 8 ++++---- .../time-tracking/time-slot/time-slot.entity.ts | 10 +++++----- .../time-tracking/timesheet/timesheet.entity.ts | 5 +++-- packages/core/src/user/user.entity.ts | 6 +++++- 26 files changed, 108 insertions(+), 48 deletions(-) create mode 100644 packages/core/src/core/decorators/entity/virtual-column.decorator.ts diff --git a/packages/core/src/candidate/candidate.entity.ts b/packages/core/src/candidate/candidate.entity.ts index af0f6480416..c7b6390445b 100644 --- a/packages/core/src/candidate/candidate.entity.ts +++ b/packages/core/src/candidate/candidate.entity.ts @@ -44,7 +44,8 @@ import { MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany, - MultiORMOneToOne + MultiORMOneToOne, + VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmCandidateRepository } from './repository/mikro-orm-candidate.repository'; @@ -106,7 +107,11 @@ export class Candidate extends TenantOrganizationBaseEntity implements ICandidat @MultiORMColumn({ nullable: true }) cvUrl?: string; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() ratings?: number; + + @VirtualMultiOrmColumn() alreadyHired?: boolean; /* diff --git a/packages/core/src/core/decorators/entity/index.ts b/packages/core/src/core/decorators/entity/index.ts index 11ef9e6e012..f3e163f932f 100644 --- a/packages/core/src/core/decorators/entity/index.ts +++ b/packages/core/src/core/decorators/entity/index.ts @@ -2,3 +2,4 @@ export * from './entity.decorator'; export * from './column.decorator'; export * from './column-index.decorator'; export * from './relations'; +export * from './virtual-column.decorator'; diff --git a/packages/core/src/core/decorators/entity/virtual-column.decorator.ts b/packages/core/src/core/decorators/entity/virtual-column.decorator.ts new file mode 100644 index 00000000000..a7ede967b51 --- /dev/null +++ b/packages/core/src/core/decorators/entity/virtual-column.decorator.ts @@ -0,0 +1,17 @@ +import { Property as MikroORMColumn, PropertyOptions as MikroORMPropertyOptions } from '@mikro-orm/core'; + +/** + * Custom decorator to define a non-persistent (virtual) column in a MikroORM entity. + * + * @param options Additional options for the property. Defaults to { persist: false }. + * @returns A property decorator function. + */ +export function VirtualMultiOrmColumn( + options: MikroORMPropertyOptions = { + persist: false + } +): PropertyDecorator { + return (target: any, propertyKey: string) => { + MikroORMColumn(options)(target, propertyKey); + }; +} diff --git a/packages/core/src/email-reset/email-reset.entity.ts b/packages/core/src/email-reset/email-reset.entity.ts index c5ee104a9a3..b77283c5df8 100644 --- a/packages/core/src/email-reset/email-reset.entity.ts +++ b/packages/core/src/email-reset/email-reset.entity.ts @@ -7,7 +7,7 @@ import { IsEmail, IsOptional, IsUUID } from 'class-validator'; import { Exclude } from 'class-transformer'; import { IEmailReset, IUser } from '@gauzy/contracts'; import { TenantBaseEntity, User } from '../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from './../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmEmailResetRepository } from './repository/mikro-orm-email-reset.repository'; @MultiORMEntity('email_reset', { mikroOrmRepository: () => MikroOrmEmailResetRepository }) @@ -39,6 +39,8 @@ export class EmailReset extends TenantBaseEntity implements IEmailReset { @MultiORMColumn({ nullable: true }) expiredAt: Date; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() isExpired: boolean; /* diff --git a/packages/core/src/email-template/email-template.entity.ts b/packages/core/src/email-template/email-template.entity.ts index 6ea32435cd6..2ec199bf900 100644 --- a/packages/core/src/email-template/email-template.entity.ts +++ b/packages/core/src/email-template/email-template.entity.ts @@ -2,7 +2,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { IEmailTemplate } from '@gauzy/contracts'; import { isMySQL } from "@gauzy/config"; import { TenantOrganizationBaseEntity } from '../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity } from './../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmEmailTemplateRepository } from './repository/mikro-orm-email-template.repository'; @MultiORMEntity('email_template', { mikroOrmRepository: () => MikroOrmEmailTemplateRepository }) @@ -27,6 +27,8 @@ export class EmailTemplate extends TenantOrganizationBaseEntity @MultiORMColumn({ ...(isMySQL() ? { type: "longtext" } : {}) }) hbs: string; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() title?: string; /* diff --git a/packages/core/src/employee/employee.entity.ts b/packages/core/src/employee/employee.entity.ts index 61f7b8b1f99..33536f6313b 100644 --- a/packages/core/src/employee/employee.entity.ts +++ b/packages/core/src/employee/employee.entity.ts @@ -9,7 +9,8 @@ import { MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany, - MultiORMOneToOne + MultiORMOneToOne, + VirtualMultiOrmColumn } from './../core/decorators/entity'; import { CurrenciesEnum, @@ -326,10 +327,11 @@ export class Employee extends TenantOrganizationBaseEntity implements IEmployee @MultiORMColumn({ nullable: true }) linkedInId?: string; - /** - * Additional Property - */ + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullName?: string; + + @VirtualMultiOrmColumn() isDeleted?: boolean; /* diff --git a/packages/core/src/export-import/import-history/import-history.entity.ts b/packages/core/src/export-import/import-history/import-history.entity.ts index e213fb3bd22..660f3cf2fc3 100644 --- a/packages/core/src/export-import/import-history/import-history.entity.ts +++ b/packages/core/src/export-import/import-history/import-history.entity.ts @@ -3,7 +3,7 @@ import { IsDate, IsEnum, IsNotEmpty, IsNumber, IsOptional } from 'class-validato import { Exclude } from 'class-transformer'; import { IImportHistory, ImportStatusEnum } from '@gauzy/contracts'; import { TenantBaseEntity } from '../../core/entities/internal'; -import { MultiORMColumn, MultiORMEntity } from '../../core/decorators/entity'; +import { MultiORMColumn, MultiORMEntity, VirtualMultiOrmColumn } from '../../core/decorators/entity'; import { MikroOrmImportHistoryRepository } from './repository/mikro-orm-import-history.repository'; @MultiORMEntity('import-history', { mikroOrmRepository: () => MikroOrmImportHistoryRepository }) @@ -38,5 +38,7 @@ export class ImportHistory extends TenantBaseEntity implements IImportHistory { @MultiORMColumn({ default: () => 'CURRENT_TIMESTAMP' }) importDate?: Date; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() public fullUrl?: string; } diff --git a/packages/core/src/export-import/import-record/import-record.entity.ts b/packages/core/src/export-import/import-record/import-record.entity.ts index 1bef1df5556..02c97aa12b5 100644 --- a/packages/core/src/export-import/import-record/import-record.entity.ts +++ b/packages/core/src/export-import/import-record/import-record.entity.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsDate } from 'class-validator'; import { IImportRecord } from '@gauzy/contracts'; -import { MultiORMColumn, MultiORMEntity } from './../../core/decorators/entity'; +import { MultiORMColumn, MultiORMEntity, VirtualMultiOrmColumn } from './../../core/decorators/entity'; import { TenantBaseEntity } from '../../core/entities/internal'; import { MikroOrmImportRecordRepository } from './repository/mikro-orm-import-record.repository'; @@ -25,5 +25,7 @@ export class ImportRecord extends TenantBaseEntity implements IImportRecord { @MultiORMColumn({ nullable: false, default: () => 'CURRENT_TIMESTAMP' }) importDate?: Date; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() wasCreated?: boolean; } diff --git a/packages/core/src/feature/feature.entity.ts b/packages/core/src/feature/feature.entity.ts index 7a634a363b1..21f5421dc23 100644 --- a/packages/core/src/feature/feature.entity.ts +++ b/packages/core/src/feature/feature.entity.ts @@ -9,7 +9,7 @@ import { IFeatureOrganization } from '@gauzy/contracts'; import { BaseEntity, FeatureOrganization } from '../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, MultiORMOneToMany } from './../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, MultiORMOneToMany, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmFeatureRepository } from './repository/mikro-orm-feature.repository'; @MultiORMEntity('feature', { mikroOrmRepository: () => MikroOrmFeatureRepository }) @@ -49,7 +49,11 @@ export class Feature extends BaseEntity implements IFeature { @MultiORMColumn({ nullable: true }) icon: string; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() isEnabled?: boolean; + + @VirtualMultiOrmColumn() imageUrl?: string; /* diff --git a/packages/core/src/image-asset/image-asset.entity.ts b/packages/core/src/image-asset/image-asset.entity.ts index 29291cca42f..9500c41bd68 100644 --- a/packages/core/src/image-asset/image-asset.entity.ts +++ b/packages/core/src/image-asset/image-asset.entity.ts @@ -9,7 +9,7 @@ import { Equipment, Warehouse } from './../core/entities/internal'; -import { MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMOneToMany } from './../core/decorators/entity'; +import { MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMOneToMany, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmImageAssetRepository } from './repository/mikro-orm-image-asset.repository'; @MultiORMEntity('image_asset', { mikroOrmRepository: () => MikroOrmImageAssetRepository }) @@ -75,9 +75,11 @@ export class ImageAsset extends TenantOrganizationBaseEntity implements IImageAs }) storageProvider?: FileStorageProviderEnum; - - /** Additional fields */ + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullUrl?: string; + + @VirtualMultiOrmColumn() thumbUrl?: string; /* diff --git a/packages/core/src/integration/integration.entity.ts b/packages/core/src/integration/integration.entity.ts index 1f49b9993e4..259293118a6 100644 --- a/packages/core/src/integration/integration.entity.ts +++ b/packages/core/src/integration/integration.entity.ts @@ -5,7 +5,7 @@ import { IIntegration, IIntegrationType, ITag } from '@gauzy/contracts'; import { ColumnNumericTransformerPipe } from './../shared/pipes'; import { BaseEntity, Tag } from '../core/entities/internal'; import { IntegrationType } from './integration-type.entity'; -import { MultiORMColumn, MultiORMEntity, MultiORMManyToMany } from './../core/decorators/entity'; +import { MultiORMColumn, MultiORMEntity, MultiORMManyToMany, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmIntegrationRepository } from './repository/mikro-orm-integration.repository'; @MultiORMEntity('integration', { mikroOrmRepository: () => MikroOrmIntegrationRepository }) @@ -77,7 +77,8 @@ export class Integration extends BaseEntity implements IIntegration { @MultiORMColumn({ nullable: true }) order: number; - /** Additional fields */ + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullImgUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/organization-team-join-request/organization-team-join-request.entity.ts b/packages/core/src/organization-team-join-request/organization-team-join-request.entity.ts index ff18ed81fc6..c9fbb2d3750 100644 --- a/packages/core/src/organization-team-join-request/organization-team-join-request.entity.ts +++ b/packages/core/src/organization-team-join-request/organization-team-join-request.entity.ts @@ -9,7 +9,7 @@ import { OrganizationTeamJoinRequestStatusEnum } from '@gauzy/contracts'; import { OrganizationTeam, TenantOrganizationBaseEntity, User } from '../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from './../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmOrganizationTeamJoinRequestRepository } from './repository/mikro-orm-organization-team-join-request.repository'; @MultiORMEntity('organization_team_join_request', { mikroOrmRepository: () => MikroOrmOrganizationTeamJoinRequestRepository }) @@ -58,7 +58,8 @@ export class OrganizationTeamJoinRequest extends TenantOrganizationBaseEntity @MultiORMColumn({ nullable: true }) expiredAt: Date; - /** Additional fields */ + /** Additional virtual columns */ + @VirtualMultiOrmColumn() isExpired: boolean; /* diff --git a/packages/core/src/password-reset/password-reset.entity.ts b/packages/core/src/password-reset/password-reset.entity.ts index fb806013028..d85602035ce 100644 --- a/packages/core/src/password-reset/password-reset.entity.ts +++ b/packages/core/src/password-reset/password-reset.entity.ts @@ -4,7 +4,7 @@ import * as moment from 'moment'; import { IPasswordReset } from '@gauzy/contracts'; import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; import { TenantBaseEntity } from './../core/entities/tenant-base.entity'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity } from './../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmPasswordResetRepository } from './repository/mikro-orm-password-reset.repository'; @MultiORMEntity('password_reset', { mikroOrmRepository: () => MikroOrmPasswordResetRepository }) @@ -26,7 +26,8 @@ export class PasswordReset extends TenantBaseEntity implements IPasswordReset { @MultiORMColumn() token: string; - /** */ + /** Additional virtual columns */ + @VirtualMultiOrmColumn() expired?: boolean; /** diff --git a/packages/core/src/reports/report.entity.ts b/packages/core/src/reports/report.entity.ts index 31bf9139a88..dfaf9eb2720 100644 --- a/packages/core/src/reports/report.entity.ts +++ b/packages/core/src/reports/report.entity.ts @@ -8,7 +8,7 @@ import { IReport, IReportCategory, IReportOrganization } from '@gauzy/contracts' import { BaseEntity } from '../core/entities/internal'; import { ReportCategory } from './report-category.entity'; import { ReportOrganization } from './report-organization.entity'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, MultiORMOneToMany } from './../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, MultiORMOneToMany, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmReportRepository } from './repository/mikro-orm-report.repository'; @MultiORMEntity('report', { mikroOrmRepository: () => MikroOrmReportRepository }) @@ -48,6 +48,8 @@ export class Report extends BaseEntity implements IReport { @MultiORMColumn({ default: false }) showInMenu?: boolean; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() imageUrl?: string; /* diff --git a/packages/core/src/tasks/issue-type/issue-type.entity.ts b/packages/core/src/tasks/issue-type/issue-type.entity.ts index ddfc14340f2..117fe96bc5a 100644 --- a/packages/core/src/tasks/issue-type/issue-type.entity.ts +++ b/packages/core/src/tasks/issue-type/issue-type.entity.ts @@ -16,7 +16,7 @@ import { OrganizationTeam, TenantOrganizationBaseEntity, } from './../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from './../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from './../../core/decorators/entity'; import { MikroOrmIssueTypeRepository } from './repository/mikro-orm-issue-type.repository'; @MultiORMEntity('issue_type', { mikroOrmRepository: () => MikroOrmIssueTypeRepository }) @@ -53,6 +53,8 @@ export class IssueType extends TenantOrganizationBaseEntity implements IIssueTyp @MultiORMColumn({ default: false, update: false }) isSystem?: boolean; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullIconUrl?: string; /* diff --git a/packages/core/src/tasks/priorities/priority.entity.ts b/packages/core/src/tasks/priorities/priority.entity.ts index 9276ff8b9b1..2705bd6bda4 100644 --- a/packages/core/src/tasks/priorities/priority.entity.ts +++ b/packages/core/src/tasks/priorities/priority.entity.ts @@ -3,7 +3,7 @@ import { RelationId } from 'typeorm'; import { IOrganizationProject, IOrganizationTeam, ITaskPriority } from '@gauzy/contracts'; import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; import { OrganizationProject, OrganizationTeam, TenantOrganizationBaseEntity } from './../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from './../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from './../../core/decorators/entity'; import { MikroOrmTaskPriorityRepository } from './repository/mikro-orm-task-priority.repository'; @MultiORMEntity('task_priority', { mikroOrmRepository: () => MikroOrmTaskPriorityRepository }) @@ -39,6 +39,8 @@ export class TaskPriority extends TenantOrganizationBaseEntity implements ITaskP @MultiORMColumn({ default: false, update: false }) isSystem?: boolean; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullIconUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/tasks/related-issue-type/related-issue-type.entity.ts b/packages/core/src/tasks/related-issue-type/related-issue-type.entity.ts index 7ae63f2f606..b0ab8880fcd 100644 --- a/packages/core/src/tasks/related-issue-type/related-issue-type.entity.ts +++ b/packages/core/src/tasks/related-issue-type/related-issue-type.entity.ts @@ -11,7 +11,7 @@ import { OrganizationTeam, TenantOrganizationBaseEntity, } from '../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from './../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from './../../core/decorators/entity'; import { MikroOrmTaskRelatedIssueTypeRepository } from './repository/mikro-orm-related-issue-type.repository'; @MultiORMEntity('task_related_issue_type', { mikroOrmRepository: () => MikroOrmTaskRelatedIssueTypeRepository }) @@ -48,6 +48,8 @@ export class TaskRelatedIssueType extends TenantOrganizationBaseEntity implement @MultiORMColumn({ default: false, update: false }) isSystem?: boolean; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullIconUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/tasks/sizes/size.entity.ts b/packages/core/src/tasks/sizes/size.entity.ts index 223442d9f9a..b9f1e68b7c3 100644 --- a/packages/core/src/tasks/sizes/size.entity.ts +++ b/packages/core/src/tasks/sizes/size.entity.ts @@ -7,7 +7,7 @@ import { OrganizationTeam, TenantOrganizationBaseEntity, } from './../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from './../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from './../../core/decorators/entity'; import { MikroOrmTaskSizeRepository } from './repository/mikro-orm-task-size.repository'; @MultiORMEntity('task_size', { mikroOrmRepository: () => MikroOrmTaskSizeRepository }) @@ -44,6 +44,8 @@ export class TaskSize extends TenantOrganizationBaseEntity implements ITaskSize @MultiORMColumn({ default: false, update: false }) isSystem?: boolean; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullIconUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/tasks/statuses/status.entity.ts b/packages/core/src/tasks/statuses/status.entity.ts index 2715fed5e78..b19381d8742 100644 --- a/packages/core/src/tasks/statuses/status.entity.ts +++ b/packages/core/src/tasks/statuses/status.entity.ts @@ -4,7 +4,7 @@ import { EntityRepositoryType } from '@mikro-orm/knex'; import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; import { IOrganizationProject, IOrganizationTeam, ITaskStatus } from '@gauzy/contracts'; import { OrganizationProject, OrganizationTeam, TenantOrganizationBaseEntity } from '../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from '../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from '../../core/decorators/entity'; import { MikroOrmTaskStatusRepository } from './repository'; @MultiORMEntity('task_status', { mikroOrmRepository: () => MikroOrmTaskStatusRepository }) @@ -54,9 +54,8 @@ export class TaskStatus extends TenantOrganizationBaseEntity implements ITaskSta @MultiORMColumn({ default: false }) isCollapsed?: boolean; - /** - * Additional Property - */ + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullIconUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/tasks/task.entity.ts b/packages/core/src/tasks/task.entity.ts index 1ab10652be3..122b667faea 100644 --- a/packages/core/src/tasks/task.entity.ts +++ b/packages/core/src/tasks/task.entity.ts @@ -52,7 +52,7 @@ import { TimeLog, User, } from '../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany } from './../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany, VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmTaskRepository } from './repository/mikro-orm-task.repository'; @MultiORMEntity('task', { mikroOrmRepository: () => MikroOrmTaskRepository }) @@ -150,10 +150,12 @@ export class Task extends TenantOrganizationBaseEntity implements ITask { @MultiORMColumn({ nullable: true }) version?: string; - /** - * Additional exposed fields - */ + /** Additional virtual columns */ + @VirtualMultiOrmColumn() taskNumber?: string; + + /** Additional virtual columns */ + @VirtualMultiOrmColumn() rootEpic?: ITask; /* diff --git a/packages/core/src/tasks/versions/version.entity.ts b/packages/core/src/tasks/versions/version.entity.ts index 511093ddef9..213b8f474c1 100644 --- a/packages/core/src/tasks/versions/version.entity.ts +++ b/packages/core/src/tasks/versions/version.entity.ts @@ -3,7 +3,7 @@ import { RelationId } from 'typeorm'; import { IOrganizationProject, IOrganizationTeam, ITaskVersion } from '@gauzy/contracts'; import { IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; import { OrganizationProject, OrganizationTeam, TenantOrganizationBaseEntity } from '../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from '../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from '../../core/decorators/entity'; import { MikroOrmTaskVersionRepository } from './repository/mikro-orm-task-version.repository'; @MultiORMEntity('task_version', { mikroOrmRepository: () => MikroOrmTaskVersionRepository }) @@ -40,6 +40,8 @@ export class TaskVersion extends TenantOrganizationBaseEntity implements ITaskVe @MultiORMColumn({ default: false, update: false }) isSystem?: boolean; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() fullIconUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/time-tracking/screenshot/screenshot.entity.ts b/packages/core/src/time-tracking/screenshot/screenshot.entity.ts index 6bb52fe6e20..45af8baf472 100644 --- a/packages/core/src/time-tracking/screenshot/screenshot.entity.ts +++ b/packages/core/src/time-tracking/screenshot/screenshot.entity.ts @@ -5,7 +5,7 @@ import { IsString, IsOptional, IsDateString, IsUUID, IsNotEmpty, IsEnum, IsBoole import { Exclude } from 'class-transformer'; import { FileStorageProviderEnum, IScreenshot, ITimeSlot, IUser } from '@gauzy/contracts'; import { isBetterSqlite3, isSqlite } from '@gauzy/config'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from '../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from '../../core/decorators/entity'; import { TenantOrganizationBaseEntity, TimeSlot, User } from './../../core/entities/internal'; import { MikroOrmScreenshotRepository } from './repository/mikro-orm-screenshot.repository'; @@ -90,10 +90,10 @@ export class Screenshot extends TenantOrganizationBaseEntity implements IScreens apps?: string | string[]; /** Additional virtual columns */ - @Property({ persist: false }) + @VirtualMultiOrmColumn() fullUrl?: string; - @Property({ persist: false }) + @VirtualMultiOrmColumn() thumbUrl?: string; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/time-tracking/time-log/time-log.entity.ts b/packages/core/src/time-tracking/time-log/time-log.entity.ts index e350f2453ed..6c1dbcc58f2 100644 --- a/packages/core/src/time-tracking/time-log/time-log.entity.ts +++ b/packages/core/src/time-tracking/time-log/time-log.entity.ts @@ -26,7 +26,7 @@ import { Timesheet, TimeSlot } from './../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne } from '../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, VirtualMultiOrmColumn } from '../../core/decorators/entity'; import { MikroOrmTimeLogRepository } from './repository/mikro-orm-time-log.repository'; @MultiORMEntity('time_log', { mikroOrmRepository: () => MikroOrmTimeLogRepository }) @@ -101,8 +101,8 @@ export class TimeLog extends TenantOrganizationBaseEntity implements ITimeLog { @MultiORMColumn({ update: false, nullable: true }) version?: string; - /** Additional fields */ - @Property({ persist: false }) + /** Additional virtual columns */ + @VirtualMultiOrmColumn() duration: number; /** @@ -110,7 +110,7 @@ export class TimeLog extends TenantOrganizationBaseEntity implements ITimeLog { * If the value is true, it means the TimeLog has been edited. * If the value is false or undefined, it means the TimeLog has not been edited. */ - @Property({ persist: false }) + @VirtualMultiOrmColumn() isEdited?: boolean; /* diff --git a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts index d25d8abdbe4..1a2c69288de 100644 --- a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts +++ b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts @@ -21,7 +21,7 @@ import { TimeLog } from './../../core/entities/internal'; import { TimeSlotMinute } from './time-slot-minute.entity'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany } from './../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, MultiORMOneToMany, VirtualMultiOrmColumn } from './../../core/decorators/entity'; import { MikroOrmTimeSlotRepository } from './repository/mikro-orm-time-slot.repository'; @MultiORMEntity('time_slot', { mikroOrmRepository: () => MikroOrmTimeSlotRepository }) @@ -62,16 +62,16 @@ export class TimeSlot extends TenantOrganizationBaseEntity startedAt: Date; /** Additional virtual columns */ - @Property({ persist: false }) + @VirtualMultiOrmColumn() stoppedAt?: Date; - @Property({ persist: false }) + @VirtualMultiOrmColumn() percentage?: number; - @Property({ persist: false }) + @VirtualMultiOrmColumn() keyboardPercentage?: number; - @Property({ persist: false }) + @VirtualMultiOrmColumn() mousePercentage?: number; /* |-------------------------------------------------------------------------- diff --git a/packages/core/src/time-tracking/timesheet/timesheet.entity.ts b/packages/core/src/time-tracking/timesheet/timesheet.entity.ts index ef364d5c4b5..0ce57c225a4 100644 --- a/packages/core/src/time-tracking/timesheet/timesheet.entity.ts +++ b/packages/core/src/time-tracking/timesheet/timesheet.entity.ts @@ -11,7 +11,7 @@ import { TenantOrganizationBaseEntity, User } from './../../core/entities/internal'; -import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne } from './../../core/decorators/entity'; +import { ColumnIndex, MultiORMColumn, MultiORMEntity, MultiORMManyToOne, VirtualMultiOrmColumn } from './../../core/decorators/entity'; import { MikroOrmTimesheetRepository } from './repository/mikro-orm-timesheet.repository'; @MultiORMEntity('timesheet', { mikroOrmRepository: () => MikroOrmTimesheetRepository }) @@ -97,13 +97,14 @@ export class Timesheet extends TenantOrganizationBaseEntity implements ITimeshee @MultiORMColumn({ default: TimesheetStatus.PENDING }) status: string; - /** Additional fields */ + /** Additional virtual columns */ /** * Indicates whether the Timesheet has been edited. * If the value is true, it means the Timesheet has been edited. * If the value is false or undefined, it means the Timesheet has not been edited. */ + @VirtualMultiOrmColumn() isEdited?: boolean; /* diff --git a/packages/core/src/user/user.entity.ts b/packages/core/src/user/user.entity.ts index b347b7007a0..976a99412ff 100644 --- a/packages/core/src/user/user.entity.ts +++ b/packages/core/src/user/user.entity.ts @@ -24,7 +24,8 @@ import { MultiORMEntity, MultiORMManyToMany, MultiORMManyToOne, - MultiORMOneToMany + MultiORMOneToMany, + VirtualMultiOrmColumn } from './../core/decorators/entity'; import { MikroOrmUserRepository } from './repository/mikro-orm-user.repository'; @@ -142,8 +143,11 @@ export class User extends TenantBaseEntity implements IUser { @MultiORMColumn({ insert: false, nullable: true }) emailToken?: string; + /** Additional virtual columns */ + @VirtualMultiOrmColumn() name?: string; + @VirtualMultiOrmColumn() isEmailVerified?: boolean; /* From 91d1f59dabcb416fa9b9c5d6f46ec3667b64be3c Mon Sep 17 00:00:00 2001 From: RAHUL RATHORE <41804588+rahul-rocket@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:29:07 +0530 Subject: [PATCH 5/6] fix: try to "convert" one method (organization team) --- packages/core/src/core/utils.ts | 17 ++++ .../organization-team.service.ts | 96 +++++++++---------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/packages/core/src/core/utils.ts b/packages/core/src/core/utils.ts index 65cea407961..46f4b4f8a11 100644 --- a/packages/core/src/core/utils.ts +++ b/packages/core/src/core/utils.ts @@ -491,6 +491,23 @@ export function concatIdToWhere(id: any, where: MikroFilterQuery): MikroFi return where; } +/** + * Adds 'tenantId' to a 'where' clause, supporting both objects and arrays. + * + * @param tenantId - The tenant ID to add. + * @param where - The current 'where' clause. + * @returns An updated 'where' clause including the 'tenantId'. + */ +export function enhanceWhereWithTenantId(tenantId: any, where: MikroFilterQuery): MikroFilterQuery { + if (Array.isArray(where)) { + // Merge tenantId into each object of the array + return where.map(condition => ({ ...condition, tenantId })); + } else { + // Merge where with tenantId if where is an object + return { ...where, tenantId }; + } +} + /** * Convert TypeORM's FindManyOptions to MikroORM's equivalent options. * diff --git a/packages/core/src/organization-team/organization-team.service.ts b/packages/core/src/organization-team/organization-team.service.ts index e1eea90e584..23839212e98 100644 --- a/packages/core/src/organization-team/organization-team.service.ts +++ b/packages/core/src/organization-team/organization-team.service.ts @@ -5,7 +5,7 @@ import { ForbiddenException, NotFoundException } from '@nestjs/common'; -import { In, ILike, SelectQueryBuilder, DeleteResult, IsNull } from 'typeorm'; +import { In, ILike, SelectQueryBuilder, DeleteResult, IsNull, FindManyOptions } from 'typeorm'; import { QueryOrder } from '@mikro-orm/knex'; import { IOrganizationTeamCreateInput, @@ -23,7 +23,7 @@ import { } from '@gauzy/contracts'; import { isNotEmpty, parseToBoolean } from '@gauzy/common'; import { Employee, OrganizationTeamEmployee } from '../core/entities/internal'; -import { MultiORMEnum } from '../core/utils'; +import { MultiORMEnum, enhanceWhereWithTenantId, parseTypeORMFindToMikroOrm } from '../core/utils'; import { PaginationParams, TenantAwareCrudService } from '../core/crud'; import { RequestContext } from '../core/context'; import { RoleService } from '../role/role.service'; @@ -388,29 +388,42 @@ export class OrganizationTeamService extends TenantAwareCrudService { - // Create a separate query builder for the subquery - const subQuery = this.mikroOrmOrganizationTeamEmployeeRepository.createQueryBuilder('team'); - // Start building the subquery - subQuery.select(['team.organizationTeamId']); - subQuery.andWhere({ 'team.tenantId': tenantId }); // Apply the tenant filter - subQuery.andWhere({ 'team.isActive': true }); - subQuery.andWhere({ 'team.isArchived': false }); - subQuery.andWhere({ 'team.employeeId': employeeId }); + /** + * Fetches distinct organization team IDs for a given employee. + * Filters based on employee ID, tenant ID, and optionally organization ID. + * + * @param employeeId - The ID of the employee to filter the teams by. + * @returns A Promise that resolves to an array of unique organization team IDs. + */ + const fetchDistinctOrgTeamIdsForEmployee = async (employeeId: string): Promise => { + const knex = this.mikroOrmOrganizationTeamEmployeeRepository.getKnex(); + + // Construct your SQL query using knex + let sqlQuery = knex('organization_team_employee').select( + knex.raw(` + DISTINCT ON ("organization_team_employee"."organizationTeamId") + "organization_team_employee"."organizationTeamId" + `) + ); + + // Builds an SQL query with specific where clauses. + sqlQuery.andWhere({ tenantId }); + sqlQuery.andWhere({ employeeId }); + sqlQuery.andWhere({ isActive: true }); + sqlQuery.andWhere({ isArchived: false }); // Apply the organization filter if available if (options?.where?.organizationId) { const { organizationId } = options.where; - subQuery.andWhere({ 'team.organizationId': organizationId }); + sqlQuery.andWhere({ organizationId }); } - // Return the subquery as a string - return subQuery.getQuery(); + // Execute the raw SQL query and get the results + const rawResults: OrganizationTeamEmployee[] = (await knex.raw(sqlQuery.toString())).rows || []; + const organizationTeamIds = rawResults.map((entry: OrganizationTeamEmployee) => entry.organizationTeamId); + + // Convert to string for the subquery + return organizationTeamIds || []; }; // If admin has login and doesn't have permission to change employee @@ -421,46 +434,29 @@ export class OrganizationTeamService extends TenantAwareCrudService { - acc[field] = direction === 'ASC' ? QueryOrder.ASC : QueryOrder.DESC; - return acc; - }, {}); - mikroOrmQueryBuilder.orderBy(orderBy); - } + // Fetches distinct organization team IDs for a given employee. + const organizationTeamIds = await fetchDistinctOrgTeamIdsForEmployee(employeeId); + options.where.id = In(organizationTeamIds); } - // Add a condition for the tenant ID - mikroOrmQueryBuilder.andWhere({ tenantId }); - // console.log(mikroOrmQueryBuilder.getQuery(), mikroOrmQueryBuilder.getParams(), 'Organization Team Mikro ORM Query'); - + // Converts TypeORM find options to a format compatible with MikroORM for a given entity. + const { where, mikroOptions } = parseTypeORMFindToMikroOrm(options as FindManyOptions); // Retrieve the items and total count - [items, total] = await mikroOrmQueryBuilder.getResultAndCount(); + const [entities, totalEntities] = await this.mikroOrmOrganizationTeamRepository.findAndCount( + enhanceWhereWithTenantId(tenantId, where), // Add a condition for the tenant ID + mikroOptions + ); // Optionally serialize the items - items = items.map((item: OrganizationTeam) => this.serialize(item)); + items = entities.map((item: OrganizationTeam) => this.serialize(item)) as OrganizationTeam[]; + total = totalEntities; break; case MultiORMEnum.TypeORM: // Create a query builder for the OrganizationTeam entity From 6eb8dc7ec33b3f3dfdad83b3e68719e2123a8df4 Mon Sep 17 00:00:00 2001 From: RAHUL RATHORE <41804588+rahul-rocket@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:54:47 +0530 Subject: [PATCH 6/6] fix(deepscan): removed unused import --- .../core/src/organization-team/organization-team.service.ts | 1 - packages/core/src/time-tracking/screenshot/screenshot.entity.ts | 1 - packages/core/src/time-tracking/time-log/time-log.entity.ts | 2 +- packages/core/src/time-tracking/time-slot/time-slot.entity.ts | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/core/src/organization-team/organization-team.service.ts b/packages/core/src/organization-team/organization-team.service.ts index 23839212e98..ae1bf109136 100644 --- a/packages/core/src/organization-team/organization-team.service.ts +++ b/packages/core/src/organization-team/organization-team.service.ts @@ -6,7 +6,6 @@ import { NotFoundException } from '@nestjs/common'; import { In, ILike, SelectQueryBuilder, DeleteResult, IsNull, FindManyOptions } from 'typeorm'; -import { QueryOrder } from '@mikro-orm/knex'; import { IOrganizationTeamCreateInput, IOrganizationTeam, diff --git a/packages/core/src/time-tracking/screenshot/screenshot.entity.ts b/packages/core/src/time-tracking/screenshot/screenshot.entity.ts index 45af8baf472..35ecd1849ab 100644 --- a/packages/core/src/time-tracking/screenshot/screenshot.entity.ts +++ b/packages/core/src/time-tracking/screenshot/screenshot.entity.ts @@ -1,6 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { RelationId, JoinColumn } from 'typeorm'; -import { Property } from '@mikro-orm/core'; import { IsString, IsOptional, IsDateString, IsUUID, IsNotEmpty, IsEnum, IsBoolean } from 'class-validator'; import { Exclude } from 'class-transformer'; import { FileStorageProviderEnum, IScreenshot, ITimeSlot, IUser } from '@gauzy/contracts'; diff --git a/packages/core/src/time-tracking/time-log/time-log.entity.ts b/packages/core/src/time-tracking/time-log/time-log.entity.ts index 6c1dbcc58f2..d417d7088fb 100644 --- a/packages/core/src/time-tracking/time-log/time-log.entity.ts +++ b/packages/core/src/time-tracking/time-log/time-log.entity.ts @@ -1,5 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; -import { OnLoad, Property } from '@mikro-orm/core'; +import { OnLoad } from '@mikro-orm/core'; import { RelationId, JoinColumn, AfterLoad } from 'typeorm'; import { IsBoolean, IsDateString, IsEnum, IsOptional, IsString, IsUUID } from 'class-validator'; import * as moment from 'moment'; diff --git a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts index 1a2c69288de..85a6a36a416 100644 --- a/packages/core/src/time-tracking/time-slot/time-slot.entity.ts +++ b/packages/core/src/time-tracking/time-slot/time-slot.entity.ts @@ -3,7 +3,6 @@ import { RelationId, JoinTable } from 'typeorm'; -import { Property } from '@mikro-orm/core'; import { IsNumber, IsDateString, IsUUID, IsNotEmpty, IsOptional } from 'class-validator'; import { ITimeSlot,