Files
edr-platform/apps/edr-freight-api/src/modules/dropdown-settings/dropdown-settings.repository.ts
Marshal 4b7f6d2548 enhance contract and booking services with server-side search and validation improvements
- Added  parameter to  and  for server-side free-text search on contract reference, company name, and booking details.
- Introduced new validation errors in  for container clashes and space issues when creating bookings.
- Implemented paginated dropdown settings retrieval in .
- Updated  to fetch active yards using a new method that handles pagination.
- Enhanced  with a  method to fetch all records by walking through pages.
- Refactored  to support filtering and pagination in schedule listings.
- Improved  to return a paginated list of facilities.
- Updated UI components in  and  to utilize debounced search inputs for better performance.
- Added alerts in  to inform users about booking constraints related to splits and capacity.
- Enhanced  to display notifications for split bookings and capacity usage.
2026-07-12 10:51:31 +00:00

107 lines
3.4 KiB
TypeScript

import { BaseRepository } from "@edr/api-common";
import { PaginatedResponse } from "@edr/types";
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { paginateQuery } from "../../common/utils/pagination.util";
import { ListDropdownSettingsQueryDto } from "./dto/list-dropdown-settings-query.dto";
import { DropdownOption } from "./entities/dropdown-option.entity";
import { DropdownSetting } from "./entities/dropdown-setting.entity";
import type { IDropdownSettingsRepository } from "./interfaces/dropdown-settings.repository.interface";
@Injectable()
export class DropdownSettingsRepository
extends BaseRepository<DropdownSetting>
implements IDropdownSettingsRepository
{
constructor(
@InjectRepository(DropdownSetting)
repository: Repository<DropdownSetting>,
@InjectRepository(DropdownOption)
private readonly optionsRepository: Repository<DropdownOption>,
) {
super(repository);
}
findByCode(code: string): Promise<DropdownSetting | null> {
return this.repository.findOne({
where: { code },
relations: { children: true },
order: { children: { order: "ASC" } },
});
}
override findById(id: string): Promise<DropdownSetting | null> {
return this.repository.findOne({
where: { id },
relations: { children: true },
order: { children: { order: "ASC" } },
});
}
override findAll(): Promise<DropdownSetting[]> {
return this.repository.find({
order: { label: "ASC", children: { order: "ASC" } },
relations: { children: true },
});
}
findPaged(
query: ListDropdownSettingsQueryDto,
): Promise<PaginatedResponse<DropdownSetting>> {
// Soft-deleted rows are excluded automatically by the query builder
// (BaseEntity's deletedAt column). Ordering mirrors findAll (label ASC).
const qb = this.repository
.createQueryBuilder("setting")
.leftJoinAndSelect("setting.children", "option")
.orderBy("setting.label", query.sortOrder ?? "ASC")
.addOrderBy("option.order", "ASC");
if (query.search) {
qb.andWhere(
"(setting.code ILIKE :search OR setting.label ILIKE :search OR setting.description ILIKE :search)",
{ search: `%${query.search}%` },
);
}
return paginateQuery(qb, query);
}
async replaceOptions(
settingId: string,
options: Array<Partial<DropdownOption>>,
): Promise<DropdownOption[]> {
await this.optionsRepository.delete({ settingId });
if (options.length === 0) return [];
const entities = options.map((o, idx) =>
this.optionsRepository.create({
...o,
settingId,
order: o.order ?? idx + 1,
}),
);
return this.optionsRepository.save(entities);
}
async addOption(
settingId: string,
option: Partial<DropdownOption>,
): Promise<DropdownOption> {
const entity = this.optionsRepository.create({ ...option, settingId });
return this.optionsRepository.save(entity);
}
async updateOption(
optionId: string,
data: Partial<DropdownOption>,
): Promise<DropdownOption | null> {
await this.optionsRepository.update(optionId, data as never);
return this.optionsRepository.findOne({ where: { id: optionId } });
}
async removeOption(optionId: string): Promise<void> {
await this.optionsRepository.softDelete(optionId);
}
}