From 90fff570fcf6d7127cd1d0ec5b0a4f495980bf6c Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Fri, 20 Dec 2024 11:26:27 -0300 Subject: [PATCH] feat(event): adiciona filtro de eventos passados closed #62, #57 --- .../src/lib/application/event.facade.ts | 7 +++ .../infrastructure/event.http.service.impl.ts | 5 ++ .../data-access/src/lib/providers/event.ts | 2 + .../src/lib/application/events.facade.ts | 12 +++++ .../events.mongo.service.impl.ts | 37 +++++++++++--- .../data-source/src/lib/providers/event.ts | 2 + .../event/domain/src/client/services/event.ts | 2 + .../src/client/use-cases/find-events-until.ts | 22 +++++++++ .../domain/src/client/use-cases/index.ts | 1 + .../domain/src/server/services/events.ts | 5 ++ .../src/server/use-cases/find-events-until.ts | 48 +++++++++++++++++++ .../domain/src/server/use-cases/index.ts | 1 + .../containers/events/events.container.html | 6 ++- .../lib/containers/events/events.container.ts | 15 +++++- .../resource/src/lib/controllers/events.ts | 14 ++++++ .../event-time/event-time.component.html | 7 +++ .../event-time/event-time.component.scss | 0 .../event-time/event-time.component.ts | 20 ++++++++ .../ui-shared/src/lib/components/index.ts | 1 + 19 files changed, 197 insertions(+), 10 deletions(-) create mode 100644 packages/event/domain/src/client/use-cases/find-events-until.ts create mode 100644 packages/event/domain/src/server/use-cases/find-events-until.ts create mode 100644 packages/event/ui-shared/src/lib/components/event-time/event-time.component.html create mode 100644 packages/event/ui-shared/src/lib/components/event-time/event-time.component.scss create mode 100644 packages/event/ui-shared/src/lib/components/event-time/event-time.component.ts diff --git a/packages/event/data-access/src/lib/application/event.facade.ts b/packages/event/data-access/src/lib/application/event.facade.ts index 8116c3cc..2086204a 100644 --- a/packages/event/data-access/src/lib/application/event.facade.ts +++ b/packages/event/data-access/src/lib/application/event.facade.ts @@ -11,6 +11,7 @@ import { FindAllEventsUseCase, CopyEventUseCase, FindMyEventsUseCase, + FindEventsUntilUseCase, } from '@devmx/event-domain/client'; export class EventFacade extends EntityFacade { @@ -26,6 +27,7 @@ export class EventFacade extends EntityFacade { private findEventsUseCase: FindEventsUseCase, private findMyEventsUseCase: FindMyEventsUseCase, private findAllEventsUseCase: FindAllEventsUseCase, + private findEventsUntilUseCase: FindEventsUntilUseCase, private findEventByIDUseCase: FindEventByIDUseCase, private updateEventUseCase: UpdateEventUseCase, private copyEventUseCase: CopyEventUseCase, @@ -51,6 +53,10 @@ export class EventFacade extends EntityFacade { this.onLoad(this.findAllEventsUseCase.execute(this.state.params)); } + loadUntil() { + this.onLoad(this.findEventsUntilUseCase.execute(this.state.params)); + } + loadMyEvents() { this.onLoad(this.findMyEventsUseCase.execute(this.state.params)); } @@ -94,6 +100,7 @@ export function provideEventFacade() { FindEventsUseCase, FindMyEventsUseCase, FindAllEventsUseCase, + FindEventsUntilUseCase, FindEventByIDUseCase, UpdateEventUseCase, CopyEventUseCase, diff --git a/packages/event/data-access/src/lib/infrastructure/event.http.service.impl.ts b/packages/event/data-access/src/lib/infrastructure/event.http.service.impl.ts index 991c3b2b..256a5e80 100644 --- a/packages/event/data-access/src/lib/infrastructure/event.http.service.impl.ts +++ b/packages/event/data-access/src/lib/infrastructure/event.http.service.impl.ts @@ -20,6 +20,11 @@ export class EventHttpServiceImpl return this.http.get>(url.join('?')); } + findUntil(params: QueryParams) { + const url = [`${this.url}/until`, createQueryParams(params)]; + return this.http.get>(url.join('?')); + } + findMyEvents(params: QueryParams) { const url = [`${this.url}/my`, createQueryParams(params)]; return this.http.get>(url.join('?')); diff --git a/packages/event/data-access/src/lib/providers/event.ts b/packages/event/data-access/src/lib/providers/event.ts index bab59d8d..bc34ed91 100644 --- a/packages/event/data-access/src/lib/providers/event.ts +++ b/packages/event/data-access/src/lib/providers/event.ts @@ -6,6 +6,7 @@ import { provideDeleteEventUseCase, provideFindAllEventsUseCase, provideFindEventByIDUseCase, + provideFindEventsUntilUseCase, provideFindEventsUseCase, provideFindMyEventsUseCase, provideUpdateEventUseCase, @@ -19,6 +20,7 @@ export function provideEvent() { provideFindEventsUseCase(), provideFindMyEventsUseCase(), provideFindAllEventsUseCase(), + provideFindEventsUntilUseCase(), provideFindEventByIDUseCase(), provideUpdateEventUseCase(), provideDeleteEventUseCase(), diff --git a/packages/event/data-source/src/lib/application/events.facade.ts b/packages/event/data-source/src/lib/application/events.facade.ts index dd90ac5f..ef76137f 100644 --- a/packages/event/data-source/src/lib/application/events.facade.ts +++ b/packages/event/data-source/src/lib/application/events.facade.ts @@ -12,6 +12,7 @@ import { DeleteEventUseCase, FindEventByIDUseCase, FindEventsFromUseCase, + FindEventsUntilUseCase, FindEventsUseCase, FindMyEventsUseCase, UpdateEventUseCase, @@ -28,6 +29,7 @@ export class EventsFacade { private findEventsUseCase: FindEventsUseCase, private findMyEventsUseCase: FindMyEventsUseCase, private findEventsFromUseCase: FindEventsFromUseCase, + private findEventsUntilUseCase: FindEventsUntilUseCase, private findEventByIDUseCase: FindEventByIDUseCase, private updateEventUseCase: UpdateEventUseCase, private copyEventUseCase: CopyEventUseCase, @@ -67,6 +69,15 @@ export class EventsFacade { return new PageDto(events, items, pages); } + async findUntil(date: Date, params: QueryParamsDto) { + const { data, items, pages } = await this.findEventsUntilUseCase.execute([ + date, + params, + ]); + const events = plainToInstance(EventDto, data); + return new PageDto(events, items, pages); + } + async findOne(id: string) { const event = await this.findEventByIDUseCase.execute(id); return plainToInstance(EventDto, event); @@ -89,6 +100,7 @@ export function provideEventsFacade() { FindEventsUseCase, FindMyEventsUseCase, FindEventsFromUseCase, + FindEventsUntilUseCase, FindEventByIDUseCase, UpdateEventUseCase, CopyEventUseCase, diff --git a/packages/event/data-source/src/lib/infrastructure/events.mongo.service.impl.ts b/packages/event/data-source/src/lib/infrastructure/events.mongo.service.impl.ts index 946ee681..cbae1964 100644 --- a/packages/event/data-source/src/lib/infrastructure/events.mongo.service.impl.ts +++ b/packages/event/data-source/src/lib/infrastructure/events.mongo.service.impl.ts @@ -1,12 +1,12 @@ import { QueryParams, EditableEntity } from '@devmx/shared-api-interfaces'; +import { Query, RootFilterQuery, SortOrder } from 'mongoose'; import { EventsService } from '@devmx/event-domain/server'; import { getModelToken } from '@nestjs/mongoose'; import { EventCollection } from '../schemas'; -import { Query } from 'mongoose'; import { + objectId, MongoService, createServiceProvider, - objectId, } from '@devmx/shared-data-source'; export class EventsMongoServiceImpl @@ -38,15 +38,38 @@ export class EventsMongoServiceImpl } async findFrom(date: Date, params: QueryParams) { - const { page = 0, size = 10, filter, sort } = params; + const { page = 0, size = 10 } = params; const skip = page * size; - const where = this.applyFilter(filter ?? {}); - const order = this.applySort(sort ?? {}); + const filter = this.applyFilter(params.filter ?? {}); + const sort = this.applySort(params.sort ?? {}); + + const where = { ...filter, date: { $gte: date } }; + + return this.findByWhere(where, sort, skip, size); + } + async findUntil(date: Date, params: QueryParams) { + const { page = 0, size = 10 } = params; + + const skip = page * size; + const filter = this.applyFilter(params.filter ?? {}); + const sort = this.applySort(params.sort ?? {}); + + const where = { ...filter, date: { $lte: date } }; + + return this.findByWhere(where, sort, skip, size); + } + + async findByWhere( + where: RootFilterQuery, + sort: Record, + skip: number, + size: number + ) { const query = this.entityModel - .find({ ...where, date: { $gte: date } }) - .sort(order) + .find(where) + .sort(sort) .skip(skip) .limit(size); diff --git a/packages/event/data-source/src/lib/providers/event.ts b/packages/event/data-source/src/lib/providers/event.ts index 6bdae8f6..84550bfc 100644 --- a/packages/event/data-source/src/lib/providers/event.ts +++ b/packages/event/data-source/src/lib/providers/event.ts @@ -9,6 +9,7 @@ import { provideFindEventsFromUseCase, provideCopyEventUseCase, provideFindMyEventsUseCase, + provideFindEventsUntilUseCase, } from '@devmx/event-domain/server'; export function provideEvent() { @@ -19,6 +20,7 @@ export function provideEvent() { provideFindEventsUseCase(), provideFindMyEventsUseCase(), provideFindEventsFromUseCase(), + provideFindEventsUntilUseCase(), provideFindEventByIDUseCase(), provideUpdateEventUseCase(), provideDeleteEventUseCase(), diff --git a/packages/event/domain/src/client/services/event.ts b/packages/event/domain/src/client/services/event.ts index df6477dc..1e7c4435 100644 --- a/packages/event/domain/src/client/services/event.ts +++ b/packages/event/domain/src/client/services/event.ts @@ -14,6 +14,8 @@ export abstract class EventService extends EntityService { abstract findAll(params: QueryParams): Observable>; + abstract findUntil(params: QueryParams): Observable>; + abstract findMyEvents(params: QueryParams): Observable>; abstract createRSVP(event: string, status: RSVPStatus): Observable; diff --git a/packages/event/domain/src/client/use-cases/find-events-until.ts b/packages/event/domain/src/client/use-cases/find-events-until.ts new file mode 100644 index 00000000..78c365a3 --- /dev/null +++ b/packages/event/domain/src/client/use-cases/find-events-until.ts @@ -0,0 +1,22 @@ +import { createUseCaseProvider } from '@devmx/shared-util-data/client'; +import { EventService } from '../services'; +import { + Page, + Event, + UseCase, + QueryParams, +} from '@devmx/shared-api-interfaces'; + +export class FindEventsUntilUseCase + implements UseCase, Page> +{ + constructor(private eventService: EventService) {} + + execute(params: QueryParams) { + return this.eventService.findUntil(params); + } +} + +export function provideFindEventsUntilUseCase() { + return createUseCaseProvider(FindEventsUntilUseCase, [EventService]); +} diff --git a/packages/event/domain/src/client/use-cases/index.ts b/packages/event/domain/src/client/use-cases/index.ts index 301151e4..b6d25730 100644 --- a/packages/event/domain/src/client/use-cases/index.ts +++ b/packages/event/domain/src/client/use-cases/index.ts @@ -4,6 +4,7 @@ export * from './create-rsvp'; export * from './delete-event'; export * from './find-all-events'; export * from './find-event-by-id'; +export * from './find-events-until'; export * from './find-events'; export * from './find-my-events'; export * from './find-rsvp-by-event'; diff --git a/packages/event/domain/src/server/services/events.ts b/packages/event/domain/src/server/services/events.ts index f3ea25c6..7cbe1344 100644 --- a/packages/event/domain/src/server/services/events.ts +++ b/packages/event/domain/src/server/services/events.ts @@ -7,5 +7,10 @@ export abstract class EventsService extends EntityService { params: QueryParams ): Promise>; + abstract findUntil( + date: Date, + params: QueryParams + ): Promise>; + abstract findMyEvents(params: QueryParams): Promise>; } diff --git a/packages/event/domain/src/server/use-cases/find-events-until.ts b/packages/event/domain/src/server/use-cases/find-events-until.ts new file mode 100644 index 00000000..db718892 --- /dev/null +++ b/packages/event/domain/src/server/use-cases/find-events-until.ts @@ -0,0 +1,48 @@ +import { createUseCaseProvider } from '@devmx/shared-util-data/server'; +import { EventsService } from '../services'; +import { + Event, + Page, + UseCase, + QueryParams, +} from '@devmx/shared-api-interfaces'; + +export class FindEventsUntilUseCase + implements UseCase<[Date, QueryParams], Page> +{ + constructor(private eventsService: EventsService) {} + + async execute([date, params]: [Date, QueryParams]) { + if (params.filter) { + if (params.filter.format) { + params.filter.format = new RegExp(params.filter.format, 'i'); + } else { + delete params.filter.format; + } + + if (params.filter.title) { + params.filter.title = new RegExp(params.filter.title, 'i'); + } else { + delete params.filter.title; + } + + if (params.filter.city) { + params.filter.city = params.filter.city.toString(); + } else { + delete params.filter.city; + } + + if (params.filter.description) { + params.filter.description = new RegExp(params.filter.description, 'i'); + } else { + delete params.filter.description; + } + } + + return await this.eventsService.findUntil(date, params); + } +} + +export function provideFindEventsUntilUseCase() { + return createUseCaseProvider(FindEventsUntilUseCase, [EventsService]); +} diff --git a/packages/event/domain/src/server/use-cases/index.ts b/packages/event/domain/src/server/use-cases/index.ts index f8726c5c..da75ddd7 100644 --- a/packages/event/domain/src/server/use-cases/index.ts +++ b/packages/event/domain/src/server/use-cases/index.ts @@ -4,6 +4,7 @@ export * from './create-rsvp'; export * from './delete-event'; export * from './find-event-by-id'; export * from './find-events-from'; +export * from './find-events-until'; export * from './find-events'; export * from './find-my-events'; export * from './find-past-events'; diff --git a/packages/event/feature-shell/src/lib/containers/events/events.container.html b/packages/event/feature-shell/src/lib/containers/events/events.container.html index 18134ad2..017f863e 100644 --- a/packages/event/feature-shell/src/lib/containers/events/events.container.html +++ b/packages/event/feature-shell/src/lib/containers/events/events.container.html @@ -1,5 +1,9 @@
- +
+ + + +
diff --git a/packages/event/feature-shell/src/lib/containers/events/events.container.ts b/packages/event/feature-shell/src/lib/containers/events/events.container.ts index 54122786..56d3d6e5 100644 --- a/packages/event/feature-shell/src/lib/containers/events/events.container.ts +++ b/packages/event/feature-shell/src/lib/containers/events/events.container.ts @@ -9,6 +9,7 @@ import { AsyncPipe } from '@angular/common'; import { EventCardComponent, EventFilterComponent, + EventTimeComponent, } from '@devmx/event-ui-shared'; @Component({ @@ -18,6 +19,7 @@ import { changeDetection: ChangeDetectionStrategy.OnPush, imports: [ PaginatorComponent, + EventTimeComponent, EventFilterComponent, SortDirectionComponent, EventCardComponent, @@ -40,7 +42,7 @@ export class EventsContainer { } onQueryParams = (params: Params) => { - const { title = '', format = '', date = 'asc' } = params; + const { title = '', format = '', date = 'asc', time = '' } = params; const { page = 0, size = 10 } = params; @@ -50,7 +52,11 @@ export class EventsContainer { this.eventFacade.setParams({ page, size, filter, sort }); - this.eventFacade.load(); + if (time === 'until') { + this.eventFacade.loadUntil(); + } else { + this.eventFacade.load(); + } }; onFilterChange(format: string) { @@ -58,6 +64,11 @@ export class EventsContainer { this.router.navigate([], { queryParams }); } + onTimeChange(time: string) { + const queryParams = { time }; + this.router.navigate([], { queryParams }); + } + onSortChange(date: string) { const queryParams = { date }; this.router.navigate([], { queryParams }); diff --git a/packages/event/resource/src/lib/controllers/events.ts b/packages/event/resource/src/lib/controllers/events.ts index 633caa37..00f8072b 100644 --- a/packages/event/resource/src/lib/controllers/events.ts +++ b/packages/event/resource/src/lib/controllers/events.ts @@ -93,6 +93,20 @@ export class EventsController { } } + @Get('until') + @Allowed() + @ApiPage(EventDto) + async findUntil(@Query() params: QueryParamsDto) { + let date = new Date(); + date = subDays(date, 1); + + try { + return await this.eventsFacade.findUntil(date, params); + } catch (err) { + throw exceptionByError(err); + } + } + @Get('my') @Allowed() @ApiPage(EventDto) diff --git a/packages/event/ui-shared/src/lib/components/event-time/event-time.component.html b/packages/event/ui-shared/src/lib/components/event-time/event-time.component.html new file mode 100644 index 00000000..9cf3e7bf --- /dev/null +++ b/packages/event/ui-shared/src/lib/components/event-time/event-time.component.html @@ -0,0 +1,7 @@ + + @for (time of times; track time.value) { + + {{ time.viewValue }} + + } + diff --git a/packages/event/ui-shared/src/lib/components/event-time/event-time.component.scss b/packages/event/ui-shared/src/lib/components/event-time/event-time.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/packages/event/ui-shared/src/lib/components/event-time/event-time.component.ts b/packages/event/ui-shared/src/lib/components/event-time/event-time.component.ts new file mode 100644 index 00000000..d0f32bad --- /dev/null +++ b/packages/event/ui-shared/src/lib/components/event-time/event-time.component.ts @@ -0,0 +1,20 @@ +import { ChangeDetectionStrategy, Component, output } from '@angular/core'; +import { MatChipsModule } from '@angular/material/chips'; +import { FormOption } from '@devmx/shared-ui-global/forms'; +import { EventFormat } from '@devmx/shared-api-interfaces'; + +@Component({ + selector: 'devmx-event-time', + templateUrl: './event-time.component.html', + styleUrl: './event-time.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [MatChipsModule], +}) +export class EventTimeComponent { + timeChange = output(); + + times: FormOption<'' | 'until'>[] = [ + { value: '', viewValue: 'Chegando' }, + { value: 'until', viewValue: 'Passados' }, + ]; +} diff --git a/packages/event/ui-shared/src/lib/components/index.ts b/packages/event/ui-shared/src/lib/components/index.ts index dda1f9fb..fde04580 100644 --- a/packages/event/ui-shared/src/lib/components/index.ts +++ b/packages/event/ui-shared/src/lib/components/index.ts @@ -2,3 +2,4 @@ export * from './event-card-list/event-card-list.component'; export * from './event-filter/event-filter.component'; export * from './rsvp-button/rsvp-button.component'; export * from './event-card/event-card.component'; +export * from './event-time/event-time.component';