Skip to content

Commit

Permalink
Add appointment-finder-element
Browse files Browse the repository at this point in the history
  • Loading branch information
bischofmax committed Sep 25, 2024
1 parent 5d0f6d5 commit 862e798
Show file tree
Hide file tree
Showing 19 changed files with 186 additions and 14 deletions.
5 changes: 4 additions & 1 deletion apps/server/src/modules/board/controller/card.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { ApiValidationError } from '@shared/common';
import { CardUc, ColumnUc } from '../uc';
import {
AnyContentElementResponse,
AppointmentFinderElementResponse,
CardIdsParams,
CardListResponse,
CardUrlParams,
Expand Down Expand Up @@ -124,7 +125,8 @@ export class CardController {
RichTextElementResponse,
SubmissionContainerElementResponse,
DrawingElementResponse,
DeletedElementResponse
DeletedElementResponse,
AppointmentFinderElementResponse
)
@ApiResponse({
status: 201,
Expand All @@ -137,6 +139,7 @@ export class CardController {
{ $ref: getSchemaPath(SubmissionContainerElementResponse) },
{ $ref: getSchemaPath(DrawingElementResponse) },
{ $ref: getSchemaPath(DeletedElementResponse) },
{ $ref: getSchemaPath(AppointmentFinderElementResponse) },
],
},
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AppointmentFinderElementResponse } from './appointment-finder-element.response';
import { CollaborativeTextEditorElementResponse } from './collaborative-text-editor-element.response';
import { DeletedElementResponse } from './deleted-element.response';
import { DrawingElementResponse } from './drawing-element.response';
Expand All @@ -15,7 +16,8 @@ export type AnyContentElementResponse =
| ExternalToolElementResponse
| DrawingElementResponse
| CollaborativeTextEditorElementResponse
| DeletedElementResponse;
| DeletedElementResponse
| AppointmentFinderElementResponse;

export const isFileElementResponse = (element: AnyContentElementResponse): element is FileElementResponse =>
element instanceof FileElementResponse;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { DecodeHtmlEntities } from '@shared/controller';
import { ContentElementType } from '../../../domain';
import { TimestampsResponse } from '../timestamps.response';

export class AppointmentFinderElementContent {
constructor({ appointmentFinderId, adminId }: AppointmentFinderElementContent) {
this.appointmentFinderId = appointmentFinderId;
this.adminId = adminId;
}

@ApiPropertyOptional()
@DecodeHtmlEntities()
appointmentFinderId?: string;

@ApiPropertyOptional()
@DecodeHtmlEntities()
adminId?: string;
}

export class AppointmentFinderElementResponse {
constructor(props: AppointmentFinderElementResponse) {
this.id = props.id;
this.type = props.type;
this.timestamps = props.timestamps;
this.content = props.content;
}

@ApiProperty({ pattern: '[a-f0-9]{24}' })
id: string;

@ApiProperty({ enum: ContentElementType, enumName: 'ContentElementType' })
type: ContentElementType.APPOINTMENT_FINDER;

@ApiProperty()
timestamps: TimestampsResponse;

@ApiProperty()
content: AppointmentFinderElementContent;
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
export * from './any-content-element.response';
export * from './appointment-finder-element.response';
export * from './collaborative-text-editor-element.response';
export * from './create-content-element.body.params';
export * from './deleted-element.response';
export * from './drawing-element.response';
export * from './external-tool-element.response';
export * from './file-element.response';
export * from './link-element.response';
export * from './rich-text-element.response';
export * from './submission-container-element.response';
export * from './update-element-content.body.params';
export * from './deleted-element.response';
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,33 @@ export class ExternalToolElementContentBody extends ElementContentBody {
content!: ExternalToolContentBody;
}

export class AppointmentFinderContentBody {
@IsString()
@ApiProperty()
appointmentFinderId!: string;

@IsString()
@ApiProperty()
adminId!: string;
}

export class AppointmentFinderElementContentBody extends ElementContentBody {
@ApiProperty({ type: ContentElementType.APPOINTMENT_FINDER })
type!: ContentElementType.APPOINTMENT_FINDER;

@ValidateNested()
@ApiProperty()
content!: AppointmentFinderContentBody;
}

export type AnyElementContentBody =
| FileContentBody
| DrawingContentBody
| LinkContentBody
| RichTextContentBody
| SubmissionContainerContentBody
| ExternalToolContentBody;
| ExternalToolContentBody
| AppointmentFinderContentBody;

export class UpdateElementContentBodyParams {
@ValidateNested()
Expand All @@ -151,6 +171,7 @@ export class UpdateElementContentBodyParams {
{ value: SubmissionContainerElementContentBody, name: ContentElementType.SUBMISSION_CONTAINER },
{ value: ExternalToolElementContentBody, name: ContentElementType.EXTERNAL_TOOL },
{ value: DrawingElementContentBody, name: ContentElementType.DRAWING },
{ value: AppointmentFinderElementContentBody, name: ContentElementType.APPOINTMENT_FINDER },
],
},
keepDiscriminatorProperty: true,
Expand All @@ -163,6 +184,7 @@ export class UpdateElementContentBodyParams {
{ $ref: getSchemaPath(SubmissionContainerElementContentBody) },
{ $ref: getSchemaPath(ExternalToolElementContentBody) },
{ $ref: getSchemaPath(DrawingElementContentBody) },
{ $ref: getSchemaPath(AppointmentFinderElementContentBody) },
],
})
data!:
Expand All @@ -171,5 +193,6 @@ export class UpdateElementContentBodyParams {
| RichTextElementContentBody
| SubmissionContainerElementContentBody
| ExternalToolElementContentBody
| DrawingElementContentBody;
| DrawingElementContentBody
| AppointmentFinderElementContentBody;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import { CardUc } from '../uc';
import { ElementUc } from '../uc/element.uc';
import {
AnyContentElementResponse,
AppointmentFinderElementContentBody,
AppointmentFinderElementResponse,
ContentElementUrlParams,
CreateSubmissionItemBodyParams,
DrawingElementContentBody,
Expand Down Expand Up @@ -71,7 +73,8 @@ export class ElementController {
SubmissionContainerElementContentBody,
ExternalToolElementContentBody,
LinkElementContentBody,
DrawingElementContentBody
DrawingElementContentBody,
AppointmentFinderElementContentBody
)
@ApiResponse({
status: 201,
Expand All @@ -83,6 +86,7 @@ export class ElementController {
{ $ref: getSchemaPath(RichTextElementResponse) },
{ $ref: getSchemaPath(SubmissionContainerElementResponse) },
{ $ref: getSchemaPath(DrawingElementResponse) },
{ $ref: getSchemaPath(AppointmentFinderElementResponse) },
],
},
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { AppointmentFinderElement, ContentElementType } from '../../domain';
import { AppointmentFinderElementResponse, TimestampsResponse } from '../dto';
import { BaseResponseMapper } from './base-mapper.interface';

export class AppointmentFinderElementResponseMapper implements BaseResponseMapper {
private static instance: AppointmentFinderElementResponseMapper;

public static getInstance(): AppointmentFinderElementResponseMapper {
if (!AppointmentFinderElementResponseMapper.instance) {
AppointmentFinderElementResponseMapper.instance = new AppointmentFinderElementResponseMapper();
}

return AppointmentFinderElementResponseMapper.instance;
}

mapToResponse(element: AppointmentFinderElement): AppointmentFinderElementResponse {
const result = new AppointmentFinderElementResponse({
id: element.id,
timestamps: new TimestampsResponse({ lastUpdatedAt: element.updatedAt, createdAt: element.createdAt }),
type: ContentElementType.APPOINTMENT_FINDER,
content: {
appointmentFinderId: element.appointmentFinderId,
adminId: element.adminId,
},
});

return result;
}

canMap(element: AppointmentFinderElement): boolean {
return element instanceof AppointmentFinderElement;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
isRichTextElementResponse,
RichTextElementResponse,
} from '../dto';
import { AppointmentFinderElementResponseMapper } from './appointment-finder-element-response.mapper';
import { BaseResponseMapper } from './base-mapper.interface';
import { CollaborativeTextEditorElementResponseMapper } from './collaborative-text-editor-element-response.mapper';
import { DeletedElementResponseMapper } from './deleted-element-response.mapper';
Expand All @@ -27,6 +28,7 @@ export class ContentElementResponseFactory {
ExternalToolElementResponseMapper.getInstance(),
CollaborativeTextEditorElementResponseMapper.getInstance(),
DeletedElementResponseMapper.getInstance(),
AppointmentFinderElementResponseMapper.getInstance(),
];

static mapToResponse(element: AnyBoardNode): AnyContentElementResponse {
Expand Down
27 changes: 27 additions & 0 deletions apps/server/src/modules/board/domain/appointment-finder.do.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { BoardNode } from './board-node.do';
import type { AppointmentFinderElementProps } from './types';

export class AppointmentFinderElement extends BoardNode<AppointmentFinderElementProps> {
get appointmentFinderId(): string | undefined {
return this.props.externalId;
}

set appointmentFinderId(value: string) {
this.props.externalId = value;
}

get adminId(): string | undefined {
return this.props.externalAdminId;
}

set adminId(value: string) {
this.props.externalAdminId = value;
}

canHaveChild(): boolean {
return false;
}
}

export const isAppointmentFinderElement = (reference: unknown): reference is AppointmentFinderElement =>
reference instanceof AppointmentFinderElement;
6 changes: 6 additions & 0 deletions apps/server/src/modules/board/domain/board-node.factory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ObjectId } from '@mikro-orm/mongodb';
import { Injectable, NotImplementedException, UnprocessableEntityException } from '@nestjs/common';
import { EntityId, InputFormat } from '@shared/domain/types';
import { AppointmentFinderElement } from './appointment-finder.do';
import { Card } from './card.do';
import { CollaborativeTextEditorElement } from './collaborative-text-editor.do';
import { ColumnBoard } from './colum-board.do';
Expand Down Expand Up @@ -86,6 +87,11 @@ export class BoardNodeFactory {
...this.getBaseProps(),
});
break;
case ContentElementType.APPOINTMENT_FINDER:
element = new AppointmentFinderElement({
...this.getBaseProps(),
});
break;
default:
handleNonExhaustiveSwitch(type);
}
Expand Down
13 changes: 7 additions & 6 deletions apps/server/src/modules/board/domain/index.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
export * from './board-node.do';
export * from './appointment-finder.do';
export * from './board-node-authorizable.do';
export * from './board-node.do';
export * from './board-node.factory';
export * from './collaborative-text-editor.do';
export * from './card.do';
export * from './column.do';
export * from './collaborative-text-editor.do';
export * from './colum-board.do';
export * from './column.do';
export * from './deleted-element.do';
export * from './drawing-element.do';
export * from './external-tool-element.do';
export * from './file-element.do';
export * from './link-element.do';
export * from './media-board';
export * from './path-utils';
export * from './rich-text-element.do';
export * from './submission-container-element.do';
export * from './submission-item.do';
export * from './path-utils';
export * from './types';
export * from './type-mapping';
export * from './deleted-element.do';
export * from './types';
2 changes: 2 additions & 0 deletions apps/server/src/modules/board/domain/type-mapping.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { NotImplementedException } from '@nestjs/common';
import { AppointmentFinderElement } from './appointment-finder.do';
import { Card } from './card.do';
import { CollaborativeTextEditorElement } from './collaborative-text-editor.do';
import { ColumnBoard } from './colum-board.do';
Expand Down Expand Up @@ -32,6 +33,7 @@ const BoardNodeTypeToConstructor = {
[BoardNodeType.SUBMISSION_CONTAINER_ELEMENT]: SubmissionContainerElement,
[BoardNodeType.SUBMISSION_ITEM]: SubmissionItem,
[BoardNodeType.DELETED_ELEMENT]: DeletedElement,
[BoardNodeType.APPOINTMENT_FINDER_ELEMENT]: AppointmentFinderElement,
} as const;

export const getBoardNodeConstructor = <T extends BoardNodeType>(type: T): typeof BoardNodeTypeToConstructor[T] =>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AppointmentFinderElement, isAppointmentFinderElement } from '../appointment-finder.do';
import { type CollaborativeTextEditorElement, isCollaborativeTextEditorElement } from '../collaborative-text-editor.do';
import { type DeletedElement, isDeletedElement } from '../deleted-element.do';
import { type DrawingElement, isDrawingElement } from '../drawing-element.do';
Expand All @@ -16,7 +17,8 @@ export type AnyContentElement =
| LinkElement
| RichTextElement
| SubmissionContainerElement
| DeletedElement;
| DeletedElement
| AppointmentFinderElement;

export const isContentElement = (boardNode: AnyBoardNode): boardNode is AnyContentElement => {
const result =
Expand All @@ -27,7 +29,8 @@ export const isContentElement = (boardNode: AnyBoardNode): boardNode is AnyConte
isLinkElement(boardNode) ||
isRichTextElement(boardNode) ||
isSubmissionContainerElement(boardNode) ||
isDeletedElement(boardNode);
isDeletedElement(boardNode) ||
isAppointmentFinderElement(boardNode);

return result;
};
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ export interface CardProps extends BoardNodeProps {

export interface CollaborativeTextEditorElementProps extends BoardNodeProps {}

export interface AppointmentFinderElementProps extends BoardNodeProps {
externalId?: string;
externalAdminId?: string;
}

export interface DrawingElementProps extends BoardNodeProps {
description: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export enum BoardNodeType {
EXTERNAL_TOOL = 'external-tool',
COLLABORATIVE_TEXT_EDITOR = 'collaborative-text-editor',
DELETED_ELEMENT = 'deleted-element',
APPOINTMENT_FINDER_ELEMENT = 'appointment-finder-element',

MEDIA_BOARD = 'media-board',
MEDIA_LINE = 'media-line',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export enum ContentElementType {
EXTERNAL_TOOL = 'externalTool',
COLLABORATIVE_TEXT_EDITOR = 'collaborativeTextEditor',
DELETED = 'deleted',
APPOINTMENT_FINDER = 'appointmentFinder',
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ export class BoardNodeEntity extends BaseEntityWithTimestamps implements BoardNo
@Property({ persist: false })
domainObject: AnyBoardNode | undefined;

@Property({ type: 'string', nullable: true })
externalId: string | undefined;

@Property({ type: 'string', nullable: true })
externalAdminId: string | undefined;

// Card, Column, ColumnBoard, LinkElement, MedialLine, DeletedElement
// --------------------------------------------------------------------------
@Property({ nullable: true })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ export class BoardNodeCopyService {
case BoardNodeType.MEDIA_EXTERNAL_TOOL_ELEMENT:
result = await this.copyMediaExternalToolElement(boardNode as MediaExternalToolElement, context);
break;
case BoardNodeType.APPOINTMENT_FINDER_ELEMENT:
throw new Error('AppointmentFinderElement is not implemented');
default:
/* istanbul ignore next */
handleNonExhaustiveSwitch(type);
Expand Down
Loading

0 comments on commit 862e798

Please sign in to comment.