From f91e841e208191eb62d1f3e14e7c01160cf7b61f Mon Sep 17 00:00:00 2001 From: Ha Minh Chien Date: Wed, 25 Dec 2024 15:23:32 +0700 Subject: [PATCH] feat(external): add ResultExternalPage and related routing --- apps/hcdc-access-service/.env.local | 4 +- .../print-form/print-template/reminder.ejs | 118 ++++++++++++ .../src/app/sample/module.ts | 2 + .../app/sample/use-case/generate-print-url.ts | 11 +- .../src/app/sample/use-case/print-reminder.ts | 134 +++++++++++++ apps/hcdc-access-service/src/config/app.ts | 5 + .../controller/http/external/auth/common.ts | 12 ++ .../controller/http/external/auth/guard.ts | 3 +- .../controller/http/external/auth/index.ts | 3 +- .../controller/http/external/controller.ts | 69 ++++++- .../http/external/dto/get-sample-result.ts | 47 +++++ .../controller/http/v1/sample/controller.ts | 28 ++- .../src/controller/http/v1/sample/routes.ts | 9 + .../domain/interface/auth/external-route.ts | 3 + .../api-codegen/access-service.cts | 3 +- .../src/features/external/components/index.ts | 0 .../src/features/external/index.ts | 2 +- .../pages/ResultExternalPage/index.tsx | 22 +++ .../pages/ResultExternalPage/loader.ts | 30 +++ .../src/features/external/pages/index.ts | 1 + .../components/BarcodeModal/index.tsx | 66 ++++++- .../components/InfoEditView/index.tsx | 6 +- .../components/InfoInputForm/index.tsx | 4 +- .../components/PrintSelectView/columns.tsx | 8 +- .../components/PrintSingleDialog/index.tsx | 1 - .../components/ResultCard/index.tsx | 96 +++++----- .../components/ResultEditView/index.tsx | 26 +-- .../src/infra/api/access-service/auth.ts | 8 +- .../infra/api/access-service/bio-product.ts | 12 +- .../src/infra/api/access-service/branch.ts | 12 +- .../src/infra/api/access-service/diagnosis.ts | 12 +- .../src/infra/api/access-service/doctor.ts | 12 +- .../src/infra/api/access-service/external.ts | 176 ++++++++++++++++++ .../infra/api/access-service/instrument.ts | 12 +- .../infra/api/access-service/patient-type.ts | 12 +- .../src/infra/api/access-service/patient.ts | 12 +- .../infra/api/access-service/print-form.ts | 12 +- .../src/infra/api/access-service/report.ts | 28 +-- .../src/infra/api/access-service/role.ts | 12 +- .../infra/api/access-service/sample-type.ts | 12 +- .../src/infra/api/access-service/sample.ts | 18 ++ .../infra/api/access-service/test-category.ts | 12 +- .../infra/api/access-service/test-combo.ts | 12 +- .../infra/api/access-service/test-element.ts | 12 +- .../src/infra/api/access-service/test.ts | 12 +- .../src/infra/api/access-service/user.ts | 18 +- apps/hcdc-web-app/src/infra/router/routes.tsx | 10 + libs/hcdc/src/entity/external-route/entity.ts | 1 + pnpm-lock.yaml | 8 +- 49 files changed, 949 insertions(+), 199 deletions(-) create mode 100644 apps/hcdc-access-service/src/app/print-form/print-template/reminder.ejs create mode 100644 apps/hcdc-access-service/src/app/sample/use-case/print-reminder.ts create mode 100644 apps/hcdc-access-service/src/controller/http/external/auth/common.ts create mode 100644 apps/hcdc-access-service/src/controller/http/external/dto/get-sample-result.ts delete mode 100644 apps/hcdc-web-app/src/features/external/components/index.ts create mode 100644 apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/index.tsx create mode 100644 apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/loader.ts create mode 100644 apps/hcdc-web-app/src/infra/api/access-service/external.ts diff --git a/apps/hcdc-access-service/.env.local b/apps/hcdc-access-service/.env.local index 0774c700..4d448c5d 100644 --- a/apps/hcdc-access-service/.env.local +++ b/apps/hcdc-access-service/.env.local @@ -26,4 +26,6 @@ BROWSER_SERVICE_URL=gateway-internal.envoy-gateway-system.svc.cluster.local:9000 REDIS_MASTER_GROUP_NAME=mymaster REDIS_SENTINEL_HOST=redis.infra.svc.cluster.local REDIS_SENTINEL_PORT=26379 -REDIS_REPLICAS_COUNT=2 \ No newline at end of file +REDIS_REPLICAS_COUNT=2 + +REMINDER_URL_PREFIX='https://lab.hcdc.vn/external/sample-result?jwt=' \ No newline at end of file diff --git a/apps/hcdc-access-service/src/app/print-form/print-template/reminder.ejs b/apps/hcdc-access-service/src/app/print-form/print-template/reminder.ejs new file mode 100644 index 00000000..12eb4e9e --- /dev/null +++ b/apps/hcdc-access-service/src/app/print-form/print-template/reminder.ejs @@ -0,0 +1,118 @@ + + + + + + + + + + + +
+
+ + style="width: 90px; object-fit: contain" + /> +
+

SỞ Y TẾ TP.HỒ CHÍ MINH

+

TRUNG TÂM KIỂM SOÁT BỆNH TẬT TP.HCM

+

<%= meta.branch.address %>

+

Website: www.hcdc.gov.vn

+
+
+
+

PHIẾU HẸN KẾT QUẢ XÉT NGHIỆM

+
+

+ Ngày lấy mẫu: + <%= data.sample.sampledAt.toLocaleDateString('vi') %> +

+

Nơi chỉ định: Phòng khám

+

Nơi lấy mẫu: Phòng xét nghiệm

+
+
+
+
+
+
+

+ Họ và tên: + <%= data.sample.patient.name.toLocaleUpperCase() %> +

+

+ ID XN: <%= data.sample.sampleId %> +

+
+
+

Năm sinh: <%= data.sample.patient.birthYear %>

+

Loại bệnh phẩm: Máu

+
+
+

+ Giới tính: + <%= data.sample.patient.gender === "Male" ? "Nam" : "Nữ" %> +

+

+ CCCD (nếu có): + <%= data.sample.patient.SSN %> +

+
+
+

Địa chỉ: <%= data.sample.patient.address %>

+ +
+
+
+

+ Ngày <%= new Date().getDate() %> tháng <%= new Date().getMonth() + 1 + %> năm <%= new Date().getFullYear() %> +

+

Nhân viên xét nghiệm

+

<%= meta.authorName %>

+
+
+ + /> + + diff --git a/apps/hcdc-access-service/src/app/sample/module.ts b/apps/hcdc-access-service/src/app/sample/module.ts index a2a28754..59073d8d 100644 --- a/apps/hcdc-access-service/src/app/sample/module.ts +++ b/apps/hcdc-access-service/src/app/sample/module.ts @@ -10,6 +10,7 @@ import { SampleGeneratePrintUrlUseCase } from './use-case/generate-print-url' import { SampleInitResultUseCase } from './use-case/init-result' import { SampleLockUseCase } from './use-case/lock' import { SamplePrintUseCase } from './use-case/print' +import { SamplePrintReminderUseCase } from './use-case/print-reminder' import { SampleSearchUseCase } from './use-case/search' import { SampleUnlockUseCase } from './use-case/unlock' import { SampleUpdateInfoUseCase } from './use-case/update-info' @@ -36,5 +37,6 @@ export const sampleMetadata: ModuleMetadata = { SampleUploadResultImageUseCase, SampleDownloadResultImageUseCase, SampleGeneratePrintUrlUseCase, + SamplePrintReminderUseCase, ], } diff --git a/apps/hcdc-access-service/src/app/sample/use-case/generate-print-url.ts b/apps/hcdc-access-service/src/app/sample/use-case/generate-print-url.ts index a9d3b4b9..40ab2df5 100644 --- a/apps/hcdc-access-service/src/app/sample/use-case/generate-print-url.ts +++ b/apps/hcdc-access-service/src/app/sample/use-case/generate-print-url.ts @@ -2,8 +2,11 @@ import { AuthSubject, ExternalRoutePath, SampleAction } from '@diut/hcdc' import { Inject, Injectable } from '@nestjs/common' import { assertPermission } from 'src/app/auth/common' import { AuthAuthorizeExternalRouteUseCase } from 'src/app/auth/use-case/authorize-external-route' -import { AUTH_CONTEXT_TOKEN, IAuthContext } from 'src/domain' -import { SamplePrintOptions } from '../common' +import { + AUTH_CONTEXT_TOKEN, + ExternalRouteOptions, + IAuthContext, +} from 'src/domain' import { SampleAssertExistsUseCase } from './assert-exists' @Injectable() @@ -15,7 +18,9 @@ export class SampleGeneratePrintUrlUseCase { private readonly authContext: IAuthContext, ) {} - async execute(input: { printOptions: SamplePrintOptions[] }) { + async execute( + input: ExternalRouteOptions[ExternalRoutePath.PrintSampleResult], + ) { const { ability } = this.authContext.getDataInternal() const branchIds = new Set() diff --git a/apps/hcdc-access-service/src/app/sample/use-case/print-reminder.ts b/apps/hcdc-access-service/src/app/sample/use-case/print-reminder.ts new file mode 100644 index 00000000..53cc0877 --- /dev/null +++ b/apps/hcdc-access-service/src/app/sample/use-case/print-reminder.ts @@ -0,0 +1,134 @@ +import { NodeEnv } from '@diut/common' +import { AuthSubject, ExternalRoutePath, SampleAction } from '@diut/hcdc' +import { PageFormat, PageOrientation } from '@diut/services' +import { Inject, Injectable } from '@nestjs/common' +import { render } from 'ejs' +import { readFile } from 'fs/promises' +import { join } from 'path' +import { of } from 'rxjs' +import { assertPermission } from 'src/app/auth/common' +import { AuthAuthorizeExternalRouteUseCase } from 'src/app/auth/use-case/authorize-external-route' +import { AppConfig, loadAppConfig } from 'src/config' +import { + AUTH_CONTEXT_TOKEN, + BROWSER_SERVICE_TOKEN, + EEntityNotFound, + IAuthContext, + IBrowserService, + IStorageBucket, + IStorageService, + STORAGE_BUCKET_TOKEN, + STORAGE_SERVICE_TOKEN, + StorageBucket, + StorageKeyFactory, +} from 'src/domain' +import { SampleFindOneUseCase } from './find-one' + +const TEMPLATE_PATH = 'reminder.ejs' + +@Injectable() +export class SamplePrintReminderUseCase { + constructor( + private readonly sampleFindOneUseCase: SampleFindOneUseCase, + private readonly authorizeExternalRouteUseCase: AuthAuthorizeExternalRouteUseCase, + @Inject(AUTH_CONTEXT_TOKEN) + private readonly authContext: IAuthContext, + @Inject(BROWSER_SERVICE_TOKEN) + private readonly browserService: IBrowserService, + @Inject(loadAppConfig.KEY) + private readonly appConfig: AppConfig, + @Inject(STORAGE_SERVICE_TOKEN) + private readonly storageService: IStorageService, + @Inject(STORAGE_BUCKET_TOKEN) + private readonly storageBucket: IStorageBucket, + ) {} + + async execute(sampleId: string, date: Date) { + const htmlContent = await this.getHtmlContent(sampleId, date) + + const { mergedPdf } = await this.browserService.printMultiplePage( + of({ + htmlContent, + pageFormat: PageFormat.A5, + pageOrientation: PageOrientation.Landscape, + }), + ) + + return mergedPdf + } + + private async getHtmlContent(sampleId: string, date: Date) { + const { jwt, sample, meta } = await this.getPrintData(sampleId) + const printTemplate = await this.getPrintTemplate() + const url = this.appConfig.REMINDER_URL_PREFIX + jwt + + return render( + printTemplate, + { data: { url, sample, date }, meta }, + { async: true }, + ) + } + + private async getPrintTemplate() { + const isDevelopment = this.appConfig.NODE_ENV === NodeEnv.Development + if (isDevelopment) { + const buffer = await readFile( + join( + __dirname, + '..', + '..', + `print-form/print-template/${TEMPLATE_PATH}`, + ), + ) + + return buffer.toString() + } + + const { buffer } = await this.storageService.readToBuffer({ + key: StorageKeyFactory[StorageBucket.APP].printFormTemplate({ + templatePath: TEMPLATE_PATH, + }), + bucket: this.storageBucket.get(StorageBucket.APP), + }) + return buffer.toString() + } + + private async getPrintData(sampleId: string) { + const { ability, user } = this.authContext.getDataInternal() + + const sample = await this.sampleFindOneUseCase.execute({ + filter: { sampleId }, + populates: [ + { + path: 'patient', + }, + { + path: 'branch', + }, + ], + }) + if (!sample) { + throw new EEntityNotFound(`Sample id=${sampleId}`) + } + + assertPermission( + ability, + AuthSubject.Sample, + SampleAction.ReadResult, + sample, + ) + + const { jwt } = await this.authorizeExternalRouteUseCase.execute( + this.constructor.name, + ExternalRoutePath.GetSampleResult, + { sampleId: sample._id }, + [sample.branchId], + ) + + return { + jwt, + sample, + meta: { branch: sample.branch, authorName: user.name }, + } + } +} diff --git a/apps/hcdc-access-service/src/config/app.ts b/apps/hcdc-access-service/src/config/app.ts index f2ea0ad7..24206ce7 100644 --- a/apps/hcdc-access-service/src/config/app.ts +++ b/apps/hcdc-access-service/src/config/app.ts @@ -13,6 +13,11 @@ export class AppConfig { @IsNotEmpty() SERVICE_NAME: string + @Expose() + @IsString() + @IsNotEmpty() + REMINDER_URL_PREFIX: string + @Expose() @IsString() @IsNotEmpty() diff --git a/apps/hcdc-access-service/src/controller/http/external/auth/common.ts b/apps/hcdc-access-service/src/controller/http/external/auth/common.ts new file mode 100644 index 00000000..b54adb47 --- /dev/null +++ b/apps/hcdc-access-service/src/controller/http/external/auth/common.ts @@ -0,0 +1,12 @@ +import { ApiQuery } from '@nestjs/swagger' + +export type ExternalAuthQuery = { + jwt: string +} + +export const AuthQuery = () => + ApiQuery({ + name: 'jwt', + required: true, + type: 'string', + }) diff --git a/apps/hcdc-access-service/src/controller/http/external/auth/guard.ts b/apps/hcdc-access-service/src/controller/http/external/auth/guard.ts index 3695c19d..ebbc6467 100644 --- a/apps/hcdc-access-service/src/controller/http/external/auth/guard.ts +++ b/apps/hcdc-access-service/src/controller/http/external/auth/guard.ts @@ -13,6 +13,7 @@ import { IAuthCacheService, IAuthContext, } from 'src/domain' +import { ExternalAuthQuery } from './common' export class HttpExternalAuthGuard implements CanActivate { private readonly logger = new Logger(this.constructor.name) @@ -30,7 +31,7 @@ export class HttpExternalAuthGuard implements CanActivate { async canActivate(context: ExecutionContext) { const request = context.switchToHttp().getRequest() - const jwt = request.query.jwt as string + const jwt = (request.query as ExternalAuthQuery).jwt if (!jwt) return false const payload = await this.verifyToken(jwt) diff --git a/apps/hcdc-access-service/src/controller/http/external/auth/index.ts b/apps/hcdc-access-service/src/controller/http/external/auth/index.ts index 668a60af..0e6ef646 100644 --- a/apps/hcdc-access-service/src/controller/http/external/auth/index.ts +++ b/apps/hcdc-access-service/src/controller/http/external/auth/index.ts @@ -1,2 +1,3 @@ -export * from './service' +export * from './common' export * from './guard' +export * from './service' diff --git a/apps/hcdc-access-service/src/controller/http/external/controller.ts b/apps/hcdc-access-service/src/controller/http/external/controller.ts index a3993f94..a762e022 100644 --- a/apps/hcdc-access-service/src/controller/http/external/controller.ts +++ b/apps/hcdc-access-service/src/controller/http/external/controller.ts @@ -1,4 +1,5 @@ -import { ExternalRoutePath } from '@diut/hcdc' +import { AuthSubject, ExternalRoutePath, SampleAction } from '@diut/hcdc' +import { Serialize } from '@diut/nestjs-infra' import { Controller, Get, @@ -7,23 +8,35 @@ import { StreamableFile, UseGuards, } from '@nestjs/common' -import { ApiTags } from '@nestjs/swagger' +import { ApiResponse, ApiTags } from '@nestjs/swagger' import { Response } from 'express' +import { assertPermission } from 'src/app/auth/common' +import { PrintFormSearchUseCase } from 'src/app/print-form/use-case/search' +import { SampleFindOneUseCase } from 'src/app/sample/use-case/find-one' import { SamplePrintUseCase } from 'src/app/sample/use-case/print' -import { AUTH_CONTEXT_TOKEN, IAuthContext } from 'src/domain' -import { HttpExternalAuthGuard } from './auth' +import { + AUTH_CONTEXT_TOKEN, + EAuthzPermissionDenied, + EEntityNotFound, + IAuthContext, +} from 'src/domain' +import { AuthQuery, HttpExternalAuthGuard } from './auth' +import { ExternalGetSampleResultResponseDto } from './dto/get-sample-result' @Controller() @ApiTags('external') @UseGuards(HttpExternalAuthGuard) export class ExternalController { constructor( - private readonly samplePrintUseCase: SamplePrintUseCase, @Inject(AUTH_CONTEXT_TOKEN) private readonly authContext: IAuthContext, + private readonly samplePrintUseCase: SamplePrintUseCase, + private readonly sampleFindOneUseCase: SampleFindOneUseCase, + private readonly printFormSearchUseCase: PrintFormSearchUseCase, ) {} @Get(ExternalRoutePath.PrintSampleResult) + @AuthQuery() async printSampleResult(@Res({ passthrough: true }) res: Response) { const { routeOptions: { printOptions }, @@ -40,4 +53,50 @@ export class ExternalController { return new StreamableFile(buffer) } + + @Get(ExternalRoutePath.GetSampleResult) + @ApiResponse({ + status: 200, + description: 'Get sample result', + type: ExternalGetSampleResultResponseDto, + }) + @Serialize(ExternalGetSampleResultResponseDto) + @AuthQuery() + async getSampleResult(@Res({ passthrough: true }) res: Response) { + const { + routeOptions: { sampleId }, + } = this.authContext.getDataExternal() + + const sample = await this.sampleFindOneUseCase.execute({ + filter: { _id: sampleId }, + populates: [ + { path: 'results.test' }, + { path: 'results.elements.testElement' }, + { path: 'patient' }, + ], + }) + + if (sample === null) { + throw new EEntityNotFound(`Sample id=${sampleId}`) + } + + if (sample.isLocked === true) { + throw new EAuthzPermissionDenied('Sample is locked') + } + + const { ability } = this.authContext.getDataExternal() + assertPermission( + ability, + AuthSubject.Sample, + SampleAction.ReadResult, + sample, + ) + + const { items: printForms } = await this.printFormSearchUseCase.execute({ + sort: { displayIndex: 1 }, + filter: { branchId: sample.branchId }, + }) + + return { sample, printForms } + } } diff --git a/apps/hcdc-access-service/src/controller/http/external/dto/get-sample-result.ts b/apps/hcdc-access-service/src/controller/http/external/dto/get-sample-result.ts new file mode 100644 index 00000000..ed5205ec --- /dev/null +++ b/apps/hcdc-access-service/src/controller/http/external/dto/get-sample-result.ts @@ -0,0 +1,47 @@ +import { ApiProperty, PickType } from '@nestjs/swagger' +import { Expose, Type } from 'class-transformer' +import { PatientUnpopulatedResponseDto } from '../../v1/patient/dto/response-dto' +import { PrintFormUnpopulatedResponseDto } from '../../v1/print-form/dto/response-dto' +import { SampleResponseDto } from '../../v1/sample/dto/response-dto' + +class PublicPatientResponseDto extends PickType(PatientUnpopulatedResponseDto, [ + '_id', + 'name', +]) {} + +class PublicSampleResponseDto extends PickType(SampleResponseDto, [ + '_id', + 'sampleId', + 'isPregnant', + 'branchId', + 'results', +]) { + @Expose() + @ApiProperty({ + type: () => PublicPatientResponseDto, + }) + @Type(() => PublicPatientResponseDto) + patient: PublicPatientResponseDto +} + +class PublicPrintFormResponseDto extends PickType( + PrintFormUnpopulatedResponseDto, + ['_id', 'template'], +) {} + +export class ExternalGetSampleResultResponseDto { + @Expose() + @ApiProperty({ + type: () => PublicSampleResponseDto, + }) + @Type(() => PublicSampleResponseDto) + sample: PublicSampleResponseDto + + @Expose() + @ApiProperty({ + isArray: true, + type: () => PublicPrintFormResponseDto, + }) + @Type(() => PublicPrintFormResponseDto) + printForms: PublicPrintFormResponseDto[] +} diff --git a/apps/hcdc-access-service/src/controller/http/v1/sample/controller.ts b/apps/hcdc-access-service/src/controller/http/v1/sample/controller.ts index 82cf97f8..d9fc80d9 100644 --- a/apps/hcdc-access-service/src/controller/http/v1/sample/controller.ts +++ b/apps/hcdc-access-service/src/controller/http/v1/sample/controller.ts @@ -24,6 +24,7 @@ import { SampleFindOneUseCase } from 'src/app/sample/use-case/find-one' import { SampleGeneratePrintUrlUseCase } from 'src/app/sample/use-case/generate-print-url' import { SampleLockUseCase } from 'src/app/sample/use-case/lock' import { SamplePrintUseCase } from 'src/app/sample/use-case/print' +import { SamplePrintReminderUseCase } from 'src/app/sample/use-case/print-reminder' import { SampleSearchUseCase } from 'src/app/sample/use-case/search' import { SampleUnlockUseCase } from 'src/app/sample/use-case/unlock' import { SampleUpdateInfoUseCase } from 'src/app/sample/use-case/update-info' @@ -58,6 +59,7 @@ export class SampleController { private readonly sampleGeneratePrintUrlUseCase: SampleGeneratePrintUrlUseCase, private readonly sampleLockUseCase: SampleLockUseCase, private readonly sampleUnlockUseCase: SampleUnlockUseCase, + private readonly samplePrintReminderUseCase: SamplePrintReminderUseCase, ) {} @HttpRoute(sampleRoutes.uploadResultImage) @@ -208,14 +210,32 @@ export class SampleController { } @HttpRoute(sampleRoutes.getPrintPath) - async getPrintPath( - @Res({ passthrough: true }) res: Response, - @Body() body: SamplePrintRequestDto, - ) { + async getPrintPath(@Body() body: SamplePrintRequestDto) { const path = await this.sampleGeneratePrintUrlUseCase.execute({ printOptions: body.requests, }) return { path } } + + @HttpRoute(sampleRoutes.printReminder) + async printReminder( + @Res({ passthrough: true }) res: Response, + @Param('id') sampleId: string, + @Query('timestamp') timestamp: Date, + ) { + const buffer = await this.samplePrintReminderUseCase.execute( + sampleId, + new Date(timestamp), + ) + + res.set({ + 'Content-Type': 'application/pdf', + 'Cache-Control': 'no-cache, no-store, must-revalidate', + Pragma: 'no-cache', + Expires: 0, + }) + + return new StreamableFile(buffer) + } } diff --git a/apps/hcdc-access-service/src/controller/http/v1/sample/routes.ts b/apps/hcdc-access-service/src/controller/http/v1/sample/routes.ts index 7e5723ff..23dffc44 100644 --- a/apps/hcdc-access-service/src/controller/http/v1/sample/routes.ts +++ b/apps/hcdc-access-service/src/controller/http/v1/sample/routes.ts @@ -1,5 +1,6 @@ import { CustomHttpRouteOptions } from '@diut/nestjs-infra' import { HttpStatus, RequestMethod } from '@nestjs/common' +import { ApiQuery } from '@nestjs/swagger' import { SampleCreateResponseDto } from './dto/create' import { SampleGetPrintPathResponseDto } from './dto/get-print-path' import { @@ -44,6 +45,14 @@ export const sampleRoutes = { method: RequestMethod.POST, }, + printReminder: { + path: ':id/print-reminder', + method: RequestMethod.GET, + routeDecorators: [ + ApiQuery({ name: 'timestamp', required: true, type: 'number' }), + ], + }, + lock: { path: ':id/lock', method: RequestMethod.POST, diff --git a/apps/hcdc-access-service/src/domain/interface/auth/external-route.ts b/apps/hcdc-access-service/src/domain/interface/auth/external-route.ts index c4c8ebbc..31aa5db2 100644 --- a/apps/hcdc-access-service/src/domain/interface/auth/external-route.ts +++ b/apps/hcdc-access-service/src/domain/interface/auth/external-route.ts @@ -5,4 +5,7 @@ export type ExternalRouteOptions = { [ExternalRoutePath.PrintSampleResult]: { printOptions: SamplePrintOptions[] } + [ExternalRoutePath.GetSampleResult]: { + sampleId: string + } } diff --git a/apps/hcdc-web-app/api-codegen/access-service.cts b/apps/hcdc-web-app/api-codegen/access-service.cts index 421a0816..80f4ba45 100644 --- a/apps/hcdc-web-app/api-codegen/access-service.cts +++ b/apps/hcdc-web-app/api-codegen/access-service.cts @@ -18,8 +18,9 @@ const ENDPOINTS = [ // 'test element', // 'patient', // 'test combo', - 'sample', + // 'sample', // 'report', + // 'external', ] const outputFiles = {} diff --git a/apps/hcdc-web-app/src/features/external/components/index.ts b/apps/hcdc-web-app/src/features/external/components/index.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/apps/hcdc-web-app/src/features/external/index.ts b/apps/hcdc-web-app/src/features/external/index.ts index 7ba346c1..8ad1cf73 100644 --- a/apps/hcdc-web-app/src/features/external/index.ts +++ b/apps/hcdc-web-app/src/features/external/index.ts @@ -1,2 +1,2 @@ // export * from './components' -// export * from './pages' +export * from './pages' diff --git a/apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/index.tsx b/apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/index.tsx new file mode 100644 index 00000000..e4551050 --- /dev/null +++ b/apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/index.tsx @@ -0,0 +1,22 @@ +export * from './loader' +import { useLoaderData } from 'react-router-dom' +import { ResultEditView } from 'src/features/sample-result' +import { resultExternalPageLoader } from './loader' + +export function urlResultExternalPage() { + return `/external/sample-result` +} + +export function ResultExternalPage() { + const { sampleRes, printFormMap } = useLoaderData() as Awaited< + ReturnType + > + + return ( + + ) +} diff --git a/apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/loader.ts b/apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/loader.ts new file mode 100644 index 00000000..088ebca0 --- /dev/null +++ b/apps/hcdc-web-app/src/features/external/pages/ResultExternalPage/loader.ts @@ -0,0 +1,30 @@ +import { LoaderFunctionArgs } from 'react-router-dom' +import { externalApi } from 'src/infra/api/access-service/external' +import { appStore } from 'src/infra/redux' + +export const resultExternalPageLoader = async ({ + request, +}: LoaderFunctionArgs) => { + const url = new URL(request.url) + const queryParams = new URLSearchParams(url.search) + const jwt = queryParams.get('jwt') + + if (jwt === null) { + throw new Error('Link thiếu JWT') + } + + try { + const data = await appStore + .dispatch(externalApi.endpoints.externalGetSampleResult.initiate(jwt)) + .unwrap() + + return { + sampleRes: data.sample, + printFormMap: new Map( + data.printForms.map((printForm) => [printForm._id, printForm]), + ), + } + } catch (error) { + throw new Error(`Lỗi khi lấy dữ liệu: ${JSON.stringify(error)}`) + } +} diff --git a/apps/hcdc-web-app/src/features/external/pages/index.ts b/apps/hcdc-web-app/src/features/external/pages/index.ts index e69de29b..3cae68d6 100644 --- a/apps/hcdc-web-app/src/features/external/pages/index.ts +++ b/apps/hcdc-web-app/src/features/external/pages/index.ts @@ -0,0 +1 @@ +export * from './ResultExternalPage' diff --git a/apps/hcdc-web-app/src/features/sample-info/components/BarcodeModal/index.tsx b/apps/hcdc-web-app/src/features/sample-info/components/BarcodeModal/index.tsx index 0ee3812a..26a48551 100644 --- a/apps/hcdc-web-app/src/features/sample-info/components/BarcodeModal/index.tsx +++ b/apps/hcdc-web-app/src/features/sample-info/components/BarcodeModal/index.tsx @@ -1,3 +1,4 @@ +import { LoadingButton } from '@mui/lab' import { Button, Dialog, @@ -5,11 +6,20 @@ import { DialogTitle, Slide, } from '@mui/material' -import { TransitionProps } from '@mui/material/transitions' import Grid from '@mui/material/Unstable_Grid2' +import { TransitionProps } from '@mui/material/transitions' +import { addDays, isWeekend, nextMonday } from 'date-fns' import { ReactElement, Ref, forwardRef } from 'react' +import { useForm } from 'react-hook-form' +import { FormContainer, FormDateTimePicker } from 'src/components/form' +import { useLazySamplePrintReminderQuery } from 'src/infra/api/access-service/sample' import { PrintBarcode, PrintBarcodeProps } from './components' +const expectedReminderDate = addDays(new Date(), 10) +const DEFAULT_REMINDER_DATE = isWeekend(expectedReminderDate) + ? nextMonday(expectedReminderDate) + : expectedReminderDate + const Transition = forwardRef(function Transition( props: TransitionProps & { children: ReactElement @@ -24,11 +34,30 @@ export interface BarcodeModalProps extends PrintBarcodeProps { onClose: Function } +interface FormData { + reminderDate: Date +} + export function BarcodeModal({ open, onClose, ...printProps }: BarcodeModalProps) { + const { control, handleSubmit } = useForm({ + defaultValues: { + reminderDate: DEFAULT_REMINDER_DATE, + }, + }) + + const [printReminder, { isFetching }] = useLazySamplePrintReminderQuery() + + const handlePrintReminder = async (data: FormData) => { + await printReminder({ + id: printProps.sampleId, + timestamp: data.reminderDate.getTime(), + }).unwrap() + } + return ( In CODE: {printProps.sampleId} - + - + - + - + +
+ + + + + + + + In + + + +
) diff --git a/apps/hcdc-web-app/src/features/sample-info/components/InfoEditView/index.tsx b/apps/hcdc-web-app/src/features/sample-info/components/InfoEditView/index.tsx index 2092aa59..0df1011d 100644 --- a/apps/hcdc-web-app/src/features/sample-info/components/InfoEditView/index.tsx +++ b/apps/hcdc-web-app/src/features/sample-info/components/InfoEditView/index.tsx @@ -1,10 +1,10 @@ import { dedupSpaces, trimObjectValues } from '@diut/common' import { AuthSubject, - checkPermission, - createAbility, PatientGender, SampleAction, + checkPermission, + createAbility, } from '@diut/hcdc' import { LoadingButton } from '@mui/lab' import { @@ -50,9 +50,9 @@ import { SampleTypeResponseDto } from 'src/infra/api/access-service/sample-type' import { useTypedSelector } from 'src/infra/redux' import { BarcodeModal } from '../BarcodeModal' import { - formResolver, FormSchema, GENDER_PREGNANT_VALUE, + formResolver, } from '../InfoInputForm/validation' const currentYear = new Date().getFullYear() diff --git a/apps/hcdc-web-app/src/features/sample-info/components/InfoInputForm/index.tsx b/apps/hcdc-web-app/src/features/sample-info/components/InfoInputForm/index.tsx index 16506f79..01163c2f 100644 --- a/apps/hcdc-web-app/src/features/sample-info/components/InfoInputForm/index.tsx +++ b/apps/hcdc-web-app/src/features/sample-info/components/InfoInputForm/index.tsx @@ -50,10 +50,10 @@ import { useTypedSelector } from 'src/infra/redux' import { useDebouncedValue } from 'src/shared/hooks' import { BarcodeModal } from '../BarcodeModal' import { - formDefaultValues, - formResolver, FormSchema, GENDER_PREGNANT_VALUE, + formDefaultValues, + formResolver, } from './validation' export type InputFormProps = { diff --git a/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/columns.tsx b/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/columns.tsx index 8985d80e..f18ed4af 100644 --- a/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/columns.tsx +++ b/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/columns.tsx @@ -71,7 +71,13 @@ export const useColumns = ( } label="In KQ" - color={row.printedById !== undefined ? 'default' : 'primary'} + color={ + row.isLocked === true + ? 'error' + : row.printedById !== undefined + ? 'default' + : 'primary' + } onClick={() => handlePrint(row)} disabled={ !checkPermission( diff --git a/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/components/PrintSingleDialog/index.tsx b/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/components/PrintSingleDialog/index.tsx index d3b7fdfa..7909e22a 100644 --- a/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/components/PrintSingleDialog/index.tsx +++ b/apps/hcdc-web-app/src/features/sample-result/components/PrintSelectView/components/PrintSingleDialog/index.tsx @@ -401,7 +401,6 @@ export function PrintSingleDialog(props: PrintSingleDialogProps) { > Đóng - - {isLocked ? ( - - ) : ( - - )} - {props.testResult.resultBy != null && ( - - {props.testResult.resultBy.name} - {' - '} - {format(new Date(props.testResult.resultAt!), DATETIME_FORMAT)} - - )} - + !props.isExternal && ( + + {isLocked ? ( + + ) : ( + + )} + {props.testResult.resultBy != null && ( + + {props.testResult.resultBy.name} + {' - '} + {format( + new Date(props.testResult.resultAt!), + DATETIME_FORMAT, + )} + + )} + + ) } /> } @@ -58,16 +59,18 @@ export function ResultEditView(props: ResultEditViewProps) { width: '280px', }} > - + {!props.isExternal && ( + + )} - {props.sampleRes.note.length > 0 && ( + {!props.isExternal && props.sampleRes.note.length > 0 && ( ( ({ query: () => ({ url: `/api/v1/auth/me` }), - providesTags: ['v1-auth'], + providesTags: ['auth'], }), authLogout: build.mutation({ query: () => ({ url: `/api/v1/auth/logout`, method: 'POST' }), - invalidatesTags: ['v1-auth'], + invalidatesTags: ['auth'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/bio-product.ts b/apps/hcdc-web-app/src/infra/api/access-service/bio-product.ts index d5f3a50d..da5b917c 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/bio-product.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/bio-product.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-bio-products'] as const +export const addTagTypes = ['bio-products'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-bio-products'], + providesTags: ['bio-products'], }), bioProductCreate: build.mutation< BioProductCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-bio-products'], + invalidatesTags: ['bio-products'], }), bioProductFindById: build.query< BioProductFindByIdApiResponse, BioProductFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/bio-products/${queryArg}` }), - providesTags: ['v1-bio-products'], + providesTags: ['bio-products'], }), bioProductUpdateById: build.mutation< BioProductUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.bioProductUpdateRequestDto, }), - invalidatesTags: ['v1-bio-products'], + invalidatesTags: ['bio-products'], }), bioProductDeleteById: build.mutation< BioProductDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/bio-products/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-bio-products'], + invalidatesTags: ['bio-products'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/branch.ts b/apps/hcdc-web-app/src/infra/api/access-service/branch.ts index 8563d340..72e96fc0 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/branch.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/branch.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-branches'] as const +export const addTagTypes = ['branches'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -12,7 +12,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-branches'], + providesTags: ['branches'], }), branchCreate: build.mutation( { @@ -21,7 +21,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-branches'], + invalidatesTags: ['branches'], }, ), branchFindById: build.query< @@ -29,7 +29,7 @@ const injectedRtkApi = api BranchFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/branches/${queryArg}` }), - providesTags: ['v1-branches'], + providesTags: ['branches'], }), branchUpdateById: build.mutation< BranchUpdateByIdApiResponse, @@ -40,7 +40,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.branchUpdateRequestDto, }), - invalidatesTags: ['v1-branches'], + invalidatesTags: ['branches'], }), branchDeleteById: build.mutation< BranchDeleteByIdApiResponse, @@ -50,7 +50,7 @@ const injectedRtkApi = api url: `/api/v1/branches/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-branches'], + invalidatesTags: ['branches'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/diagnosis.ts b/apps/hcdc-web-app/src/infra/api/access-service/diagnosis.ts index 0264a5df..1ff98267 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/diagnosis.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/diagnosis.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-diagnoses'] as const +export const addTagTypes = ['diagnoses'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-diagnoses'], + providesTags: ['diagnoses'], }), diagnosisCreate: build.mutation< DiagnosisCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-diagnoses'], + invalidatesTags: ['diagnoses'], }), diagnosisFindById: build.query< DiagnosisFindByIdApiResponse, DiagnosisFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/diagnoses/${queryArg}` }), - providesTags: ['v1-diagnoses'], + providesTags: ['diagnoses'], }), diagnosisUpdateById: build.mutation< DiagnosisUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.diagnosisUpdateRequestDto, }), - invalidatesTags: ['v1-diagnoses'], + invalidatesTags: ['diagnoses'], }), diagnosisDeleteById: build.mutation< DiagnosisDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/diagnoses/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-diagnoses'], + invalidatesTags: ['diagnoses'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/doctor.ts b/apps/hcdc-web-app/src/infra/api/access-service/doctor.ts index ef74ac6d..0ec9dfa3 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/doctor.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/doctor.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-doctors'] as const +export const addTagTypes = ['doctors'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -12,7 +12,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-doctors'], + providesTags: ['doctors'], }), doctorCreate: build.mutation( { @@ -21,7 +21,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-doctors'], + invalidatesTags: ['doctors'], }, ), doctorFindById: build.query< @@ -29,7 +29,7 @@ const injectedRtkApi = api DoctorFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/doctors/${queryArg}` }), - providesTags: ['v1-doctors'], + providesTags: ['doctors'], }), doctorUpdateById: build.mutation< DoctorUpdateByIdApiResponse, @@ -40,7 +40,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.doctorUpdateRequestDto, }), - invalidatesTags: ['v1-doctors'], + invalidatesTags: ['doctors'], }), doctorDeleteById: build.mutation< DoctorDeleteByIdApiResponse, @@ -50,7 +50,7 @@ const injectedRtkApi = api url: `/api/v1/doctors/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-doctors'], + invalidatesTags: ['doctors'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/external.ts b/apps/hcdc-web-app/src/infra/api/access-service/external.ts new file mode 100644 index 00000000..51ec6ae3 --- /dev/null +++ b/apps/hcdc-web-app/src/infra/api/access-service/external.ts @@ -0,0 +1,176 @@ +import { accessServiceApiSlice as api } from './slice' +export const addTagTypes = ['external'] as const +const injectedRtkApi = api + .enhanceEndpoints({ + addTagTypes, + }) + .injectEndpoints({ + endpoints: (build) => ({ + externalPrintSampleResult: build.query< + ExternalPrintSampleResultApiResponse, + ExternalPrintSampleResultApiArg + >({ + query: (queryArg) => ({ + url: `/api/external/print-sample-result`, + params: { jwt: queryArg }, + }), + providesTags: ['external'], + }), + externalGetSampleResult: build.query< + ExternalGetSampleResultApiResponse, + ExternalGetSampleResultApiArg + >({ + query: (queryArg) => ({ + url: `/api/external/get-sample-result`, + params: { jwt: queryArg }, + }), + providesTags: ['external'], + }), + }), + overrideExisting: false, + }) +export { injectedRtkApi as externalApi } +export type ExternalPrintSampleResultApiResponse = unknown +export type ExternalPrintSampleResultApiArg = string +export type ExternalGetSampleResultApiResponse = + /** status 200 Get sample result */ ExternalGetSampleResultResponseDto +export type ExternalGetSampleResultApiArg = string +export type TestElementNormalRuleDto = { + category: + | 'Any' + | 'YoungMale' + | 'YoungFemale' + | 'MatureMale' + | 'MatureFemale' + | 'Pregnant' + defaultChecked?: boolean + normalValue?: string + normalLowerBound?: number + normalUpperBound?: number + description: string + note: string +} +export type TestElementUnpopulatedResponseDto = { + _id: string + displayIndex: number + name: string + printIndex: number + reportIndex: number + unit: string + isParent: boolean + normalRules: TestElementNormalRuleDto[] + testId: string + branchId: string +} +export type SampleResultTestElementResponseDto = { + testElementId: string + value: string + isAbnormal: boolean + testElement?: TestElementUnpopulatedResponseDto | null +} +export type TestUnpopulatedResponseDto = { + _id: string + displayIndex: number + name: string + shouldDisplayWithChildren: boolean + bioProductId: string | null + instrumentId: string | null + sampleTypeId: string | null + testCategoryId: string + printFormIds: string[] + branchId: string +} +export type PermissionRuleDto = { + subject: + | 'Branch' + | 'Role' + | 'User' + | 'PrintForm' + | 'BioProduct' + | 'Instrument' + | 'SampleType' + | 'Doctor' + | 'PatientType' + | 'Diagnosis' + | 'TestCategory' + | 'TestElement' + | 'Test' + | 'TestCombo' + | 'Patient' + | 'Sample' + | 'SampleTestResult' + | 'Report' + | 'ExternalRoute' + | 'all' + action: + | 'Create' + | 'Read' + | 'Update' + | 'Delete' + | 'AuthorizeUser' + | 'DeauthorizeUser' + | 'AssignToUser' + | 'AssignUserInline' + | 'ChangePassword' + | 'OverrideAuthor' + | 'Modify' + | 'ReadInfo' + | 'ReadResult' + | 'UpdateInfo' + | 'UpdateResult' + | 'PrintResult' + | 'Lock' + | 'View' + | 'Export' + | 'Generate' + | 'manage' + inverted?: boolean + conditions: object + fields?: any[] +} +export type UserUnpopulatedResponseDto = { + _id: string + username: string + name: string + phoneNumber: string + inlinePermissions: PermissionRuleDto[] + branchIds: string[] + roleIds: string[] +} +export type SampleResultTestResponseDto = { + testId: string + isLocked: boolean + elements: SampleResultTestElementResponseDto[] + test?: TestUnpopulatedResponseDto | null + resultById?: string + resultBy?: UserUnpopulatedResponseDto | null + resultAt?: string + bioProductName?: string + instrumentName?: string +} +export type PublicPatientResponseDto = { + _id: string + name: string +} +export type PublicSampleResponseDto = { + _id: string + sampleId: string + isPregnant: boolean + branchId: string + results: SampleResultTestResponseDto[] + patient: PublicPatientResponseDto +} +export type PublicPrintFormResponseDto = { + _id: string + template: 'FormChung' | 'FormHIV' | 'FormPap' | 'FormSoiNhuom' | 'FormTD' +} +export type ExternalGetSampleResultResponseDto = { + sample: PublicSampleResponseDto + printForms: PublicPrintFormResponseDto[] +} +export const { + useExternalPrintSampleResultQuery, + useLazyExternalPrintSampleResultQuery, + useExternalGetSampleResultQuery, + useLazyExternalGetSampleResultQuery, +} = injectedRtkApi diff --git a/apps/hcdc-web-app/src/infra/api/access-service/instrument.ts b/apps/hcdc-web-app/src/infra/api/access-service/instrument.ts index 14abea57..d84a81d6 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/instrument.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/instrument.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-instruments'] as const +export const addTagTypes = ['instruments'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-instruments'], + providesTags: ['instruments'], }), instrumentCreate: build.mutation< InstrumentCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-instruments'], + invalidatesTags: ['instruments'], }), instrumentFindById: build.query< InstrumentFindByIdApiResponse, InstrumentFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/instruments/${queryArg}` }), - providesTags: ['v1-instruments'], + providesTags: ['instruments'], }), instrumentUpdateById: build.mutation< InstrumentUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.instrumentUpdateRequestDto, }), - invalidatesTags: ['v1-instruments'], + invalidatesTags: ['instruments'], }), instrumentDeleteById: build.mutation< InstrumentDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/instruments/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-instruments'], + invalidatesTags: ['instruments'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/patient-type.ts b/apps/hcdc-web-app/src/infra/api/access-service/patient-type.ts index 386c430d..f9703ecc 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/patient-type.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/patient-type.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-patient-types'] as const +export const addTagTypes = ['patient-types'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-patient-types'], + providesTags: ['patient-types'], }), patientTypeCreate: build.mutation< PatientTypeCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-patient-types'], + invalidatesTags: ['patient-types'], }), patientTypeFindById: build.query< PatientTypeFindByIdApiResponse, PatientTypeFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/patient-types/${queryArg}` }), - providesTags: ['v1-patient-types'], + providesTags: ['patient-types'], }), patientTypeUpdateById: build.mutation< PatientTypeUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.patientTypeUpdateRequestDto, }), - invalidatesTags: ['v1-patient-types'], + invalidatesTags: ['patient-types'], }), patientTypeDeleteById: build.mutation< PatientTypeDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/patient-types/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-patient-types'], + invalidatesTags: ['patient-types'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/patient.ts b/apps/hcdc-web-app/src/infra/api/access-service/patient.ts index 91083d62..f0732b4c 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/patient.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/patient.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-patients'] as const +export const addTagTypes = ['patients'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -13,7 +13,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-patients'], + providesTags: ['patients'], }, ), patientCreate: build.mutation< @@ -25,14 +25,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-patients'], + invalidatesTags: ['patients'], }), patientFindById: build.query< PatientFindByIdApiResponse, PatientFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/patients/${queryArg}` }), - providesTags: ['v1-patients'], + providesTags: ['patients'], }), patientUpdateById: build.mutation< PatientUpdateByIdApiResponse, @@ -43,7 +43,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.patientUpdateRequestDto, }), - invalidatesTags: ['v1-patients'], + invalidatesTags: ['patients'], }), patientDeleteById: build.mutation< PatientDeleteByIdApiResponse, @@ -53,7 +53,7 @@ const injectedRtkApi = api url: `/api/v1/patients/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-patients'], + invalidatesTags: ['patients'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/print-form.ts b/apps/hcdc-web-app/src/infra/api/access-service/print-form.ts index cb6d7a44..7abce90d 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/print-form.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/print-form.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-print-forms'] as const +export const addTagTypes = ['print-forms'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-print-forms'], + providesTags: ['print-forms'], }), printFormCreate: build.mutation< PrintFormCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-print-forms'], + invalidatesTags: ['print-forms'], }), printFormFindById: build.query< PrintFormFindByIdApiResponse, PrintFormFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/print-forms/${queryArg}` }), - providesTags: ['v1-print-forms'], + providesTags: ['print-forms'], }), printFormUpdateById: build.mutation< PrintFormUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.printFormUpdateRequestDto, }), - invalidatesTags: ['v1-print-forms'], + invalidatesTags: ['print-forms'], }), printFormDeleteById: build.mutation< PrintFormDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/print-forms/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-print-forms'], + invalidatesTags: ['print-forms'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/report.ts b/apps/hcdc-web-app/src/infra/api/access-service/report.ts index 16a05f75..cfcc617f 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/report.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/report.ts @@ -1,6 +1,6 @@ import { fileReponseHandler } from '../utils' import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-reports'] as const +export const addTagTypes = ['reports'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -16,7 +16,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-reports'], + providesTags: ['reports'], }), reportExportSoNhanMau: build.mutation< ReportExportSoNhanMauApiResponse, @@ -28,7 +28,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportSinhHoa: build.mutation< ReportExportSinhHoaApiResponse, @@ -40,7 +40,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportSoiNhuom: build.mutation< ReportExportSoiNhuomApiResponse, @@ -52,7 +52,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportTdd: build.mutation< ReportExportTddApiResponse, @@ -64,7 +64,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportUrine: build.mutation< ReportExportUrineApiResponse, @@ -76,7 +76,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportHcg: build.mutation< ReportExportHcgApiResponse, @@ -88,7 +88,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportPap: build.mutation< ReportExportPapApiResponse, @@ -100,7 +100,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportThinprep: build.mutation< ReportExportThinprepApiResponse, @@ -112,7 +112,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportHiv: build.mutation< ReportExportHivApiResponse, @@ -124,7 +124,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportCtm: build.mutation< ReportExportCtmApiResponse, @@ -136,7 +136,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportTraKq: build.mutation< ReportExportTraKqApiResponse, @@ -148,7 +148,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), reportExportGiaoNhan: build.mutation< ReportExportGiaoNhanApiResponse, @@ -160,7 +160,7 @@ const injectedRtkApi = api body: queryArg, responseHandler: fileReponseHandler({ mode: 'download' }), }), - invalidatesTags: ['v1-reports'], + invalidatesTags: ['reports'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/role.ts b/apps/hcdc-web-app/src/infra/api/access-service/role.ts index a2196735..9f0ae7f4 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/role.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/role.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-roles'] as const +export const addTagTypes = ['roles'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -12,7 +12,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-roles'], + providesTags: ['roles'], }), roleCreate: build.mutation({ query: (queryArg) => ({ @@ -20,11 +20,11 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-roles'], + invalidatesTags: ['roles'], }), roleFindById: build.query({ query: (queryArg) => ({ url: `/api/v1/roles/${queryArg}` }), - providesTags: ['v1-roles'], + providesTags: ['roles'], }), roleUpdateById: build.mutation< RoleUpdateByIdApiResponse, @@ -35,7 +35,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.roleUpdateRequestDto, }), - invalidatesTags: ['v1-roles'], + invalidatesTags: ['roles'], }), roleDeleteById: build.mutation< RoleDeleteByIdApiResponse, @@ -45,7 +45,7 @@ const injectedRtkApi = api url: `/api/v1/roles/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-roles'], + invalidatesTags: ['roles'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/sample-type.ts b/apps/hcdc-web-app/src/infra/api/access-service/sample-type.ts index 5df2f2c0..5a43684d 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/sample-type.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/sample-type.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-sample-types'] as const +export const addTagTypes = ['sample-types'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-sample-types'], + providesTags: ['sample-types'], }), sampleTypeCreate: build.mutation< SampleTypeCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-sample-types'], + invalidatesTags: ['sample-types'], }), sampleTypeFindById: build.query< SampleTypeFindByIdApiResponse, SampleTypeFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/sample-types/${queryArg}` }), - providesTags: ['v1-sample-types'], + providesTags: ['sample-types'], }), sampleTypeUpdateById: build.mutation< SampleTypeUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.sampleTypeUpdateRequestDto, }), - invalidatesTags: ['v1-sample-types'], + invalidatesTags: ['sample-types'], }), sampleTypeDeleteById: build.mutation< SampleTypeDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/sample-types/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-sample-types'], + invalidatesTags: ['sample-types'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/sample.ts b/apps/hcdc-web-app/src/infra/api/access-service/sample.ts index 9d95aec5..b171bb06 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/sample.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/sample.ts @@ -136,6 +136,17 @@ const injectedRtkApi = api }), providesTags: ['samples'], }), + samplePrintReminder: build.query< + SamplePrintReminderApiResponse, + SamplePrintReminderApiArg + >({ + query: (queryArg) => ({ + url: `/api/v1/samples/${queryArg.id}/print-reminder`, + params: { timestamp: queryArg.timestamp }, + responseHandler: fileReponseHandler({ mode: 'preview' }), + }), + providesTags: ['samples'], + }), }), overrideExisting: false, }) @@ -184,6 +195,11 @@ export type SamplePrintApiArg = SamplePrintRequestDto export type SampleGetPrintPathApiResponse = /** status 200 */ SampleGetPrintPathResponseDto export type SampleGetPrintPathApiArg = SamplePrintRequestDto +export type SamplePrintReminderApiResponse = unknown +export type SamplePrintReminderApiArg = { + id: string + timestamp: number +} export type SampleUploadImageResponseDto = { storageKey: string } @@ -630,4 +646,6 @@ export const { useSamplePrintMutation, useSampleGetPrintPathQuery, useLazySampleGetPrintPathQuery, + useSamplePrintReminderQuery, + useLazySamplePrintReminderQuery, } = injectedRtkApi diff --git a/apps/hcdc-web-app/src/infra/api/access-service/test-category.ts b/apps/hcdc-web-app/src/infra/api/access-service/test-category.ts index 32fa6cf7..aa474f3b 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/test-category.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/test-category.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-test-categories'] as const +export const addTagTypes = ['test-categories'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-test-categories'], + providesTags: ['test-categories'], }), testCategoryCreate: build.mutation< TestCategoryCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-test-categories'], + invalidatesTags: ['test-categories'], }), testCategoryFindById: build.query< TestCategoryFindByIdApiResponse, TestCategoryFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/test-categories/${queryArg}` }), - providesTags: ['v1-test-categories'], + providesTags: ['test-categories'], }), testCategoryUpdateById: build.mutation< TestCategoryUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.testCategoryUpdateRequestDto, }), - invalidatesTags: ['v1-test-categories'], + invalidatesTags: ['test-categories'], }), testCategoryDeleteById: build.mutation< TestCategoryDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/test-categories/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-test-categories'], + invalidatesTags: ['test-categories'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/test-combo.ts b/apps/hcdc-web-app/src/infra/api/access-service/test-combo.ts index 0c33d269..b9d7c7ac 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/test-combo.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/test-combo.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-test-combos'] as const +export const addTagTypes = ['test-combos'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-test-combos'], + providesTags: ['test-combos'], }), testComboCreate: build.mutation< TestComboCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-test-combos'], + invalidatesTags: ['test-combos'], }), testComboFindById: build.query< TestComboFindByIdApiResponse, TestComboFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/test-combos/${queryArg}` }), - providesTags: ['v1-test-combos'], + providesTags: ['test-combos'], }), testComboUpdateById: build.mutation< TestComboUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.testComboUpdateRequestDto, }), - invalidatesTags: ['v1-test-combos'], + invalidatesTags: ['test-combos'], }), testComboDeleteById: build.mutation< TestComboDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/test-combos/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-test-combos'], + invalidatesTags: ['test-combos'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/test-element.ts b/apps/hcdc-web-app/src/infra/api/access-service/test-element.ts index 7543ae6d..29d8037c 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/test-element.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/test-element.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-test-elements'] as const +export const addTagTypes = ['test-elements'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -15,7 +15,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-test-elements'], + providesTags: ['test-elements'], }), testElementCreate: build.mutation< TestElementCreateApiResponse, @@ -26,14 +26,14 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-test-elements'], + invalidatesTags: ['test-elements'], }), testElementFindById: build.query< TestElementFindByIdApiResponse, TestElementFindByIdApiArg >({ query: (queryArg) => ({ url: `/api/v1/test-elements/${queryArg}` }), - providesTags: ['v1-test-elements'], + providesTags: ['test-elements'], }), testElementUpdateById: build.mutation< TestElementUpdateByIdApiResponse, @@ -44,7 +44,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.testElementUpdateRequestDto, }), - invalidatesTags: ['v1-test-elements'], + invalidatesTags: ['test-elements'], }), testElementDeleteById: build.mutation< TestElementDeleteByIdApiResponse, @@ -54,7 +54,7 @@ const injectedRtkApi = api url: `/api/v1/test-elements/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-test-elements'], + invalidatesTags: ['test-elements'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/test.ts b/apps/hcdc-web-app/src/infra/api/access-service/test.ts index f60de5a4..b7d6ed4d 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/test.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/test.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-tests'] as const +export const addTagTypes = ['tests'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -12,7 +12,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-tests'], + providesTags: ['tests'], }), testCreate: build.mutation({ query: (queryArg) => ({ @@ -20,11 +20,11 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-tests'], + invalidatesTags: ['tests'], }), testFindById: build.query({ query: (queryArg) => ({ url: `/api/v1/tests/${queryArg}` }), - providesTags: ['v1-tests'], + providesTags: ['tests'], }), testUpdateById: build.mutation< TestUpdateByIdApiResponse, @@ -35,7 +35,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.testUpdateRequestDto, }), - invalidatesTags: ['v1-tests'], + invalidatesTags: ['tests'], }), testDeleteById: build.mutation< TestDeleteByIdApiResponse, @@ -45,7 +45,7 @@ const injectedRtkApi = api url: `/api/v1/tests/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-tests'], + invalidatesTags: ['tests'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/api/access-service/user.ts b/apps/hcdc-web-app/src/infra/api/access-service/user.ts index 1a0a9933..50953203 100644 --- a/apps/hcdc-web-app/src/infra/api/access-service/user.ts +++ b/apps/hcdc-web-app/src/infra/api/access-service/user.ts @@ -1,5 +1,5 @@ import { accessServiceApiSlice as api } from './slice' -export const addTagTypes = ['v1-users'] as const +export const addTagTypes = ['users'] as const const injectedRtkApi = api .enhanceEndpoints({ addTagTypes, @@ -12,7 +12,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - providesTags: ['v1-users'], + providesTags: ['users'], }), userCreate: build.mutation({ query: (queryArg) => ({ @@ -20,11 +20,11 @@ const injectedRtkApi = api method: 'POST', body: queryArg, }), - invalidatesTags: ['v1-users'], + invalidatesTags: ['users'], }), userFindById: build.query({ query: (queryArg) => ({ url: `/api/v1/users/${queryArg}` }), - providesTags: ['v1-users'], + providesTags: ['users'], }), userUpdateById: build.mutation< UserUpdateByIdApiResponse, @@ -35,7 +35,7 @@ const injectedRtkApi = api method: 'PATCH', body: queryArg.userUpdateRequestDto, }), - invalidatesTags: ['v1-users'], + invalidatesTags: ['users'], }), userDeleteById: build.mutation< UserDeleteByIdApiResponse, @@ -45,7 +45,7 @@ const injectedRtkApi = api url: `/api/v1/users/${queryArg}`, method: 'DELETE', }), - invalidatesTags: ['v1-users'], + invalidatesTags: ['users'], }), userChangePassword: build.mutation< UserChangePasswordApiResponse, @@ -56,7 +56,7 @@ const injectedRtkApi = api method: 'POST', body: queryArg.userChangePasswordRequestDto, }), - invalidatesTags: ['v1-users'], + invalidatesTags: ['users'], }), userBranchAuthorize: build.mutation< UserBranchAuthorizeApiResponse, @@ -66,7 +66,7 @@ const injectedRtkApi = api url: `/api/v1/users/${queryArg.userId}/branch-authorize/${queryArg.branchId}`, method: 'POST', }), - invalidatesTags: ['v1-users'], + invalidatesTags: ['users'], }), userBranchDeauthorize: build.mutation< UserBranchDeauthorizeApiResponse, @@ -76,7 +76,7 @@ const injectedRtkApi = api url: `/api/v1/users/${queryArg.userId}/branch-deauthorize/${queryArg.branchId}`, method: 'POST', }), - invalidatesTags: ['v1-users'], + invalidatesTags: ['users'], }), }), overrideExisting: false, diff --git a/apps/hcdc-web-app/src/infra/router/routes.tsx b/apps/hcdc-web-app/src/infra/router/routes.tsx index a292ef40..c47754c4 100644 --- a/apps/hcdc-web-app/src/infra/router/routes.tsx +++ b/apps/hcdc-web-app/src/infra/router/routes.tsx @@ -5,6 +5,11 @@ import { urlManageDiagnosisPage, } from 'src/features/diagnosis' import { ManageDoctorPage, urlManageDoctorPage } from 'src/features/doctor' +import { + ResultExternalPage, + resultExternalPageLoader, + urlResultExternalPage, +} from 'src/features/external' import { HomePage } from 'src/features/homepage' import { PatientSearchPage, urlPatientSearchPage } from 'src/features/patient' import { @@ -79,6 +84,11 @@ export const appRoutes: CustomRouteObject[] = [ path: urlLoginPage(), element: , }, + { + path: urlResultExternalPage(), + element: , + loader: resultExternalPageLoader, + }, { path: '/', element: , diff --git a/libs/hcdc/src/entity/external-route/entity.ts b/libs/hcdc/src/entity/external-route/entity.ts index 0a0089b8..42253ff5 100644 --- a/libs/hcdc/src/entity/external-route/entity.ts +++ b/libs/hcdc/src/entity/external-route/entity.ts @@ -2,6 +2,7 @@ import { AssertAllKeysInArray } from '@diut/common' export enum ExternalRoutePath { PrintSampleResult = 'print-sample-result', + GetSampleResult = 'get-sample-result', } export type ExternalRoute = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f519314d..e3ff22e7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,7 +44,7 @@ importers: version: 10.3.10(@nestjs/common@10.3.10)(@nestjs/microservices@10.3.10)(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/microservices': specifier: ^10.3.3 - version: 10.3.10(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(ioredis@5.4.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + version: 10.3.10(@grpc/grpc-js@1.10.11)(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/terminus': specifier: ^10.2.3 version: 10.2.3(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(@nestjs/microservices@10.3.10)(@nestjs/mongoose@10.0.10)(mongoose@8.5.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) @@ -177,7 +177,7 @@ importers: version: 10.2.0(@nestjs/common@10.3.10) '@nestjs/microservices': specifier: ^10.3.3 - version: 10.3.10(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(ioredis@5.4.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + version: 10.3.10(@grpc/grpc-js@1.10.11)(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/mongoose': specifier: ^10.0.4 version: 10.0.10(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(mongoose@8.5.1)(rxjs@7.8.1) @@ -2584,7 +2584,7 @@ packages: optional: true dependencies: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/microservices': 10.3.10(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(ioredis@5.4.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/microservices': 10.3.10(@grpc/grpc-js@1.10.11)(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/platform-express': 10.3.10(@nestjs/common@10.3.10)(@nestjs/core@10.3.10) '@nuxtjs/opencollective': 0.3.2 fast-safe-stringify: 2.1.1 @@ -2842,7 +2842,7 @@ packages: dependencies: '@nestjs/common': 10.3.10(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/core': 10.3.10(@nestjs/common@10.3.10)(@nestjs/microservices@10.3.10)(@nestjs/platform-express@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) - '@nestjs/microservices': 10.3.10(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(ioredis@5.4.1)(reflect-metadata@0.1.14)(rxjs@7.8.1) + '@nestjs/microservices': 10.3.10(@grpc/grpc-js@1.10.11)(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(reflect-metadata@0.1.14)(rxjs@7.8.1) '@nestjs/mongoose': 10.0.10(@nestjs/common@10.3.10)(@nestjs/core@10.3.10)(mongoose@8.5.1)(rxjs@7.8.1) boxen: 5.1.2 check-disk-space: 3.4.0