From d6ada8fe162061f3d3e7893ff65b5d6218a30bdf Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Mon, 30 Sep 2024 16:15:45 -0300 Subject: [PATCH 01/11] feat: event scope --- apps/server/src/app.module.ts | 6 +- .../resource/src/lib/controllers/accounts.ts | 2 +- .../resource/src/lib/controllers/auth.ts | 2 +- packages/event/data-source/.eslintrc.json | 30 ++++++++ packages/event/data-source/jest.config.ts | 11 +++ packages/event/data-source/package.json | 22 ++++++ packages/event/data-source/project.json | 19 +++++ packages/event/data-source/src/index.ts | 3 + .../data-source/src/lib/dtos/create-event.ts | 47 +++++++++++++ .../event/data-source/src/lib/dtos/event.ts | 50 +++++++++++++ .../event/data-source/src/lib/dtos/index.ts | 3 + .../data-source/src/lib/dtos/update-event.ts | 4 ++ .../data-source/src/lib/event-providers.ts | 12 ++++ .../data-source/src/lib/facades/events.ts | 16 +++++ .../data-source/src/lib/facades/index.ts | 1 + .../data-source/src/lib/providers/facades.ts | 7 ++ .../data-source/src/lib/providers/index.ts | 3 + .../data-source/src/lib/providers/services.ts | 11 +++ .../src/lib/providers/use-cases.ts | 6 ++ .../data-source/src/lib/schemas/event.ts | 70 +++++++++++++++++++ .../data-source/src/lib/schemas/index.ts | 1 + .../src/lib/services/events.impl.ts | 64 +++++++++++++++++ .../data-source/src/lib/services/index.ts | 1 + packages/event/data-source/tsconfig.json | 23 ++++++ packages/event/data-source/tsconfig.lib.json | 10 +++ packages/event/data-source/tsconfig.spec.json | 14 ++++ packages/event/domain/.eslintrc.json | 30 ++++++++ packages/event/domain/jest.config.ts | 9 +++ packages/event/domain/package.json | 12 ++++ packages/event/domain/project.json | 23 ++++++ packages/event/domain/src/index.ts | 1 + .../event/domain/src/lib/event-domain.spec.ts | 7 ++ packages/event/domain/src/lib/event-domain.ts | 3 + packages/event/domain/src/server.ts | 1 + .../domain/src/server/dtos/create-event.ts | 23 ++++++ .../event/domain/src/server/dtos/index.ts | 2 + .../domain/src/server/dtos/update-event.ts | 5 ++ packages/event/domain/src/server/index.ts | 3 + .../event/domain/src/server/services/event.ts | 21 ++++++ .../event/domain/src/server/services/index.ts | 1 + .../src/server/use-cases/find-events.ts | 42 +++++++++++ .../domain/src/server/use-cases/index.ts | 1 + packages/event/domain/tsconfig.json | 22 ++++++ packages/event/domain/tsconfig.lib.json | 10 +++ packages/event/domain/tsconfig.spec.json | 14 ++++ packages/event/resource/.eslintrc.json | 18 +++++ packages/event/resource/README.md | 7 ++ packages/event/resource/jest.config.ts | 11 +++ packages/event/resource/project.json | 9 +++ packages/event/resource/src/index.ts | 1 + .../resource/src/lib/controllers/events.ts | 24 +++++++ .../resource/src/lib/controllers/index.ts | 1 + .../resource/src/lib/event-database.module.ts | 22 ++++++ .../resource/src/lib/event-resource.module.ts | 9 +++ packages/event/resource/tsconfig.json | 22 ++++++ packages/event/resource/tsconfig.lib.json | 16 +++++ packages/event/resource/tsconfig.spec.json | 14 ++++ .../resource/src/lib/controllers/locations.ts | 2 +- .../src/lib/controllers/presentations.ts | 2 - .../api-interfaces/src/lib/entities/event.ts | 30 ++++++++ .../api-interfaces/src/lib/entities/index.ts | 1 + .../src/lib/types/event-format.ts | 1 + .../api-interfaces/src/lib/types/index.ts | 1 + tsconfig.base.json | 10 ++- 64 files changed, 859 insertions(+), 10 deletions(-) create mode 100644 packages/event/data-source/.eslintrc.json create mode 100644 packages/event/data-source/jest.config.ts create mode 100644 packages/event/data-source/package.json create mode 100644 packages/event/data-source/project.json create mode 100644 packages/event/data-source/src/index.ts create mode 100644 packages/event/data-source/src/lib/dtos/create-event.ts create mode 100644 packages/event/data-source/src/lib/dtos/event.ts create mode 100644 packages/event/data-source/src/lib/dtos/index.ts create mode 100644 packages/event/data-source/src/lib/dtos/update-event.ts create mode 100644 packages/event/data-source/src/lib/event-providers.ts create mode 100644 packages/event/data-source/src/lib/facades/events.ts create mode 100644 packages/event/data-source/src/lib/facades/index.ts create mode 100644 packages/event/data-source/src/lib/providers/facades.ts create mode 100644 packages/event/data-source/src/lib/providers/index.ts create mode 100644 packages/event/data-source/src/lib/providers/services.ts create mode 100644 packages/event/data-source/src/lib/providers/use-cases.ts create mode 100644 packages/event/data-source/src/lib/schemas/event.ts create mode 100644 packages/event/data-source/src/lib/schemas/index.ts create mode 100644 packages/event/data-source/src/lib/services/events.impl.ts create mode 100644 packages/event/data-source/src/lib/services/index.ts create mode 100644 packages/event/data-source/tsconfig.json create mode 100644 packages/event/data-source/tsconfig.lib.json create mode 100644 packages/event/data-source/tsconfig.spec.json create mode 100644 packages/event/domain/.eslintrc.json create mode 100644 packages/event/domain/jest.config.ts create mode 100644 packages/event/domain/package.json create mode 100644 packages/event/domain/project.json create mode 100644 packages/event/domain/src/index.ts create mode 100644 packages/event/domain/src/lib/event-domain.spec.ts create mode 100644 packages/event/domain/src/lib/event-domain.ts create mode 100644 packages/event/domain/src/server.ts create mode 100644 packages/event/domain/src/server/dtos/create-event.ts create mode 100644 packages/event/domain/src/server/dtos/index.ts create mode 100644 packages/event/domain/src/server/dtos/update-event.ts create mode 100644 packages/event/domain/src/server/index.ts create mode 100644 packages/event/domain/src/server/services/event.ts create mode 100644 packages/event/domain/src/server/services/index.ts create mode 100644 packages/event/domain/src/server/use-cases/find-events.ts create mode 100644 packages/event/domain/src/server/use-cases/index.ts create mode 100644 packages/event/domain/tsconfig.json create mode 100644 packages/event/domain/tsconfig.lib.json create mode 100644 packages/event/domain/tsconfig.spec.json create mode 100644 packages/event/resource/.eslintrc.json create mode 100644 packages/event/resource/README.md create mode 100644 packages/event/resource/jest.config.ts create mode 100644 packages/event/resource/project.json create mode 100644 packages/event/resource/src/index.ts create mode 100644 packages/event/resource/src/lib/controllers/events.ts create mode 100644 packages/event/resource/src/lib/controllers/index.ts create mode 100644 packages/event/resource/src/lib/event-database.module.ts create mode 100644 packages/event/resource/src/lib/event-resource.module.ts create mode 100644 packages/event/resource/tsconfig.json create mode 100644 packages/event/resource/tsconfig.lib.json create mode 100644 packages/event/resource/tsconfig.spec.json create mode 100644 packages/shared/api-interfaces/src/lib/entities/event.ts create mode 100644 packages/shared/api-interfaces/src/lib/types/event-format.ts diff --git a/apps/server/src/app.module.ts b/apps/server/src/app.module.ts index 3221a5ca..973b6bff 100644 --- a/apps/server/src/app.module.ts +++ b/apps/server/src/app.module.ts @@ -1,7 +1,8 @@ import { SharedDatabaseModule, SharedResourceModule } from '@devmx/shared-resource'; import { PresentationResourceModule } from '@devmx/presentation-resource'; -import { AccountResourceModule } from '@devmx/account-resource'; import { LocationResourceModule } from '@devmx/location-resource'; +import { AccountResourceModule } from '@devmx/account-resource'; +import { EventResourceModule } from '@devmx/event-resource'; import { ServeStaticModule } from '@nestjs/serve-static'; import { Module } from '@nestjs/common'; import { env } from './envs/env'; @@ -13,7 +14,8 @@ import { env } from './envs/env'; SharedDatabaseModule, AccountResourceModule, PresentationResourceModule, - LocationResourceModule + LocationResourceModule, + EventResourceModule ] }) export class AppModule {} diff --git a/packages/account/resource/src/lib/controllers/accounts.ts b/packages/account/resource/src/lib/controllers/accounts.ts index 88c49dd7..d86c4d68 100644 --- a/packages/account/resource/src/lib/controllers/accounts.ts +++ b/packages/account/resource/src/lib/controllers/accounts.ts @@ -41,7 +41,7 @@ import { import 'multer'; @ApiBearerAuth() -@ApiTags('Accounts') +@ApiTags('Contas') @Controller('accounts') export class AccountsController { constructor(private readonly accountsFacade: AccountsFacade) {} diff --git a/packages/account/resource/src/lib/controllers/auth.ts b/packages/account/resource/src/lib/controllers/auth.ts index 097cb635..9eb534be 100644 --- a/packages/account/resource/src/lib/controllers/auth.ts +++ b/packages/account/resource/src/lib/controllers/auth.ts @@ -11,7 +11,7 @@ import { AccessTokenDto, } from '@devmx/account-data-source'; -@ApiTags('Auth') +@ApiTags('Autenticação') @Controller('auth') export class AuthController { constructor(private authFacade: AuthFacade) {} diff --git a/packages/event/data-source/.eslintrc.json b/packages/event/data-source/.eslintrc.json new file mode 100644 index 00000000..ca1930a1 --- /dev/null +++ b/packages/event/data-source/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] + } + ] + } + } + ] +} diff --git a/packages/event/data-source/jest.config.ts b/packages/event/data-source/jest.config.ts new file mode 100644 index 00000000..fee4318d --- /dev/null +++ b/packages/event/data-source/jest.config.ts @@ -0,0 +1,11 @@ +export default { + displayName: 'event-data-source', + preset: '../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/packages/event/data-source', + passWithNoTests: true +}; diff --git a/packages/event/data-source/package.json b/packages/event/data-source/package.json new file mode 100644 index 00000000..c215eba3 --- /dev/null +++ b/packages/event/data-source/package.json @@ -0,0 +1,22 @@ +{ + "name": "@devmx/event-data-source", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0", + "@nestjs/swagger": "^7.4.2", + "class-validator": "^0.14.1", + "@devmx/shared-api-interfaces": "0.0.1", + "@devmx/location-data-source": "0.0.1", + "@devmx/presentation-data-source": "0.0.1", + "class-transformer": "^0.5.1", + "@nestjs/mapped-types": "*", + "@devmx/shared-data-source": "0.0.1", + "@devmx/event-domain": "0.0.1", + "@nestjs/mongoose": "^10.0.10", + "mongoose": "^8.6.3" + }, + "type": "commonjs", + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/packages/event/data-source/project.json b/packages/event/data-source/project.json new file mode 100644 index 00000000..4d6ca951 --- /dev/null +++ b/packages/event/data-source/project.json @@ -0,0 +1,19 @@ +{ + "name": "event-data-source", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/event/data-source/src", + "projectType": "library", + "tags": ["type:data"], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/packages/event/data-source", + "main": "packages/event/data-source/src/index.ts", + "tsConfig": "packages/event/data-source/tsconfig.lib.json", + "assets": [] + } + } + } +} diff --git a/packages/event/data-source/src/index.ts b/packages/event/data-source/src/index.ts new file mode 100644 index 00000000..dc8a0f1c --- /dev/null +++ b/packages/event/data-source/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/event-providers'; +export * from './lib/schemas'; +export * from './lib/facades'; diff --git a/packages/event/data-source/src/lib/dtos/create-event.ts b/packages/event/data-source/src/lib/dtos/create-event.ts new file mode 100644 index 00000000..6be44bb6 --- /dev/null +++ b/packages/event/data-source/src/lib/dtos/create-event.ts @@ -0,0 +1,47 @@ +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { IsBoolean, IsOptional, IsString } from 'class-validator'; +import { EventFormat } from '@devmx/shared-api-interfaces'; + +export class CreateEventDto { + @IsString() + @ApiProperty() + title: string; + + @IsString() + @ApiProperty() + description: string; + + @IsString() + @ApiProperty({ + type: 'enum', + enum: ['in-person', 'online', 'mixed'], + example: 'in-person', + }) + format: EventFormat; + + @IsString() + @ApiProperty() + date: string; + + @IsString() + @ApiProperty() + time: string; + + @IsString() + @IsOptional() + @ApiPropertyOptional() + cover = ''; + + @IsBoolean() + @IsOptional() + @ApiPropertyOptional() + visible = false; + + @IsString() + @ApiProperty() + address: string; + + city?: string; + + location?: string; +} diff --git a/packages/event/data-source/src/lib/dtos/event.ts b/packages/event/data-source/src/lib/dtos/event.ts new file mode 100644 index 00000000..c66e6086 --- /dev/null +++ b/packages/event/data-source/src/lib/dtos/event.ts @@ -0,0 +1,50 @@ +import { CityDto, LocationDto } from '@devmx/location-data-source'; +import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { PresentationDto } from '@devmx/presentation-data-source'; +import { EventFormat } from '@devmx/shared-api-interfaces'; +import { Type } from 'class-transformer'; + +export class EventDto { + @ApiProperty() + id: string; + + @ApiProperty() + title: string; + + @ApiProperty() + description: string; + + @ApiProperty({ + type: 'enum', + enum: ['in-person', 'online', 'mixed'], + example: 'in-person', + }) + format: EventFormat; + + @ApiProperty() + date: string; + + @ApiProperty() + time: string; + + @ApiProperty() + cover: string; + + @ApiProperty() + visible: boolean; + + @ApiProperty({ type: () => [PresentationDto]}) + @Type(() => PresentationDto) + presentations: PresentationDto[]; + + @ApiProperty() + address: string; + + @ApiPropertyOptional({ type: () => CityDto}) + @Type(() => CityDto) + city?: CityDto; + + @ApiPropertyOptional({ type: () => LocationDto}) + @Type(() => LocationDto) + location?: LocationDto; +} diff --git a/packages/event/data-source/src/lib/dtos/index.ts b/packages/event/data-source/src/lib/dtos/index.ts new file mode 100644 index 00000000..5090cf6d --- /dev/null +++ b/packages/event/data-source/src/lib/dtos/index.ts @@ -0,0 +1,3 @@ +export * from './create-event'; +export * from './event'; +export * from './update-event'; diff --git a/packages/event/data-source/src/lib/dtos/update-event.ts b/packages/event/data-source/src/lib/dtos/update-event.ts new file mode 100644 index 00000000..2cbc8280 --- /dev/null +++ b/packages/event/data-source/src/lib/dtos/update-event.ts @@ -0,0 +1,4 @@ +import { CreateEventDto } from './create-event'; +import { PartialType } from '@nestjs/mapped-types'; + +export class UpdateEventDto extends PartialType(CreateEventDto) {} diff --git a/packages/event/data-source/src/lib/event-providers.ts b/packages/event/data-source/src/lib/event-providers.ts new file mode 100644 index 00000000..e4b8d43f --- /dev/null +++ b/packages/event/data-source/src/lib/event-providers.ts @@ -0,0 +1,12 @@ +import { provideEventsFacade, provideEventsService } from "./providers"; +import { provideFindEventsUseCase } from "./providers/use-cases"; + +export function provideEvents() { + return [ + provideEventsService(), + + provideFindEventsUseCase(), + + provideEventsFacade() + ] +} diff --git a/packages/event/data-source/src/lib/facades/events.ts b/packages/event/data-source/src/lib/facades/events.ts new file mode 100644 index 00000000..9868eea1 --- /dev/null +++ b/packages/event/data-source/src/lib/facades/events.ts @@ -0,0 +1,16 @@ +import { PageDto, QueryParamsDto } from '@devmx/shared-data-source'; +import { FindEventsUseCase } from '@devmx/event-domain/server'; +import { Event } from '@devmx/shared-api-interfaces'; +import { plainToInstance } from 'class-transformer'; +import { EventDto } from '../dtos'; + +export class EventsFacade { + constructor(private findEventsUseCase: FindEventsUseCase) {} + + async find(params: QueryParamsDto) { + params.filter = { ...params.filter, visible: true }; + const { data, items, pages } = await this.findEventsUseCase.execute(params); + const presentations = plainToInstance(EventDto, data); + return new PageDto(presentations, items, pages); + } +} diff --git a/packages/event/data-source/src/lib/facades/index.ts b/packages/event/data-source/src/lib/facades/index.ts new file mode 100644 index 00000000..67f709a0 --- /dev/null +++ b/packages/event/data-source/src/lib/facades/index.ts @@ -0,0 +1 @@ +export * from './events'; diff --git a/packages/event/data-source/src/lib/providers/facades.ts b/packages/event/data-source/src/lib/providers/facades.ts new file mode 100644 index 00000000..244754a9 --- /dev/null +++ b/packages/event/data-source/src/lib/providers/facades.ts @@ -0,0 +1,7 @@ +import { createServerProvider } from '@devmx/shared-data-source'; +import { EventsFacade } from '../facades'; +import { FindEventsUseCase } from '@devmx/event-domain/server'; + +export function provideEventsFacade() { + return createServerProvider(EventsFacade, [FindEventsUseCase]); +} diff --git a/packages/event/data-source/src/lib/providers/index.ts b/packages/event/data-source/src/lib/providers/index.ts new file mode 100644 index 00000000..f95ea038 --- /dev/null +++ b/packages/event/data-source/src/lib/providers/index.ts @@ -0,0 +1,3 @@ +export * from './facades'; +export * from './services'; +export * from './use-cases'; diff --git a/packages/event/data-source/src/lib/providers/services.ts b/packages/event/data-source/src/lib/providers/services.ts new file mode 100644 index 00000000..9684fdac --- /dev/null +++ b/packages/event/data-source/src/lib/providers/services.ts @@ -0,0 +1,11 @@ +import { createServiceProvider } from '@devmx/shared-data-source'; +import { EventsService } from '@devmx/event-domain/server'; +import { getModelToken } from '@nestjs/mongoose'; +import { EventsServiceImpl } from '../services'; +import { EventCollection } from '../schemas'; + +export function provideEventsService() { + return createServiceProvider(EventsService, EventsServiceImpl, [ + getModelToken(EventCollection.name), + ]); +} diff --git a/packages/event/data-source/src/lib/providers/use-cases.ts b/packages/event/data-source/src/lib/providers/use-cases.ts new file mode 100644 index 00000000..9be7b6dd --- /dev/null +++ b/packages/event/data-source/src/lib/providers/use-cases.ts @@ -0,0 +1,6 @@ +import { EventsService, FindEventsUseCase } from '@devmx/event-domain/server'; +import { createUseCaseProvider } from '@devmx/shared-data-source'; + +export function provideFindEventsUseCase() { + return createUseCaseProvider(FindEventsUseCase, [EventsService]); +} diff --git a/packages/event/data-source/src/lib/schemas/event.ts b/packages/event/data-source/src/lib/schemas/event.ts new file mode 100644 index 00000000..d6d8d42b --- /dev/null +++ b/packages/event/data-source/src/lib/schemas/event.ts @@ -0,0 +1,70 @@ +import { PresentationCollection } from '@devmx/presentation-data-source'; +import { Event, EventFormat } from '@devmx/shared-api-interfaces'; +import { createSchema } from '@devmx/shared-data-source'; +import { Prop, Schema } from '@nestjs/mongoose'; +import mongoose, { Document } from 'mongoose'; +import { + PointSchema, + CityCollection, + PointCollection, +} from '@devmx/location-data-source'; + +@Schema() +export class EventCollection extends Document implements Event { + override id: string; + + @Prop({ type: String, required: true }) + title: string; + + @Prop({ type: String, default: '' }) + description: string; + + @Prop({ + type: String, + enum: ['in-person', 'online', 'mixed'], + default: 'in-person', + }) + format: EventFormat; + + @Prop({ type: String, required: true, default: '' }) + date: string; + + @Prop({ type: String, required: true, default: '' }) + time: string; + + @Prop({ default: '' }) + cover: string; + + @Prop({ default: false }) + visible: boolean; + + @Prop({ + type: [ + { + type: mongoose.Schema.Types.ObjectId, + ref: PresentationCollection.name, + }, + ], + }) + presentations: PresentationCollection[]; + + @Prop({ + type: String, + required: true, + }) + address: string; + + @Prop({ + type: mongoose.Schema.Types.ObjectId, + ref: CityCollection.name, + }) + city?: CityCollection; + + @Prop({ + type: PointSchema, + index: '2dsphere', + }) + location?: PointCollection; +} + +export const EventSchema = createSchema(EventCollection); diff --git a/packages/event/data-source/src/lib/schemas/index.ts b/packages/event/data-source/src/lib/schemas/index.ts new file mode 100644 index 00000000..742039d1 --- /dev/null +++ b/packages/event/data-source/src/lib/schemas/index.ts @@ -0,0 +1 @@ +export * from './event'; diff --git a/packages/event/data-source/src/lib/services/events.impl.ts b/packages/event/data-source/src/lib/services/events.impl.ts new file mode 100644 index 00000000..ac70528c --- /dev/null +++ b/packages/event/data-source/src/lib/services/events.impl.ts @@ -0,0 +1,64 @@ +import { QueryFilterDto, QueryParamsDto } from '@devmx/shared-data-source'; +import { EventsService } from '@devmx/event-domain/server'; +import { CreateEventDto, UpdateEventDto } from '../dtos'; +import { Event } from '@devmx/shared-api-interfaces'; +import { Model } from 'mongoose'; + +export class EventsServiceImpl implements EventsService { + constructor(private eventModel: Model) {} + + async create(data: CreateEventDto): Promise { + const createdEvent = new this.eventModel(data); + return (await createdEvent.save()).toJSON(); + } + + async find(params: QueryParamsDto) { + const { page = 0, size = 10, filter } = params; + + const skip = page * size; + + const where = { ...filter }; + + const events = await this.eventModel + .find(where) + .skip(skip) + .limit(size) + .populate('account') + .exec(); + + const data = events.map((item) => item.toJSON()); + const items = await this.eventModel.countDocuments(where).exec(); + const pages = Math.ceil(items / size); + + return { data, items, pages }; + } + + async findOne(id: string) { + const event = await this.eventModel.findById(id).populate('account').exec(); + + return event ? event.toJSON() : null; + } + + async findOneBy(filter: QueryFilterDto) { + const event = await this.eventModel + .findOne(filter) + .populate('account') + .exec(); + + return event ? event.toJSON() : null; + } + + async update(id: string, data: UpdateEventDto) { + const event = await this.eventModel + .findOneAndUpdate({ _id: id }, data) + .exec(); + + return event ? event.toJSON() : null; + } + + async remove(id: string) { + const event = await this.eventModel.findOneAndDelete({ _id: id }).exec(); + + return event ? event.toJSON() : null; + } +} diff --git a/packages/event/data-source/src/lib/services/index.ts b/packages/event/data-source/src/lib/services/index.ts new file mode 100644 index 00000000..163bac30 --- /dev/null +++ b/packages/event/data-source/src/lib/services/index.ts @@ -0,0 +1 @@ +export * from './events.impl'; diff --git a/packages/event/data-source/tsconfig.json b/packages/event/data-source/tsconfig.json new file mode 100644 index 00000000..1faeabf7 --- /dev/null +++ b/packages/event/data-source/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "strictPropertyInitialization": false + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/event/data-source/tsconfig.lib.json b/packages/event/data-source/tsconfig.lib.json new file mode 100644 index 00000000..4befa7f0 --- /dev/null +++ b/packages/event/data-source/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/event/data-source/tsconfig.spec.json b/packages/event/data-source/tsconfig.spec.json new file mode 100644 index 00000000..69a251f3 --- /dev/null +++ b/packages/event/data-source/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/packages/event/domain/.eslintrc.json b/packages/event/domain/.eslintrc.json new file mode 100644 index 00000000..ca1930a1 --- /dev/null +++ b/packages/event/domain/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] + } + ] + } + } + ] +} diff --git a/packages/event/domain/jest.config.ts b/packages/event/domain/jest.config.ts new file mode 100644 index 00000000..7361a021 --- /dev/null +++ b/packages/event/domain/jest.config.ts @@ -0,0 +1,9 @@ +export default { + displayName: 'event-domain', + preset: '../../../jest.preset.js', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/packages/event/domain', +}; diff --git a/packages/event/domain/package.json b/packages/event/domain/package.json new file mode 100644 index 00000000..d7c68016 --- /dev/null +++ b/packages/event/domain/package.json @@ -0,0 +1,12 @@ +{ + "name": "@devmx/event-domain", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0", + "@devmx/shared-api-interfaces": "0.0.1" + }, + "type": "commonjs", + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/packages/event/domain/project.json b/packages/event/domain/project.json new file mode 100644 index 00000000..1f85499d --- /dev/null +++ b/packages/event/domain/project.json @@ -0,0 +1,23 @@ +{ + "name": "event-domain", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/event/domain/src", + "projectType": "library", + "tags": ["type:domain"], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/packages/event/domain", + "main": "packages/event/domain/src/index.ts", + "tsConfig": "packages/event/domain/tsconfig.lib.json", + "assets": [], + "additionalEntryPoints": [ + "packages/event/domain/src/server.ts" + ], + "generateExportsField": true + } + } + } +} diff --git a/packages/event/domain/src/index.ts b/packages/event/domain/src/index.ts new file mode 100644 index 00000000..7e98bf00 --- /dev/null +++ b/packages/event/domain/src/index.ts @@ -0,0 +1 @@ +export * from './lib/event-domain'; diff --git a/packages/event/domain/src/lib/event-domain.spec.ts b/packages/event/domain/src/lib/event-domain.spec.ts new file mode 100644 index 00000000..6c87cd46 --- /dev/null +++ b/packages/event/domain/src/lib/event-domain.spec.ts @@ -0,0 +1,7 @@ +import { eventDomain } from './event-domain'; + +describe('eventDomain', () => { + it('should work', () => { + expect(eventDomain()).toEqual('event-domain'); + }); +}); diff --git a/packages/event/domain/src/lib/event-domain.ts b/packages/event/domain/src/lib/event-domain.ts new file mode 100644 index 00000000..5e459b59 --- /dev/null +++ b/packages/event/domain/src/lib/event-domain.ts @@ -0,0 +1,3 @@ +export function eventDomain(): string { + return 'event-domain'; +} diff --git a/packages/event/domain/src/server.ts b/packages/event/domain/src/server.ts new file mode 100644 index 00000000..ca39cd0d --- /dev/null +++ b/packages/event/domain/src/server.ts @@ -0,0 +1 @@ +export * from './server/index'; diff --git a/packages/event/domain/src/server/dtos/create-event.ts b/packages/event/domain/src/server/dtos/create-event.ts new file mode 100644 index 00000000..483950cb --- /dev/null +++ b/packages/event/domain/src/server/dtos/create-event.ts @@ -0,0 +1,23 @@ +import { EventFormat } from '@devmx/shared-api-interfaces'; + +export interface CreateEvent { + title: string; + + description: string; + + format: EventFormat; + + date: string; + + time: string; + + cover?: string; + + visible?: boolean; + + address: string; + + city?: string; + + location?: string; +} diff --git a/packages/event/domain/src/server/dtos/index.ts b/packages/event/domain/src/server/dtos/index.ts new file mode 100644 index 00000000..438171d4 --- /dev/null +++ b/packages/event/domain/src/server/dtos/index.ts @@ -0,0 +1,2 @@ +export * from './create-event'; +export * from './update-event'; diff --git a/packages/event/domain/src/server/dtos/update-event.ts b/packages/event/domain/src/server/dtos/update-event.ts new file mode 100644 index 00000000..ecf41e71 --- /dev/null +++ b/packages/event/domain/src/server/dtos/update-event.ts @@ -0,0 +1,5 @@ +import { CreateEvent } from './create-event'; + +export interface UpdateEvent extends CreateEvent { + id: string; +} diff --git a/packages/event/domain/src/server/index.ts b/packages/event/domain/src/server/index.ts new file mode 100644 index 00000000..1f25b2af --- /dev/null +++ b/packages/event/domain/src/server/index.ts @@ -0,0 +1,3 @@ +export * from './dtos'; +export * from './services'; +export * from './use-cases'; diff --git a/packages/event/domain/src/server/services/event.ts b/packages/event/domain/src/server/services/event.ts new file mode 100644 index 00000000..b22e3cad --- /dev/null +++ b/packages/event/domain/src/server/services/event.ts @@ -0,0 +1,21 @@ +import { CreateEvent, UpdateEvent } from '../dtos'; +import { + Page, + Event, + QueryFilter, + QueryParams, +} from '@devmx/shared-api-interfaces'; + +export abstract class EventsService { + abstract create(data: CreateEvent): Promise; + + abstract find(params: QueryParams): Promise>; + + abstract findOne(id: string): Promise; + + abstract findOneBy(filter: QueryFilter): Promise; + + abstract update(id: string, data: UpdateEvent): Promise; + + abstract remove(id: string): Promise; +} diff --git a/packages/event/domain/src/server/services/index.ts b/packages/event/domain/src/server/services/index.ts new file mode 100644 index 00000000..742039d1 --- /dev/null +++ b/packages/event/domain/src/server/services/index.ts @@ -0,0 +1 @@ +export * from './event'; diff --git a/packages/event/domain/src/server/use-cases/find-events.ts b/packages/event/domain/src/server/use-cases/find-events.ts new file mode 100644 index 00000000..52bb545a --- /dev/null +++ b/packages/event/domain/src/server/use-cases/find-events.ts @@ -0,0 +1,42 @@ +import { EventsService } from '../services'; +import { + Event, + Page, + UseCase, + QueryFilter, + QueryParams, +} from '@devmx/shared-api-interfaces'; + +export class FindEventsUseCase + implements UseCase, Page> +{ + constructor(private eventsService: EventsService) {} + + async execute(params: QueryParams) { + const filter: QueryFilter = {}; + + if (params.filter) { + if (params.filter.format) { + filter.format = new RegExp(params.filter.format, 'i'); + } else { + delete params.filter.format; + } + + if (params.filter.title) { + filter.title = new RegExp(params.filter.title, 'i'); + } else { + delete params.filter.title; + } + + if (params.filter.description) { + filter.description = new RegExp(params.filter.description, 'i'); + } else { + delete params.filter.description; + } + } + + params.filter = { ...params.filter, ...filter }; + + return await this.eventsService.find(params); + } +} diff --git a/packages/event/domain/src/server/use-cases/index.ts b/packages/event/domain/src/server/use-cases/index.ts new file mode 100644 index 00000000..7314ef3e --- /dev/null +++ b/packages/event/domain/src/server/use-cases/index.ts @@ -0,0 +1 @@ +export * from './find-events'; diff --git a/packages/event/domain/tsconfig.json b/packages/event/domain/tsconfig.json new file mode 100644 index 00000000..8122543a --- /dev/null +++ b/packages/event/domain/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/event/domain/tsconfig.lib.json b/packages/event/domain/tsconfig.lib.json new file mode 100644 index 00000000..4befa7f0 --- /dev/null +++ b/packages/event/domain/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/event/domain/tsconfig.spec.json b/packages/event/domain/tsconfig.spec.json new file mode 100644 index 00000000..69a251f3 --- /dev/null +++ b/packages/event/domain/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/packages/event/resource/.eslintrc.json b/packages/event/resource/.eslintrc.json new file mode 100644 index 00000000..3456be9b --- /dev/null +++ b/packages/event/resource/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/packages/event/resource/README.md b/packages/event/resource/README.md new file mode 100644 index 00000000..90509fc6 --- /dev/null +++ b/packages/event/resource/README.md @@ -0,0 +1,7 @@ +# event-resource + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test event-resource` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/packages/event/resource/jest.config.ts b/packages/event/resource/jest.config.ts new file mode 100644 index 00000000..5ac658e8 --- /dev/null +++ b/packages/event/resource/jest.config.ts @@ -0,0 +1,11 @@ +export default { + displayName: 'event-resource', + preset: '../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/packages/event/resource', + passWithNoTests: true +}; diff --git a/packages/event/resource/project.json b/packages/event/resource/project.json new file mode 100644 index 00000000..7b704861 --- /dev/null +++ b/packages/event/resource/project.json @@ -0,0 +1,9 @@ +{ + "name": "event-resource", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/event/resource/src", + "projectType": "library", + "tags": ["type:resource"], + "// targets": "to see all targets run: nx show project event-resource --web", + "targets": {} +} diff --git a/packages/event/resource/src/index.ts b/packages/event/resource/src/index.ts new file mode 100644 index 00000000..d5f26bee --- /dev/null +++ b/packages/event/resource/src/index.ts @@ -0,0 +1 @@ +export * from './lib/event-resource.module'; diff --git a/packages/event/resource/src/lib/controllers/events.ts b/packages/event/resource/src/lib/controllers/events.ts new file mode 100644 index 00000000..aae62e50 --- /dev/null +++ b/packages/event/resource/src/lib/controllers/events.ts @@ -0,0 +1,24 @@ +import { ApiPage, QueryParamsDto } from '@devmx/shared-data-source'; +import { EventDto } from 'packages/event/data-source/src/lib/dtos'; +import { exceptionByError } from '@devmx/shared-resource'; +import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; +import { EventsFacade } from '@devmx/event-data-source'; +import { Controller, Get, Query } from '@nestjs/common'; +import { Event } from '@devmx/shared-api-interfaces'; + +@ApiBearerAuth() +@ApiTags('Eventos') +@Controller('events') +export class EventsController { + constructor(private readonly eventsFacade: EventsFacade) {} + + @Get() + @ApiPage(EventDto) + async findAll(@Query() params: QueryParamsDto) { + try { + return await this.eventsFacade.find(params); + } catch (err) { + throw exceptionByError(err); + } + } +} diff --git a/packages/event/resource/src/lib/controllers/index.ts b/packages/event/resource/src/lib/controllers/index.ts new file mode 100644 index 00000000..67f709a0 --- /dev/null +++ b/packages/event/resource/src/lib/controllers/index.ts @@ -0,0 +1 @@ +export * from './events'; diff --git a/packages/event/resource/src/lib/event-database.module.ts b/packages/event/resource/src/lib/event-database.module.ts new file mode 100644 index 00000000..1da38511 --- /dev/null +++ b/packages/event/resource/src/lib/event-database.module.ts @@ -0,0 +1,22 @@ +import { MongooseModule } from '@nestjs/mongoose'; +import { Global, Module } from '@nestjs/common'; +import { + EventSchema, + provideEvents, + EventCollection, +} from '@devmx/event-data-source'; + +@Global() +@Module({ + imports: [ + MongooseModule.forFeature([ + { + name: EventCollection.name, + schema: EventSchema, + }, + ]), + ], + providers: [...provideEvents()], + exports: [...provideEvents()], +}) +export class EventDatabaseModule {} diff --git a/packages/event/resource/src/lib/event-resource.module.ts b/packages/event/resource/src/lib/event-resource.module.ts new file mode 100644 index 00000000..9dc5a630 --- /dev/null +++ b/packages/event/resource/src/lib/event-resource.module.ts @@ -0,0 +1,9 @@ +import { EventDatabaseModule } from './event-database.module'; +import { EventsController } from './controllers'; +import { Module } from '@nestjs/common'; + +@Module({ + imports: [EventDatabaseModule], + controllers: [EventsController], +}) +export class EventResourceModule {} diff --git a/packages/event/resource/tsconfig.json b/packages/event/resource/tsconfig.json new file mode 100644 index 00000000..8122543a --- /dev/null +++ b/packages/event/resource/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/event/resource/tsconfig.lib.json b/packages/event/resource/tsconfig.lib.json new file mode 100644 index 00000000..dbf54fd7 --- /dev/null +++ b/packages/event/resource/tsconfig.lib.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"], + "target": "es2021", + "strictNullChecks": true, + "noImplicitAny": true, + "strictBindCallApply": true, + "forceConsistentCasingInFileNames": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/event/resource/tsconfig.spec.json b/packages/event/resource/tsconfig.spec.json new file mode 100644 index 00000000..69a251f3 --- /dev/null +++ b/packages/event/resource/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/packages/location/resource/src/lib/controllers/locations.ts b/packages/location/resource/src/lib/controllers/locations.ts index 16f27243..92394cbe 100644 --- a/packages/location/resource/src/lib/controllers/locations.ts +++ b/packages/location/resource/src/lib/controllers/locations.ts @@ -8,7 +8,7 @@ import { LocationFilterDto, } from '@devmx/location-data-source'; -@ApiTags('Locations') +@ApiTags('Localizações') @Controller('locations') export class LocationsController { constructor(private citiesFacade: CitiesFacade) {} diff --git a/packages/presentation/resource/src/lib/controllers/presentations.ts b/packages/presentation/resource/src/lib/controllers/presentations.ts index fc87cece..643541c9 100644 --- a/packages/presentation/resource/src/lib/controllers/presentations.ts +++ b/packages/presentation/resource/src/lib/controllers/presentations.ts @@ -57,8 +57,6 @@ export class PresentationsController { try { return await this.presentationsFacade.find(params); } catch (err) { - console.log(err); - throw exceptionByError(err); } } diff --git a/packages/shared/api-interfaces/src/lib/entities/event.ts b/packages/shared/api-interfaces/src/lib/entities/event.ts new file mode 100644 index 00000000..1418d3c4 --- /dev/null +++ b/packages/shared/api-interfaces/src/lib/entities/event.ts @@ -0,0 +1,30 @@ +import { Presentation } from './presentation'; +import { Location } from '../interfaces'; +import { EventFormat } from '../types'; +import { City } from './city'; + +export interface Event { + id: string; + + title: string; + + description: string; + + format: EventFormat; + + date: string; + + time: string; + + cover: string; + + visible: boolean; + + presentations: Presentation[]; + + address: string; + + city?: City; + + location?: Location; +} diff --git a/packages/shared/api-interfaces/src/lib/entities/index.ts b/packages/shared/api-interfaces/src/lib/entities/index.ts index bda83662..7dfb1be3 100644 --- a/packages/shared/api-interfaces/src/lib/entities/index.ts +++ b/packages/shared/api-interfaces/src/lib/entities/index.ts @@ -1,5 +1,6 @@ export * from './account'; export * from './city'; +export * from './event'; export * from './presentation-comment'; export * from './presentation-reaction'; export * from './presentation'; diff --git a/packages/shared/api-interfaces/src/lib/types/event-format.ts b/packages/shared/api-interfaces/src/lib/types/event-format.ts new file mode 100644 index 00000000..add8cf1b --- /dev/null +++ b/packages/shared/api-interfaces/src/lib/types/event-format.ts @@ -0,0 +1 @@ +export type EventFormat = 'in-person' | 'online' | 'mixed'; diff --git a/packages/shared/api-interfaces/src/lib/types/index.ts b/packages/shared/api-interfaces/src/lib/types/index.ts index f5b2e761..b281d1be 100644 --- a/packages/shared/api-interfaces/src/lib/types/index.ts +++ b/packages/shared/api-interfaces/src/lib/types/index.ts @@ -3,6 +3,7 @@ export * from './abstract'; export * from './account-role'; export * from './creatable'; export * from './editable'; +export * from './event-format'; export * from './find-filter'; export * from './findable'; export * from './fn'; diff --git a/tsconfig.base.json b/tsconfig.base.json index 4639ed4c..1c91c5fb 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -37,6 +37,10 @@ "packages/account/feature-shell/src/index.ts" ], "@devmx/account-resource": ["packages/account/resource/src/index.ts"], + "@devmx/event-data-source": ["packages/event/data-source/src/index.ts"], + "@devmx/event-domain": ["packages/event/domain/src/index.ts"], + "@devmx/event-domain/server": ["packages/event/domain/src/server.ts"], + "@devmx/event-resource": ["packages/event/resource/src/index.ts"], "@devmx/location-data-access": [ "packages/location/data-access/src/index.ts" ], @@ -44,12 +48,12 @@ "packages/location/data-source/src/index.ts" ], "@devmx/location-domain": ["packages/location/domain/src/index.ts"], - "@devmx/location-domain/server": [ - "packages/location/domain/src/server.ts" - ], "@devmx/location-domain/client": [ "packages/location/domain/src/client.ts" ], + "@devmx/location-domain/server": [ + "packages/location/domain/src/server.ts" + ], "@devmx/location-resource": ["packages/location/resource/src/index.ts"], "@devmx/location-ui-forms": ["packages/location/ui-forms/src/index.ts"], "@devmx/presentation-data-access": [ From 73907e2cec35f782d30e35b18d0c4011e1aa3973 Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Mon, 30 Sep 2024 16:40:36 -0300 Subject: [PATCH 02/11] feat: crud event server --- packages/event/data-access/.eslintrc.json | 30 +++++++++++++++ packages/event/data-access/jest.config.ts | 9 +++++ packages/event/data-access/package.json | 11 ++++++ packages/event/data-access/project.json | 19 ++++++++++ packages/event/data-access/src/index.ts | 1 + .../src/lib/event-data-access.spec.ts | 7 ++++ .../data-access/src/lib/event-data-access.ts | 3 ++ .../src/lib/services/event.impl.ts | 32 ++++++++++++++++ packages/event/data-access/tsconfig.json | 22 +++++++++++ packages/event/data-access/tsconfig.lib.json | 10 +++++ packages/event/data-access/tsconfig.spec.json | 14 +++++++ .../data-source/src/lib/dtos/update-event.ts | 4 +- .../data-source/src/lib/event-providers.ts | 19 ++++++++-- .../data-source/src/lib/facades/events.ts | 38 +++++++++++++++++-- .../data-source/src/lib/providers/facades.ts | 16 +++++++- .../src/lib/providers/use-cases.ts | 25 +++++++++++- packages/event/domain/project.json | 3 +- packages/event/domain/src/client.ts | 1 + packages/event/domain/src/client/index.ts | 2 + .../event/domain/src/client/services/event.ts | 20 ++++++++++ .../event/domain/src/client/services/index.ts | 1 + .../src/client/use-cases/find-events.ts | 19 ++++++++++ .../domain/src/client/use-cases/index.ts | 1 + .../domain/src/server/dtos/update-event.ts | 2 +- .../src/server/use-cases/create-event.ts | 11 ++++++ .../src/server/use-cases/find-event-by-id.ts | 19 ++++++++++ .../domain/src/server/use-cases/index.ts | 4 ++ .../src/server/use-cases/remove-event.ts | 17 +++++++++ .../src/server/use-cases/update-event.ts | 26 +++++++++++++ .../api-interfaces/src/lib/dtos/event-out.ts | 30 +++++++++++++++ .../api-interfaces/src/lib/dtos/index.ts | 1 + tsconfig.base.json | 2 + 32 files changed, 406 insertions(+), 13 deletions(-) create mode 100644 packages/event/data-access/.eslintrc.json create mode 100644 packages/event/data-access/jest.config.ts create mode 100644 packages/event/data-access/package.json create mode 100644 packages/event/data-access/project.json create mode 100644 packages/event/data-access/src/index.ts create mode 100644 packages/event/data-access/src/lib/event-data-access.spec.ts create mode 100644 packages/event/data-access/src/lib/event-data-access.ts create mode 100644 packages/event/data-access/src/lib/services/event.impl.ts create mode 100644 packages/event/data-access/tsconfig.json create mode 100644 packages/event/data-access/tsconfig.lib.json create mode 100644 packages/event/data-access/tsconfig.spec.json create mode 100644 packages/event/domain/src/client.ts create mode 100644 packages/event/domain/src/client/index.ts create mode 100644 packages/event/domain/src/client/services/event.ts create mode 100644 packages/event/domain/src/client/services/index.ts create mode 100644 packages/event/domain/src/client/use-cases/find-events.ts create mode 100644 packages/event/domain/src/client/use-cases/index.ts create mode 100644 packages/event/domain/src/server/use-cases/create-event.ts create mode 100644 packages/event/domain/src/server/use-cases/find-event-by-id.ts create mode 100644 packages/event/domain/src/server/use-cases/remove-event.ts create mode 100644 packages/event/domain/src/server/use-cases/update-event.ts create mode 100644 packages/shared/api-interfaces/src/lib/dtos/event-out.ts diff --git a/packages/event/data-access/.eslintrc.json b/packages/event/data-access/.eslintrc.json new file mode 100644 index 00000000..ca1930a1 --- /dev/null +++ b/packages/event/data-access/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.json"], + "parser": "jsonc-eslint-parser", + "rules": { + "@nx/dependency-checks": [ + "error", + { + "ignoredFiles": ["{projectRoot}/eslint.config.{js,cjs,mjs}"] + } + ] + } + } + ] +} diff --git a/packages/event/data-access/jest.config.ts b/packages/event/data-access/jest.config.ts new file mode 100644 index 00000000..87173882 --- /dev/null +++ b/packages/event/data-access/jest.config.ts @@ -0,0 +1,9 @@ +export default { + displayName: 'event-data-access', + preset: '../../../jest.preset.js', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/packages/event/data-access', +}; diff --git a/packages/event/data-access/package.json b/packages/event/data-access/package.json new file mode 100644 index 00000000..a63d8442 --- /dev/null +++ b/packages/event/data-access/package.json @@ -0,0 +1,11 @@ +{ + "name": "@devmx/event-data-access", + "version": "0.0.1", + "dependencies": { + "tslib": "^2.3.0" + }, + "type": "commonjs", + "main": "./src/index.js", + "typings": "./src/index.d.ts", + "private": true +} diff --git a/packages/event/data-access/project.json b/packages/event/data-access/project.json new file mode 100644 index 00000000..23be0889 --- /dev/null +++ b/packages/event/data-access/project.json @@ -0,0 +1,19 @@ +{ + "name": "event-data-access", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/event/data-access/src", + "projectType": "library", + "tags": ["type:data"], + "targets": { + "build": { + "executor": "@nx/js:tsc", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/packages/event/data-access", + "main": "packages/event/data-access/src/index.ts", + "tsConfig": "packages/event/data-access/tsconfig.lib.json", + "assets": [] + } + } + } +} diff --git a/packages/event/data-access/src/index.ts b/packages/event/data-access/src/index.ts new file mode 100644 index 00000000..c6ed3d96 --- /dev/null +++ b/packages/event/data-access/src/index.ts @@ -0,0 +1 @@ +export * from './lib/event-data-access'; diff --git a/packages/event/data-access/src/lib/event-data-access.spec.ts b/packages/event/data-access/src/lib/event-data-access.spec.ts new file mode 100644 index 00000000..5ed9d2d4 --- /dev/null +++ b/packages/event/data-access/src/lib/event-data-access.spec.ts @@ -0,0 +1,7 @@ +import { eventDataAccess } from './event-data-access'; + +describe('eventDataAccess', () => { + it('should work', () => { + expect(eventDataAccess()).toEqual('event-data-access'); + }); +}); diff --git a/packages/event/data-access/src/lib/event-data-access.ts b/packages/event/data-access/src/lib/event-data-access.ts new file mode 100644 index 00000000..e3fbfc69 --- /dev/null +++ b/packages/event/data-access/src/lib/event-data-access.ts @@ -0,0 +1,3 @@ +export function eventDataAccess(): string { + return 'event-data-access'; +} diff --git a/packages/event/data-access/src/lib/services/event.impl.ts b/packages/event/data-access/src/lib/services/event.impl.ts new file mode 100644 index 00000000..60a660f8 --- /dev/null +++ b/packages/event/data-access/src/lib/services/event.impl.ts @@ -0,0 +1,32 @@ +import { EventOut, Page } from '@devmx/shared-api-interfaces'; +import { Env } from '@devmx/shared-api-interfaces/client'; +import { HttpClient } from '@devmx/shared-data-access'; + +export class EventServiceImpl { + get url() { + return `${this.env.api.url}/events`; + } + + constructor(private http: HttpClient, private env: Env) {} + + find(params: URLSearchParams) { + const url = [this.url, params.toString()]; + return this.http.get>(url.join('?')); + } + + findOne(id: string) { + return this.http.get(`${this.url}/${id}`); + } + + create(data: Event) { + return this.http.post(this.url, data); + } + + update(id: string, data: Event) { + return this.http.patch(`${this.url}/${id}`, data); + } + + remove(id: string) { + return this.http.delete(`${this.url}/${id}`); + } +} diff --git a/packages/event/data-access/tsconfig.json b/packages/event/data-access/tsconfig.json new file mode 100644 index 00000000..8122543a --- /dev/null +++ b/packages/event/data-access/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/packages/event/data-access/tsconfig.lib.json b/packages/event/data-access/tsconfig.lib.json new file mode 100644 index 00000000..4befa7f0 --- /dev/null +++ b/packages/event/data-access/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/packages/event/data-access/tsconfig.spec.json b/packages/event/data-access/tsconfig.spec.json new file mode 100644 index 00000000..69a251f3 --- /dev/null +++ b/packages/event/data-access/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/packages/event/data-source/src/lib/dtos/update-event.ts b/packages/event/data-source/src/lib/dtos/update-event.ts index 2cbc8280..565ce535 100644 --- a/packages/event/data-source/src/lib/dtos/update-event.ts +++ b/packages/event/data-source/src/lib/dtos/update-event.ts @@ -1,4 +1,6 @@ import { CreateEventDto } from './create-event'; import { PartialType } from '@nestjs/mapped-types'; -export class UpdateEventDto extends PartialType(CreateEventDto) {} +export class UpdateEventDto extends PartialType(CreateEventDto) { + id: string +} diff --git a/packages/event/data-source/src/lib/event-providers.ts b/packages/event/data-source/src/lib/event-providers.ts index e4b8d43f..f9ed6590 100644 --- a/packages/event/data-source/src/lib/event-providers.ts +++ b/packages/event/data-source/src/lib/event-providers.ts @@ -1,12 +1,23 @@ -import { provideEventsFacade, provideEventsService } from "./providers"; -import { provideFindEventsUseCase } from "./providers/use-cases"; +import { + provideEventsFacade, + provideEventsService, + provideCreateEventUseCase, + provideFindEventByIDUseCase, + provideFindEventsUseCase, + provideRemoveEventUseCase, + provideUpdateEventUseCase, +} from './providers'; export function provideEvents() { return [ provideEventsService(), + provideCreateEventUseCase(), provideFindEventsUseCase(), + provideFindEventByIDUseCase(), + provideUpdateEventUseCase(), + provideRemoveEventUseCase(), - provideEventsFacade() - ] + provideEventsFacade(), + ]; } diff --git a/packages/event/data-source/src/lib/facades/events.ts b/packages/event/data-source/src/lib/facades/events.ts index 9868eea1..9aba4e55 100644 --- a/packages/event/data-source/src/lib/facades/events.ts +++ b/packages/event/data-source/src/lib/facades/events.ts @@ -1,11 +1,28 @@ import { PageDto, QueryParamsDto } from '@devmx/shared-data-source'; -import { FindEventsUseCase } from '@devmx/event-domain/server'; +import { + CreateEventUseCase, + FindEventByIDUseCase, + FindEventsUseCase, + RemoveEventUseCase, + UpdateEventUseCase, +} from '@devmx/event-domain/server'; import { Event } from '@devmx/shared-api-interfaces'; import { plainToInstance } from 'class-transformer'; -import { EventDto } from '../dtos'; +import { CreateEventDto, EventDto, UpdateEventDto } from '../dtos'; export class EventsFacade { - constructor(private findEventsUseCase: FindEventsUseCase) {} + constructor( + private createEventUseCase: CreateEventUseCase, + private findEventsUseCase: FindEventsUseCase, + private findEventByIDUseCase: FindEventByIDUseCase, + private updateEventUseCase: UpdateEventUseCase, + private removeEventUseCase: RemoveEventUseCase + ) {} + + async create(data: CreateEventDto) { + const presentation = await this.createEventUseCase.execute(data); + return plainToInstance(EventDto, presentation); + } async find(params: QueryParamsDto) { params.filter = { ...params.filter, visible: true }; @@ -13,4 +30,19 @@ export class EventsFacade { const presentations = plainToInstance(EventDto, data); return new PageDto(presentations, items, pages); } + + async findOne(id: string) { + const presentation = await this.findEventByIDUseCase.execute(id); + return plainToInstance(EventDto, presentation); + } + + async update(id: string, data: UpdateEventDto) { + const presentation = await this.updateEventUseCase.execute({ ...data, id }); + return plainToInstance(EventDto, presentation); + } + + async remove(id: string) { + const presentation = this.removeEventUseCase.execute(id); + return plainToInstance(EventDto, presentation); + } } diff --git a/packages/event/data-source/src/lib/providers/facades.ts b/packages/event/data-source/src/lib/providers/facades.ts index 244754a9..4345a2cb 100644 --- a/packages/event/data-source/src/lib/providers/facades.ts +++ b/packages/event/data-source/src/lib/providers/facades.ts @@ -1,7 +1,19 @@ import { createServerProvider } from '@devmx/shared-data-source'; import { EventsFacade } from '../facades'; -import { FindEventsUseCase } from '@devmx/event-domain/server'; +import { + CreateEventUseCase, + FindEventByIDUseCase, + FindEventsUseCase, + RemoveEventUseCase, + UpdateEventUseCase, +} from '@devmx/event-domain/server'; export function provideEventsFacade() { - return createServerProvider(EventsFacade, [FindEventsUseCase]); + return createServerProvider(EventsFacade, [ + CreateEventUseCase, + FindEventsUseCase, + FindEventByIDUseCase, + UpdateEventUseCase, + RemoveEventUseCase, + ]); } diff --git a/packages/event/data-source/src/lib/providers/use-cases.ts b/packages/event/data-source/src/lib/providers/use-cases.ts index 9be7b6dd..244aa219 100644 --- a/packages/event/data-source/src/lib/providers/use-cases.ts +++ b/packages/event/data-source/src/lib/providers/use-cases.ts @@ -1,6 +1,29 @@ -import { EventsService, FindEventsUseCase } from '@devmx/event-domain/server'; +import { + CreateEventUseCase, + EventsService, + FindEventByIDUseCase, + FindEventsUseCase, + RemoveEventUseCase, + UpdateEventUseCase, +} from '@devmx/event-domain/server'; import { createUseCaseProvider } from '@devmx/shared-data-source'; +export function provideCreateEventUseCase() { + return createUseCaseProvider(CreateEventUseCase, [EventsService]); +} + export function provideFindEventsUseCase() { return createUseCaseProvider(FindEventsUseCase, [EventsService]); } + +export function provideFindEventByIDUseCase() { + return createUseCaseProvider(FindEventByIDUseCase, [EventsService]); +} + +export function provideUpdateEventUseCase() { + return createUseCaseProvider(UpdateEventUseCase, [EventsService]); +} + +export function provideRemoveEventUseCase() { + return createUseCaseProvider(RemoveEventUseCase, [EventsService]); +} diff --git a/packages/event/domain/project.json b/packages/event/domain/project.json index 1f85499d..00259d2b 100644 --- a/packages/event/domain/project.json +++ b/packages/event/domain/project.json @@ -14,7 +14,8 @@ "tsConfig": "packages/event/domain/tsconfig.lib.json", "assets": [], "additionalEntryPoints": [ - "packages/event/domain/src/server.ts" + "packages/event/domain/src/server.ts", + "packages/event/domain/src/client.ts" ], "generateExportsField": true } diff --git a/packages/event/domain/src/client.ts b/packages/event/domain/src/client.ts new file mode 100644 index 00000000..bdd02c04 --- /dev/null +++ b/packages/event/domain/src/client.ts @@ -0,0 +1 @@ +export * from './client/index' diff --git a/packages/event/domain/src/client/index.ts b/packages/event/domain/src/client/index.ts new file mode 100644 index 00000000..3087244d --- /dev/null +++ b/packages/event/domain/src/client/index.ts @@ -0,0 +1,2 @@ +export * from './services'; +export * from './use-cases'; diff --git a/packages/event/domain/src/client/services/event.ts b/packages/event/domain/src/client/services/event.ts new file mode 100644 index 00000000..b5fa7add --- /dev/null +++ b/packages/event/domain/src/client/services/event.ts @@ -0,0 +1,20 @@ +import { Observable } from 'rxjs'; +import { + Page, + Event, + EventOut, + QueryParams, +} from '@devmx/shared-api-interfaces'; + +// prettier-ignore +export abstract class EventService { + abstract find(params: QueryParams): Observable>; + + abstract findOne(id: string): Observable + + abstract create(presentation: Event): Observable; + + abstract update(id: string, presentation: Event): Observable; + + abstract remove(id: string): Observable +} diff --git a/packages/event/domain/src/client/services/index.ts b/packages/event/domain/src/client/services/index.ts new file mode 100644 index 00000000..742039d1 --- /dev/null +++ b/packages/event/domain/src/client/services/index.ts @@ -0,0 +1 @@ +export * from './event'; diff --git a/packages/event/domain/src/client/use-cases/find-events.ts b/packages/event/domain/src/client/use-cases/find-events.ts new file mode 100644 index 00000000..865bc1b9 --- /dev/null +++ b/packages/event/domain/src/client/use-cases/find-events.ts @@ -0,0 +1,19 @@ +import { createQueryParams } from '@devmx/shared-util-data'; +import { EventService } from '../services'; +import { + Page, + Event, + UseCase, + EventOut, + QueryParams, +} from '@devmx/shared-api-interfaces'; + +export class FindEventsUseCase + implements UseCase, Page> +{ + constructor(private eventService: EventService) {} + + execute(params: QueryParams) { + return this.eventService.find(createQueryParams(params)); + } +} diff --git a/packages/event/domain/src/client/use-cases/index.ts b/packages/event/domain/src/client/use-cases/index.ts new file mode 100644 index 00000000..7314ef3e --- /dev/null +++ b/packages/event/domain/src/client/use-cases/index.ts @@ -0,0 +1 @@ +export * from './find-events'; diff --git a/packages/event/domain/src/server/dtos/update-event.ts b/packages/event/domain/src/server/dtos/update-event.ts index ecf41e71..2a1b1f15 100644 --- a/packages/event/domain/src/server/dtos/update-event.ts +++ b/packages/event/domain/src/server/dtos/update-event.ts @@ -1,5 +1,5 @@ import { CreateEvent } from './create-event'; -export interface UpdateEvent extends CreateEvent { +export interface UpdateEvent extends Partial { id: string; } diff --git a/packages/event/domain/src/server/use-cases/create-event.ts b/packages/event/domain/src/server/use-cases/create-event.ts new file mode 100644 index 00000000..c454715b --- /dev/null +++ b/packages/event/domain/src/server/use-cases/create-event.ts @@ -0,0 +1,11 @@ +import { Event, UseCase } from '@devmx/shared-api-interfaces'; +import { EventsService } from '../services'; +import { CreateEvent } from '../dtos'; + +export class CreateEventUseCase implements UseCase { + constructor(private readonly eventsService: EventsService) {} + + execute(data: CreateEvent) { + return this.eventsService.create(data); + } +} diff --git a/packages/event/domain/src/server/use-cases/find-event-by-id.ts b/packages/event/domain/src/server/use-cases/find-event-by-id.ts new file mode 100644 index 00000000..190b444d --- /dev/null +++ b/packages/event/domain/src/server/use-cases/find-event-by-id.ts @@ -0,0 +1,19 @@ +import { Event, UseCase } from '@devmx/shared-api-interfaces'; +import { EventsService } from '../services'; +import { NotFoundError } from '@devmx/shared-util-errors'; + +export class FindEventByIDUseCase + implements UseCase +{ + constructor(private eventsService: EventsService) {} + + async execute(id: string) { + const event = await this.eventsService.findOne(id); + + if (!event) { + throw new NotFoundError(`Evento não encontrado`); + } + + return event; + } +} diff --git a/packages/event/domain/src/server/use-cases/index.ts b/packages/event/domain/src/server/use-cases/index.ts index 7314ef3e..08725c93 100644 --- a/packages/event/domain/src/server/use-cases/index.ts +++ b/packages/event/domain/src/server/use-cases/index.ts @@ -1 +1,5 @@ +export * from './create-event'; +export * from './find-event-by-id'; export * from './find-events'; +export * from './remove-event'; +export * from './update-event'; diff --git a/packages/event/domain/src/server/use-cases/remove-event.ts b/packages/event/domain/src/server/use-cases/remove-event.ts new file mode 100644 index 00000000..9d36cdfd --- /dev/null +++ b/packages/event/domain/src/server/use-cases/remove-event.ts @@ -0,0 +1,17 @@ +import { Event, UseCase } from '@devmx/shared-api-interfaces'; +import { PersistenceError } from '@devmx/shared-util-errors'; +import { EventsService } from '../services'; + +export class RemoveEventUseCase implements UseCase { + constructor(private eventsService: EventsService) {} + + async execute(id: string) { + const removed = await this.eventsService.remove(id); + + if (!removed) { + throw new PersistenceError(`Algo deu errado ao remover evento`); + } + + return removed; + } +} diff --git a/packages/event/domain/src/server/use-cases/update-event.ts b/packages/event/domain/src/server/use-cases/update-event.ts new file mode 100644 index 00000000..cb4f9e45 --- /dev/null +++ b/packages/event/domain/src/server/use-cases/update-event.ts @@ -0,0 +1,26 @@ +import { NotFoundError, PersistenceError } from '@devmx/shared-util-errors'; +import { Event, UseCase } from '@devmx/shared-api-interfaces'; +import { EventsService } from '../services'; +import { UpdateEvent } from '../dtos'; + +export class UpdateEventUseCase implements UseCase { + constructor(private eventsService: EventsService) {} + + async execute(data: UpdateEvent) { + const event = await this.eventsService.findOne(data.id); + + if (!event) { + throw new NotFoundError(`Evento não encontrado`); + } + + const updated = await this.eventsService.update(data.id, data); + + if (!updated) { + throw new PersistenceError( + `Algo deu errado ao persistir os dados do evento` + ); + } + + return updated; + } +} diff --git a/packages/shared/api-interfaces/src/lib/dtos/event-out.ts b/packages/shared/api-interfaces/src/lib/dtos/event-out.ts new file mode 100644 index 00000000..0b8aa0a8 --- /dev/null +++ b/packages/shared/api-interfaces/src/lib/dtos/event-out.ts @@ -0,0 +1,30 @@ +import { PresentationOut } from './presentation-out'; +import { Location } from '../interfaces'; +import { EventFormat } from '../types'; +import { City } from '../entities'; + +export interface EventOut { + id: string; + + title: string; + + description: string; + + format: EventFormat; + + date: string; + + time: string; + + cover: string; + + visible: boolean; + + presentations: PresentationOut[]; + + address: string; + + city?: City; + + location?: Location; +} diff --git a/packages/shared/api-interfaces/src/lib/dtos/index.ts b/packages/shared/api-interfaces/src/lib/dtos/index.ts index 271979ea..e5dfcc63 100644 --- a/packages/shared/api-interfaces/src/lib/dtos/index.ts +++ b/packages/shared/api-interfaces/src/lib/dtos/index.ts @@ -1,5 +1,6 @@ export * from './access-token'; export * from './account-out'; +export * from './event-out'; export * from './presentation-comment-out'; export * from './presentation-out'; export * from './sign-in'; diff --git a/tsconfig.base.json b/tsconfig.base.json index 1c91c5fb..0c9e8375 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -37,9 +37,11 @@ "packages/account/feature-shell/src/index.ts" ], "@devmx/account-resource": ["packages/account/resource/src/index.ts"], + "@devmx/event-data-access": ["packages/event/data-access/src/index.ts"], "@devmx/event-data-source": ["packages/event/data-source/src/index.ts"], "@devmx/event-domain": ["packages/event/domain/src/index.ts"], "@devmx/event-domain/server": ["packages/event/domain/src/server.ts"], + "@devmx/event-domain/client": ["packages/event/domain/src/client.ts"], "@devmx/event-resource": ["packages/event/resource/src/index.ts"], "@devmx/location-data-access": [ "packages/location/data-access/src/index.ts" From 85bedca8a17320a581de6a7fe71b243270896c41 Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Mon, 30 Sep 2024 17:07:48 -0300 Subject: [PATCH 03/11] feat: event data-access --- packages/event/data-access/jest.config.ts | 1 + packages/event/data-access/src/index.ts | 4 +- .../data-access/src/lib/dtos/filter-event.ts | 6 ++ .../event/data-access/src/lib/dtos/index.ts | 1 + .../src/lib/event-data-access.spec.ts | 7 -- .../data-access/src/lib/event-data-access.ts | 3 - .../data-access/src/lib/event.providers.ts | 23 +++++ .../data-access/src/lib/facades/event.ts | 87 +++++++++++++++++++ .../data-access/src/lib/facades/index.ts | 1 + .../data-access/src/lib/providers/facades.ts | 19 ++++ .../data-access/src/lib/providers/index.ts | 3 + .../data-access/src/lib/providers/services.ts | 14 +++ .../src/lib/providers/use-cases.ts | 29 +++++++ .../src/lib/services/event.impl.ts | 8 +- .../data-access/src/lib/services/index.ts | 1 + .../event/domain/src/client/services/event.ts | 5 +- .../src/client/use-cases/create-event.ts | 11 +++ .../src/client/use-cases/find-event-by-id.ts | 12 +++ .../domain/src/client/use-cases/index.ts | 4 + .../src/client/use-cases/remove-event.ts | 12 +++ .../src/client/use-cases/update-event.ts | 11 +++ packages/event/domain/src/index.ts | 2 +- .../src/{server => lib}/dtos/create-event.ts | 0 .../domain/src/{server => lib}/dtos/index.ts | 0 .../src/{server => lib}/dtos/update-event.ts | 0 packages/event/domain/src/server/index.ts | 1 - .../event/domain/src/server/services/event.ts | 2 +- .../src/server/use-cases/create-event.ts | 2 +- 28 files changed, 249 insertions(+), 20 deletions(-) create mode 100644 packages/event/data-access/src/lib/dtos/filter-event.ts create mode 100644 packages/event/data-access/src/lib/dtos/index.ts delete mode 100644 packages/event/data-access/src/lib/event-data-access.spec.ts delete mode 100644 packages/event/data-access/src/lib/event-data-access.ts create mode 100644 packages/event/data-access/src/lib/event.providers.ts create mode 100644 packages/event/data-access/src/lib/facades/event.ts create mode 100644 packages/event/data-access/src/lib/facades/index.ts create mode 100644 packages/event/data-access/src/lib/providers/facades.ts create mode 100644 packages/event/data-access/src/lib/providers/index.ts create mode 100644 packages/event/data-access/src/lib/providers/services.ts create mode 100644 packages/event/data-access/src/lib/providers/use-cases.ts create mode 100644 packages/event/data-access/src/lib/services/index.ts create mode 100644 packages/event/domain/src/client/use-cases/create-event.ts create mode 100644 packages/event/domain/src/client/use-cases/find-event-by-id.ts create mode 100644 packages/event/domain/src/client/use-cases/remove-event.ts create mode 100644 packages/event/domain/src/client/use-cases/update-event.ts rename packages/event/domain/src/{server => lib}/dtos/create-event.ts (100%) rename packages/event/domain/src/{server => lib}/dtos/index.ts (100%) rename packages/event/domain/src/{server => lib}/dtos/update-event.ts (100%) diff --git a/packages/event/data-access/jest.config.ts b/packages/event/data-access/jest.config.ts index 87173882..0da24003 100644 --- a/packages/event/data-access/jest.config.ts +++ b/packages/event/data-access/jest.config.ts @@ -6,4 +6,5 @@ export default { }, moduleFileExtensions: ['ts', 'js', 'html'], coverageDirectory: '../../../coverage/packages/event/data-access', + passWithNoTests: true }; diff --git a/packages/event/data-access/src/index.ts b/packages/event/data-access/src/index.ts index c6ed3d96..46f091cf 100644 --- a/packages/event/data-access/src/index.ts +++ b/packages/event/data-access/src/index.ts @@ -1 +1,3 @@ -export * from './lib/event-data-access'; +export * from './lib/event.providers'; +export * from './lib/facades'; +export * from './lib/dtos'; diff --git a/packages/event/data-access/src/lib/dtos/filter-event.ts b/packages/event/data-access/src/lib/dtos/filter-event.ts new file mode 100644 index 00000000..3e13b254 --- /dev/null +++ b/packages/event/data-access/src/lib/dtos/filter-event.ts @@ -0,0 +1,6 @@ +import { EventFormat } from '@devmx/shared-api-interfaces'; + +export interface FilterEvent { + format: EventFormat | ''; + title: string; +} diff --git a/packages/event/data-access/src/lib/dtos/index.ts b/packages/event/data-access/src/lib/dtos/index.ts new file mode 100644 index 00000000..1f8c7cb4 --- /dev/null +++ b/packages/event/data-access/src/lib/dtos/index.ts @@ -0,0 +1 @@ +export * from './filter-event'; diff --git a/packages/event/data-access/src/lib/event-data-access.spec.ts b/packages/event/data-access/src/lib/event-data-access.spec.ts deleted file mode 100644 index 5ed9d2d4..00000000 --- a/packages/event/data-access/src/lib/event-data-access.spec.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { eventDataAccess } from './event-data-access'; - -describe('eventDataAccess', () => { - it('should work', () => { - expect(eventDataAccess()).toEqual('event-data-access'); - }); -}); diff --git a/packages/event/data-access/src/lib/event-data-access.ts b/packages/event/data-access/src/lib/event-data-access.ts deleted file mode 100644 index e3fbfc69..00000000 --- a/packages/event/data-access/src/lib/event-data-access.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function eventDataAccess(): string { - return 'event-data-access'; -} diff --git a/packages/event/data-access/src/lib/event.providers.ts b/packages/event/data-access/src/lib/event.providers.ts new file mode 100644 index 00000000..0a0c2a62 --- /dev/null +++ b/packages/event/data-access/src/lib/event.providers.ts @@ -0,0 +1,23 @@ +import { + provideEventService, + provideCreateEventUseCase, + provideFindEventByIDUseCase, + provideFindEventsUseCase, + provideRemoveEventUseCase, + provideUpdateEventUseCase, + provideEventFacade, +} from './providers'; + +export function provideEvent() { + return [ + provideEventService(), + + provideCreateEventUseCase(), + provideFindEventsUseCase(), + provideFindEventByIDUseCase(), + provideUpdateEventUseCase(), + provideRemoveEventUseCase(), + + provideEventFacade(), + ]; +} diff --git a/packages/event/data-access/src/lib/facades/event.ts b/packages/event/data-access/src/lib/facades/event.ts new file mode 100644 index 00000000..8e9e1270 --- /dev/null +++ b/packages/event/data-access/src/lib/facades/event.ts @@ -0,0 +1,87 @@ +import { CreateEvent, UpdateEvent } from '@devmx/event-domain'; +import { EventOut, Page } from '@devmx/shared-api-interfaces'; +import { State } from '@devmx/shared-data-access'; +import { FilterEvent } from '../dtos'; +import { take } from 'rxjs'; +import { + CreateEventUseCase, + FindEventByIDUseCase, + FindEventsUseCase, + RemoveEventUseCase, + UpdateEventUseCase, +} from '@devmx/event-domain/client'; + +interface EventState { + events: Page; + event: EventOut | null; + filter: FilterEvent; +} + +export class EventFacade extends State { + events$ = this.select((state) => state.events); + + event$ = this.select((state) => state.event); + + constructor( + private createEventUseCase: CreateEventUseCase, + private findEventsUseCase: FindEventsUseCase, + private findEventByIDUseCase: FindEventByIDUseCase, + private updateEventUseCase: UpdateEventUseCase, + private removeEventUseCase: RemoveEventUseCase + ) { + super({ + events: { data: [], items: 0, pages: 0 }, + filter: { title: '', format: '' }, + event: null, + }); + } + + setFilter(filter: FilterEvent) { + this.setState({ filter }); + } + + clearFilter() { + this.setState({ filter: { format: '', title: '' } }); + } + + load(page = 0, size = 10) { + const filter = this.state.filter; + const params = { filter, page, size }; + + const request$ = this.findEventsUseCase.execute(params); + + const onEvents = (events: Page) => { + this.setState({ events }); + }; + + request$.pipe(take(1)).subscribe(onEvents); + } + + loadOne(id: string) { + const request$ = this.findEventByIDUseCase.execute(id); + + const onEvent = (event: EventOut) => { + this.setState({ event }); + }; + + request$.pipe(take(1)).subscribe(onEvent); + } + + create(data: CreateEvent) { + const request$ = this.createEventUseCase.execute(data); + + request$.pipe(take(1)).subscribe(({ id }) => this.loadOne(id)); + } + + update(data: UpdateEvent) { + const request$ = this.updateEventUseCase.execute(data); + + request$.pipe(take(1)).subscribe(() => this.load()); + } + + remove(id: string) { + const request$ = this.removeEventUseCase.execute(id); + + request$.pipe(take(1)).subscribe(() => this.load()); + } +} diff --git a/packages/event/data-access/src/lib/facades/index.ts b/packages/event/data-access/src/lib/facades/index.ts new file mode 100644 index 00000000..742039d1 --- /dev/null +++ b/packages/event/data-access/src/lib/facades/index.ts @@ -0,0 +1 @@ +export * from './event'; diff --git a/packages/event/data-access/src/lib/providers/facades.ts b/packages/event/data-access/src/lib/providers/facades.ts new file mode 100644 index 00000000..9ed61959 --- /dev/null +++ b/packages/event/data-access/src/lib/providers/facades.ts @@ -0,0 +1,19 @@ +import { createClientProvider } from '@devmx/shared-data-access'; +import { EventFacade } from '../facades'; +import { + CreateEventUseCase, + FindEventByIDUseCase, + FindEventsUseCase, + RemoveEventUseCase, + UpdateEventUseCase, +} from '@devmx/event-domain/client'; + +export function provideEventFacade() { + return createClientProvider(EventFacade, [ + CreateEventUseCase, + FindEventsUseCase, + FindEventByIDUseCase, + UpdateEventUseCase, + RemoveEventUseCase, + ]); +} diff --git a/packages/event/data-access/src/lib/providers/index.ts b/packages/event/data-access/src/lib/providers/index.ts new file mode 100644 index 00000000..f95ea038 --- /dev/null +++ b/packages/event/data-access/src/lib/providers/index.ts @@ -0,0 +1,3 @@ +export * from './facades'; +export * from './services'; +export * from './use-cases'; diff --git a/packages/event/data-access/src/lib/providers/services.ts b/packages/event/data-access/src/lib/providers/services.ts new file mode 100644 index 00000000..a2c5e7bf --- /dev/null +++ b/packages/event/data-access/src/lib/providers/services.ts @@ -0,0 +1,14 @@ +import { EventService } from '@devmx/event-domain/client'; +import { Env } from '@devmx/shared-api-interfaces/client'; +import { HttpClient } from '@devmx/shared-data-access'; +import { EventServiceImpl } from '../services'; + +export function provideEventService() { + return { + provide: EventService, + useFactory(http: HttpClient, env: Env) { + return new EventServiceImpl(http, env); + }, + deps: [HttpClient, Env], + }; +} diff --git a/packages/event/data-access/src/lib/providers/use-cases.ts b/packages/event/data-access/src/lib/providers/use-cases.ts new file mode 100644 index 00000000..efddde4b --- /dev/null +++ b/packages/event/data-access/src/lib/providers/use-cases.ts @@ -0,0 +1,29 @@ +import { + EventService, + CreateEventUseCase, + FindEventByIDUseCase, + FindEventsUseCase, + RemoveEventUseCase, + UpdateEventUseCase, +} from '@devmx/event-domain/client'; +import { createUseCaseProvider } from '@devmx/shared-data-access'; + +export function provideCreateEventUseCase() { + return createUseCaseProvider(CreateEventUseCase, [EventService]); +} + +export function provideFindEventsUseCase() { + return createUseCaseProvider(FindEventsUseCase, [EventService]); +} + +export function provideFindEventByIDUseCase() { + return createUseCaseProvider(FindEventByIDUseCase, [EventService]); +} + +export function provideUpdateEventUseCase() { + return createUseCaseProvider(UpdateEventUseCase, [EventService]); +} + +export function provideRemoveEventUseCase() { + return createUseCaseProvider(RemoveEventUseCase, [EventService]); +} diff --git a/packages/event/data-access/src/lib/services/event.impl.ts b/packages/event/data-access/src/lib/services/event.impl.ts index 60a660f8..6bac2fac 100644 --- a/packages/event/data-access/src/lib/services/event.impl.ts +++ b/packages/event/data-access/src/lib/services/event.impl.ts @@ -1,8 +1,10 @@ +import { CreateEvent, UpdateEvent } from '@devmx/event-domain'; import { EventOut, Page } from '@devmx/shared-api-interfaces'; +import { EventService } from '@devmx/event-domain/client'; import { Env } from '@devmx/shared-api-interfaces/client'; import { HttpClient } from '@devmx/shared-data-access'; -export class EventServiceImpl { +export class EventServiceImpl implements EventService { get url() { return `${this.env.api.url}/events`; } @@ -18,11 +20,11 @@ export class EventServiceImpl { return this.http.get(`${this.url}/${id}`); } - create(data: Event) { + create(data: CreateEvent) { return this.http.post(this.url, data); } - update(id: string, data: Event) { + update(id: string, data: UpdateEvent) { return this.http.patch(`${this.url}/${id}`, data); } diff --git a/packages/event/data-access/src/lib/services/index.ts b/packages/event/data-access/src/lib/services/index.ts new file mode 100644 index 00000000..4790abba --- /dev/null +++ b/packages/event/data-access/src/lib/services/index.ts @@ -0,0 +1 @@ +export * from './event.impl'; diff --git a/packages/event/domain/src/client/services/event.ts b/packages/event/domain/src/client/services/event.ts index b5fa7add..3fc34027 100644 --- a/packages/event/domain/src/client/services/event.ts +++ b/packages/event/domain/src/client/services/event.ts @@ -1,3 +1,4 @@ +import { CreateEvent, UpdateEvent } from '../../lib/dtos'; import { Observable } from 'rxjs'; import { Page, @@ -12,9 +13,9 @@ export abstract class EventService { abstract findOne(id: string): Observable - abstract create(presentation: Event): Observable; + abstract create(data: CreateEvent): Observable; - abstract update(id: string, presentation: Event): Observable; + abstract update(id: string, data: UpdateEvent): Observable; abstract remove(id: string): Observable } diff --git a/packages/event/domain/src/client/use-cases/create-event.ts b/packages/event/domain/src/client/use-cases/create-event.ts new file mode 100644 index 00000000..d2c0fe85 --- /dev/null +++ b/packages/event/domain/src/client/use-cases/create-event.ts @@ -0,0 +1,11 @@ +import { UseCase, EventOut } from '@devmx/shared-api-interfaces'; +import { CreateEvent } from '../../lib/dtos'; +import { EventService } from '../services'; + +export class CreateEventUseCase implements UseCase { + constructor(private eventService: EventService) {} + + execute(data: CreateEvent) { + return this.eventService.create(data); + } +} diff --git a/packages/event/domain/src/client/use-cases/find-event-by-id.ts b/packages/event/domain/src/client/use-cases/find-event-by-id.ts new file mode 100644 index 00000000..8dd85fd8 --- /dev/null +++ b/packages/event/domain/src/client/use-cases/find-event-by-id.ts @@ -0,0 +1,12 @@ +import { UseCase, EventOut } from '@devmx/shared-api-interfaces'; +import { EventService } from '../services'; + +export class FindEventByIDUseCase + implements UseCase +{ + constructor(private eventService: EventService) {} + + execute(id: string) { + return this.eventService.findOne(id); + } +} diff --git a/packages/event/domain/src/client/use-cases/index.ts b/packages/event/domain/src/client/use-cases/index.ts index 7314ef3e..08725c93 100644 --- a/packages/event/domain/src/client/use-cases/index.ts +++ b/packages/event/domain/src/client/use-cases/index.ts @@ -1 +1,5 @@ +export * from './create-event'; +export * from './find-event-by-id'; export * from './find-events'; +export * from './remove-event'; +export * from './update-event'; diff --git a/packages/event/domain/src/client/use-cases/remove-event.ts b/packages/event/domain/src/client/use-cases/remove-event.ts new file mode 100644 index 00000000..ecffb07d --- /dev/null +++ b/packages/event/domain/src/client/use-cases/remove-event.ts @@ -0,0 +1,12 @@ +import { UseCase, EventOut } from '@devmx/shared-api-interfaces'; +import { EventService } from '../services'; + +export class RemoveEventUseCase + implements UseCase +{ + constructor(private eventService: EventService) {} + + execute(id: string) { + return this.eventService.remove(id); + } +} diff --git a/packages/event/domain/src/client/use-cases/update-event.ts b/packages/event/domain/src/client/use-cases/update-event.ts new file mode 100644 index 00000000..b5e2bf76 --- /dev/null +++ b/packages/event/domain/src/client/use-cases/update-event.ts @@ -0,0 +1,11 @@ +import { UseCase, EventOut } from '@devmx/shared-api-interfaces'; +import { UpdateEvent } from '../../lib/dtos'; +import { EventService } from '../services'; + +export class UpdateEventUseCase implements UseCase { + constructor(private eventService: EventService) {} + + execute(data: UpdateEvent) { + return this.eventService.update(data.id, data); + } +} diff --git a/packages/event/domain/src/index.ts b/packages/event/domain/src/index.ts index 7e98bf00..d1ec7982 100644 --- a/packages/event/domain/src/index.ts +++ b/packages/event/domain/src/index.ts @@ -1 +1 @@ -export * from './lib/event-domain'; +export * from './lib/dtos'; diff --git a/packages/event/domain/src/server/dtos/create-event.ts b/packages/event/domain/src/lib/dtos/create-event.ts similarity index 100% rename from packages/event/domain/src/server/dtos/create-event.ts rename to packages/event/domain/src/lib/dtos/create-event.ts diff --git a/packages/event/domain/src/server/dtos/index.ts b/packages/event/domain/src/lib/dtos/index.ts similarity index 100% rename from packages/event/domain/src/server/dtos/index.ts rename to packages/event/domain/src/lib/dtos/index.ts diff --git a/packages/event/domain/src/server/dtos/update-event.ts b/packages/event/domain/src/lib/dtos/update-event.ts similarity index 100% rename from packages/event/domain/src/server/dtos/update-event.ts rename to packages/event/domain/src/lib/dtos/update-event.ts diff --git a/packages/event/domain/src/server/index.ts b/packages/event/domain/src/server/index.ts index 1f25b2af..3087244d 100644 --- a/packages/event/domain/src/server/index.ts +++ b/packages/event/domain/src/server/index.ts @@ -1,3 +1,2 @@ -export * from './dtos'; export * from './services'; export * from './use-cases'; diff --git a/packages/event/domain/src/server/services/event.ts b/packages/event/domain/src/server/services/event.ts index b22e3cad..55e73618 100644 --- a/packages/event/domain/src/server/services/event.ts +++ b/packages/event/domain/src/server/services/event.ts @@ -1,4 +1,4 @@ -import { CreateEvent, UpdateEvent } from '../dtos'; +import { CreateEvent, UpdateEvent } from '../../lib/dtos'; import { Page, Event, diff --git a/packages/event/domain/src/server/use-cases/create-event.ts b/packages/event/domain/src/server/use-cases/create-event.ts index c454715b..72b7669c 100644 --- a/packages/event/domain/src/server/use-cases/create-event.ts +++ b/packages/event/domain/src/server/use-cases/create-event.ts @@ -1,6 +1,6 @@ import { Event, UseCase } from '@devmx/shared-api-interfaces'; import { EventsService } from '../services'; -import { CreateEvent } from '../dtos'; +import { CreateEvent } from '../../lib/dtos'; export class CreateEventUseCase implements UseCase { constructor(private readonly eventsService: EventsService) {} From 3ca8a023405af20eeb1d35ba405861de1ffea637 Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Mon, 30 Sep 2024 19:05:11 -0300 Subject: [PATCH 04/11] feat: add event feature shell --- apps/devmx/src/app/app.routes.ts | 9 ++- .../src/server/use-cases/update-event.ts | 2 +- packages/event/feature-shell/.eslintrc.json | 42 +++++++++++ packages/event/feature-shell/README.md | 7 ++ packages/event/feature-shell/jest.config.ts | 21 ++++++ packages/event/feature-shell/project.json | 20 +++++ packages/event/feature-shell/src/index.ts | 3 + .../filter-event/filter-event.component.html | 16 ++++ .../filter-event/filter-event.component.scss | 13 ++++ .../filter-event/filter-event.component.ts | 44 +++++++++++ .../feature-shell/src/lib/components/index.ts | 1 + .../containers/events/events.container.html | 35 +++++++++ .../containers/events/events.container.scss | 48 ++++++++++++ .../lib/containers/events/events.container.ts | 48 ++++++++++++ .../feature-shell/src/lib/containers/index.ts | 1 + .../lib/event-feature-shell.component.html | 16 ++++ .../lib/event-feature-shell.component.scss | 48 ++++++++++++ .../lib/event-feature-shell.component.spec.ts | 21 ++++++ .../src/lib/event-feature-shell.component.ts | 74 +++++++++++++++++++ .../src/lib/event-feature-shell.routes.ts | 19 +++++ .../src/lib/forms/filter-event.ts | 24 ++++++ .../feature-shell/src/lib/forms/index.ts | 1 + .../event/feature-shell/src/test-setup.ts | 8 ++ packages/event/feature-shell/tsconfig.json | 28 +++++++ .../event/feature-shell/tsconfig.lib.json | 17 +++++ .../event/feature-shell/tsconfig.spec.json | 16 ++++ tsconfig.base.json | 5 +- 27 files changed, 584 insertions(+), 3 deletions(-) create mode 100644 packages/event/feature-shell/.eslintrc.json create mode 100644 packages/event/feature-shell/README.md create mode 100644 packages/event/feature-shell/jest.config.ts create mode 100644 packages/event/feature-shell/project.json create mode 100644 packages/event/feature-shell/src/index.ts create mode 100644 packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.html create mode 100644 packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.scss create mode 100644 packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.ts create mode 100644 packages/event/feature-shell/src/lib/components/index.ts create mode 100644 packages/event/feature-shell/src/lib/containers/events/events.container.html create mode 100644 packages/event/feature-shell/src/lib/containers/events/events.container.scss create mode 100644 packages/event/feature-shell/src/lib/containers/events/events.container.ts create mode 100644 packages/event/feature-shell/src/lib/containers/index.ts create mode 100644 packages/event/feature-shell/src/lib/event-feature-shell.component.html create mode 100644 packages/event/feature-shell/src/lib/event-feature-shell.component.scss create mode 100644 packages/event/feature-shell/src/lib/event-feature-shell.component.spec.ts create mode 100644 packages/event/feature-shell/src/lib/event-feature-shell.component.ts create mode 100644 packages/event/feature-shell/src/lib/event-feature-shell.routes.ts create mode 100644 packages/event/feature-shell/src/lib/forms/filter-event.ts create mode 100644 packages/event/feature-shell/src/lib/forms/index.ts create mode 100644 packages/event/feature-shell/src/test-setup.ts create mode 100644 packages/event/feature-shell/tsconfig.json create mode 100644 packages/event/feature-shell/tsconfig.lib.json create mode 100644 packages/event/feature-shell/tsconfig.spec.json diff --git a/apps/devmx/src/app/app.routes.ts b/apps/devmx/src/app/app.routes.ts index 4044c0fe..cffb514a 100644 --- a/apps/devmx/src/app/app.routes.ts +++ b/apps/devmx/src/app/app.routes.ts @@ -1,6 +1,13 @@ import { Route } from '@angular/router'; export const appRoutes: Route[] = [ + { + path: 'events', + loadChildren: () => + import('@devmx/event-feature-shell').then( + (m) => m.eventFeatureShellRoutes + ), + }, { path: 'presentations', loadChildren: () => @@ -18,6 +25,6 @@ export const appRoutes: Route[] = [ { path: '', pathMatch: 'prefix', - redirectTo: 'presentations', + redirectTo: 'events', }, ]; diff --git a/packages/event/domain/src/server/use-cases/update-event.ts b/packages/event/domain/src/server/use-cases/update-event.ts index cb4f9e45..d65213a1 100644 --- a/packages/event/domain/src/server/use-cases/update-event.ts +++ b/packages/event/domain/src/server/use-cases/update-event.ts @@ -1,7 +1,7 @@ import { NotFoundError, PersistenceError } from '@devmx/shared-util-errors'; import { Event, UseCase } from '@devmx/shared-api-interfaces'; import { EventsService } from '../services'; -import { UpdateEvent } from '../dtos'; +import { UpdateEvent } from '../../lib/dtos'; export class UpdateEventUseCase implements UseCase { constructor(private eventsService: EventsService) {} diff --git a/packages/event/feature-shell/.eslintrc.json b/packages/event/feature-shell/.eslintrc.json new file mode 100644 index 00000000..a4ccf5d0 --- /dev/null +++ b/packages/event/feature-shell/.eslintrc.json @@ -0,0 +1,42 @@ +{ + "extends": ["../../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "devmx", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "devmx", + "style": "kebab-case" + } + ], + "@angular-eslint/component-class-suffix": [ + "error", + { + "suffixes": ["Component", "Container"] + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nx/angular-template"], + "rules": {} + } + ] +} diff --git a/packages/event/feature-shell/README.md b/packages/event/feature-shell/README.md new file mode 100644 index 00000000..6c39cfb5 --- /dev/null +++ b/packages/event/feature-shell/README.md @@ -0,0 +1,7 @@ +# event-feature-shell + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test event-feature-shell` to execute the unit tests. diff --git a/packages/event/feature-shell/jest.config.ts b/packages/event/feature-shell/jest.config.ts new file mode 100644 index 00000000..50c3e4db --- /dev/null +++ b/packages/event/feature-shell/jest.config.ts @@ -0,0 +1,21 @@ +export default { + displayName: 'event-feature-shell', + preset: '../../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], + coverageDirectory: '../../../coverage/packages/event/feature-shell', + transform: { + '^.+\\.(ts|mjs|js|html)$': [ + 'jest-preset-angular', + { + tsconfig: '/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + }, + ], + }, + transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], + snapshotSerializers: [ + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', + ], +}; diff --git a/packages/event/feature-shell/project.json b/packages/event/feature-shell/project.json new file mode 100644 index 00000000..c306509b --- /dev/null +++ b/packages/event/feature-shell/project.json @@ -0,0 +1,20 @@ +{ + "name": "event-feature-shell", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/event/feature-shell/src", + "prefix": "devmx", + "projectType": "library", + "tags": ["type:feature"], + "targets": { + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "packages/event/feature-shell/jest.config.ts" + } + }, + "lint": { + "executor": "@nx/eslint:lint" + } + } +} diff --git a/packages/event/feature-shell/src/index.ts b/packages/event/feature-shell/src/index.ts new file mode 100644 index 00000000..0f2e629c --- /dev/null +++ b/packages/event/feature-shell/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/event-feature-shell.routes'; + +export * from './lib/event-feature-shell.component'; diff --git a/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.html b/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.html new file mode 100644 index 00000000..5356e8ec --- /dev/null +++ b/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.html @@ -0,0 +1,16 @@ +
+ + Filtrar + search + + + + + Formato + + @for (format of form.formats; track format) { + {{ format.viewValue }} + } + + +
diff --git a/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.scss b/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.scss new file mode 100644 index 00000000..03ee643b --- /dev/null +++ b/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.scss @@ -0,0 +1,13 @@ +:host { + display: flex; + + form { + display: flex; + flex-flow: row wrap; + gap: 1.2em; + + .event-format-field { + width: 16em; + } + } +} diff --git a/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.ts b/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.ts new file mode 100644 index 00000000..2de93587 --- /dev/null +++ b/packages/event/feature-shell/src/lib/components/filter-event/filter-event.component.ts @@ -0,0 +1,44 @@ +import { Component, DestroyRef, inject, OnInit, output } from '@angular/core'; +import { FilterEvent } from '@devmx/event-data-access'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; +import { MatButtonModule } from '@angular/material/button'; +import { MatSelectModule } from '@angular/material/select'; +import { MatInputModule } from '@angular/material/input'; +import { MatIconModule } from '@angular/material/icon'; +import { ReactiveFormsModule } from '@angular/forms'; +import { FilterEventForm } from '../../forms'; +import { debounceTime } from 'rxjs'; + +@Component({ + selector: 'devmx-filter-event', + templateUrl: './filter-event.component.html', + styleUrl: './filter-event.component.scss', + imports: [ + ReactiveFormsModule, + MatFormFieldModule, + MatSelectModule, + MatInputModule, + MatIconModule, + MatButtonModule, + ], + standalone: true, +}) +export class FilterEventComponent implements OnInit { + #destroyRef = inject(DestroyRef); + + form = new FilterEventForm(); + + valueChange = output(); + + ngOnInit() { + const valueChange$ = this.form.valueChanges.pipe( + takeUntilDestroyed(this.#destroyRef), + debounceTime(300) + ); + + valueChange$.subscribe(() => { + this.valueChange.emit(this.form.getRawValue()); + }); + } +} diff --git a/packages/event/feature-shell/src/lib/components/index.ts b/packages/event/feature-shell/src/lib/components/index.ts new file mode 100644 index 00000000..84907ea2 --- /dev/null +++ b/packages/event/feature-shell/src/lib/components/index.ts @@ -0,0 +1 @@ +export * from './filter-event/filter-event.component'; 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 new file mode 100644 index 00000000..eeb43f1e --- /dev/null +++ b/packages/event/feature-shell/src/lib/containers/events/events.container.html @@ -0,0 +1,35 @@ +
+ +
+ +@if (eventFacade.events$ | async; as events) { + + + +
+ +
+} diff --git a/packages/event/feature-shell/src/lib/containers/events/events.container.scss b/packages/event/feature-shell/src/lib/containers/events/events.container.scss new file mode 100644 index 00000000..ab38cd6c --- /dev/null +++ b/packages/event/feature-shell/src/lib/containers/events/events.container.scss @@ -0,0 +1,48 @@ +@use '@angular/material' as mat; + +:host { + flex: 1; + display: flex; + flex-direction: column; + + .events-header { + padding: 1em; + display: flex; + justify-content: flex-end; + } + + .events-container { + display: grid; + gap: 1em; /* Espaçamento entre os itens */ + padding: 1em; + } + + .event-card { + @include mat.elevation-transition(); + @include mat.elevation(2); + + &:active, + &:hover { + @include mat.elevation(6); + } + } + + /* Estilo para dispositivos médios: 2 colunas */ + @media (min-width: 768px) { + .events-container { + grid-template-columns: repeat(2, 1fr); /* 2 colunas */ + } + } + + /* Estilo para dispositivos pequenos: 1 coluna */ + @media (max-width: 767px) { + .events-container { + grid-template-columns: 1fr; /* 1 coluna */ + } + } + + .events-footer { + display: flex; + justify-content: center; + } +} 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 new file mode 100644 index 00000000..8fa3320f --- /dev/null +++ b/packages/event/feature-shell/src/lib/containers/events/events.container.ts @@ -0,0 +1,48 @@ +import { MatPaginatorModule, PageEvent } from '@angular/material/paginator'; +import { EventFacade, FilterEvent } from '@devmx/event-data-access'; +import { MatButtonModule } from '@angular/material/button'; +import { FilterEventComponent } from '../../components'; +import { MatCardModule } from '@angular/material/card'; +import { MatIconModule } from '@angular/material/icon'; +import { RouterLink } from '@angular/router'; +import { AsyncPipe, DatePipe } from '@angular/common'; +import { + inject, + OnInit, + Component, + ChangeDetectionStrategy, +} from '@angular/core'; + +@Component({ + selector: 'devmx-events', + templateUrl: './events.container.html', + styleUrl: './events.container.scss', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + MatCardModule, + MatIconModule, + MatButtonModule, + MatPaginatorModule, + FilterEventComponent, + RouterLink, + AsyncPipe, + DatePipe + ], + standalone: true, +}) +export class EventsContainer implements OnInit { + eventFacade = inject(EventFacade); + + ngOnInit() { + this.eventFacade.load(); + } + + find(filter: FilterEvent) { + this.eventFacade.setFilter(filter); + this.eventFacade.load(); + } + + onPageChange(event: PageEvent) { + this.eventFacade.load(event.pageIndex, event.pageSize); + } +} diff --git a/packages/event/feature-shell/src/lib/containers/index.ts b/packages/event/feature-shell/src/lib/containers/index.ts new file mode 100644 index 00000000..21652978 --- /dev/null +++ b/packages/event/feature-shell/src/lib/containers/index.ts @@ -0,0 +1 @@ +export * from './events/events.container'; diff --git a/packages/event/feature-shell/src/lib/event-feature-shell.component.html b/packages/event/feature-shell/src/lib/event-feature-shell.component.html new file mode 100644 index 00000000..3e4ce202 --- /dev/null +++ b/packages/event/feature-shell/src/lib/event-feature-shell.component.html @@ -0,0 +1,16 @@ +
+ @if (authFacade.user$ | async; as user) { + + + + } + + + + + + +
diff --git a/packages/event/feature-shell/src/lib/event-feature-shell.component.scss b/packages/event/feature-shell/src/lib/event-feature-shell.component.scss new file mode 100644 index 00000000..ca453f72 --- /dev/null +++ b/packages/event/feature-shell/src/lib/event-feature-shell.component.scss @@ -0,0 +1,48 @@ +:host { + flex: 1; + display: flex; + flex-direction: column; + + .event-container { + display: flex; + flex-direction: column; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + } + + .event-is-mobile .event-toolbar { + position: fixed; + /* Make sure the toolbar will stay on top of the content as it scrolls past. */ + z-index: 2; + } + + h1.event-app-name { + margin-left: 8px; + } + + .event-sidenav-container { + /* When the sidenav is not fixed, stretch the sidenav container to fill the available space. This + causes `` to act as our scrolling element for desktop layouts. */ + flex: 1; + } + + .event-sidenav-start { + width: 16em; + } + + .event-content { + flex: 1; + display: flex; + flex-direction: column; + padding: 0 1em; + } + + .event-is-mobile .event-sidenav-container { + /* When the sidenav is fixed, don't constrain the height of the sidenav container. This allows the + `` to be our scrolling element for mobile layouts. */ + flex: 1 0 auto; + } +} diff --git a/packages/event/feature-shell/src/lib/event-feature-shell.component.spec.ts b/packages/event/feature-shell/src/lib/event-feature-shell.component.spec.ts new file mode 100644 index 00000000..27c726c1 --- /dev/null +++ b/packages/event/feature-shell/src/lib/event-feature-shell.component.spec.ts @@ -0,0 +1,21 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { EventFeatureShellComponent } from './event-feature-shell.component'; + +describe('EventFeatureShellComponent', () => { + let component: EventFeatureShellComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [EventFeatureShellComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(EventFeatureShellComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/packages/event/feature-shell/src/lib/event-feature-shell.component.ts b/packages/event/feature-shell/src/lib/event-feature-shell.component.ts new file mode 100644 index 00000000..f3199e7e --- /dev/null +++ b/packages/event/feature-shell/src/lib/event-feature-shell.component.ts @@ -0,0 +1,74 @@ +import { AuthUserComponent, ToolbarComponent } from '@devmx/shared-ui-global'; +import { EventFacade } from '@devmx/event-data-access'; +import { LayoutModule, MediaMatcher } from '@angular/cdk/layout'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatButtonModule } from '@angular/material/button'; +import { AuthFacade } from '@devmx/account-data-access'; +import { MatIconModule } from '@angular/material/icon'; +import { MatListModule } from '@angular/material/list'; +import { Router, RouterModule } from '@angular/router'; +import { AsyncPipe } from '@angular/common'; +import { + inject, + OnInit, + Component, + OnDestroy, + ChangeDetectorRef, + ChangeDetectionStrategy, +} from '@angular/core'; + +@Component({ + selector: 'devmx-event-feature-shell', + templateUrl: './event-feature-shell.component.html', + styleUrl: './event-feature-shell.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + ToolbarComponent, + AuthUserComponent, + MatButtonModule, + MatIconModule, + MatSidenavModule, + MatListModule, + LayoutModule, + RouterModule, + AsyncPipe, + ], + standalone: true, +}) +export class EventFeatureShellComponent implements OnInit, OnDestroy { + authFacade = inject(AuthFacade); + router = inject(Router); + + mobileQuery: MediaQueryList; + + #mobileQueryListener: () => void; + + eventFacade = inject(EventFacade); + + constructor() { + const changeDetectorRef = inject(ChangeDetectorRef); + const media = inject(MediaMatcher); + + this.mobileQuery = media.matchMedia('(max-width: 600px)'); + this.#mobileQueryListener = () => changeDetectorRef.detectChanges(); + if (this.mobileQuery.addEventListener) { + this.mobileQuery.addEventListener('change', this.#mobileQueryListener); + } + } + + ngOnInit() { + this.authFacade.loadAuthUser(); + } + + + onLogout() { + this.authFacade.signOut(); + this.router.navigateByUrl('/account/auth'); + } + + ngOnDestroy() { + if (this.mobileQuery.removeEventListener) { + this.mobileQuery.removeEventListener('change', this.#mobileQueryListener); + } + } +} diff --git a/packages/event/feature-shell/src/lib/event-feature-shell.routes.ts b/packages/event/feature-shell/src/lib/event-feature-shell.routes.ts new file mode 100644 index 00000000..0b858bc9 --- /dev/null +++ b/packages/event/feature-shell/src/lib/event-feature-shell.routes.ts @@ -0,0 +1,19 @@ +import { EventFeatureShellComponent } from './event-feature-shell.component'; +import { provideAccount } from '@devmx/account-data-access'; +import { provideEvent } from '@devmx/event-data-access'; +import { EventsContainer } from './containers'; +import { Route } from '@angular/router'; + +export const eventFeatureShellRoutes: Route[] = [ + { + path: '', + providers: [...provideEvent(), ...provideAccount()], + component: EventFeatureShellComponent, + children: [ + { + path: '', + component: EventsContainer, + }, + ], + }, +]; diff --git a/packages/event/feature-shell/src/lib/forms/filter-event.ts b/packages/event/feature-shell/src/lib/forms/filter-event.ts new file mode 100644 index 00000000..8f8863a8 --- /dev/null +++ b/packages/event/feature-shell/src/lib/forms/filter-event.ts @@ -0,0 +1,24 @@ +import { FormOption, TypedForm } from '@devmx/shared-ui-global'; +import { EventFormat } from '@devmx/shared-api-interfaces'; +import { FormControl, FormGroup } from '@angular/forms'; +import { FilterEvent } from '@devmx/event-data-access'; + +export class FilterEventForm extends FormGroup> { + formats: FormOption[] = [ + { value: '', viewValue: 'Todos' }, + { value: 'in-person', viewValue: 'Presencial' }, + { value: 'online', viewValue: 'Online' }, + { value: 'mixed', viewValue: 'Híbrido' }, + ]; + + constructor() { + super({ + format: new FormControl('', { + nonNullable: true, + }), + title: new FormControl('', { + nonNullable: true, + }), + }); + } +} diff --git a/packages/event/feature-shell/src/lib/forms/index.ts b/packages/event/feature-shell/src/lib/forms/index.ts new file mode 100644 index 00000000..1f8c7cb4 --- /dev/null +++ b/packages/event/feature-shell/src/lib/forms/index.ts @@ -0,0 +1 @@ +export * from './filter-event'; diff --git a/packages/event/feature-shell/src/test-setup.ts b/packages/event/feature-shell/src/test-setup.ts new file mode 100644 index 00000000..ab1eeeb3 --- /dev/null +++ b/packages/event/feature-shell/src/test-setup.ts @@ -0,0 +1,8 @@ +// @ts-expect-error https://thymikee.github.io/jest-preset-angular/docs/getting-started/test-environment +globalThis.ngJest = { + testEnvironmentOptions: { + errorOnUnknownElements: true, + errorOnUnknownProperties: true, + }, +}; +import 'jest-preset-angular/setup-jest'; diff --git a/packages/event/feature-shell/tsconfig.json b/packages/event/feature-shell/tsconfig.json new file mode 100644 index 00000000..fde35eab --- /dev/null +++ b/packages/event/feature-shell/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "es2022", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "extends": "../../../tsconfig.base.json", + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/packages/event/feature-shell/tsconfig.lib.json b/packages/event/feature-shell/tsconfig.lib.json new file mode 100644 index 00000000..9b49be75 --- /dev/null +++ b/packages/event/feature-shell/tsconfig.lib.json @@ -0,0 +1,17 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [] + }, + "exclude": [ + "src/**/*.spec.ts", + "src/test-setup.ts", + "jest.config.ts", + "src/**/*.test.ts" + ], + "include": ["src/**/*.ts"] +} diff --git a/packages/event/feature-shell/tsconfig.spec.json b/packages/event/feature-shell/tsconfig.spec.json new file mode 100644 index 00000000..f858ef78 --- /dev/null +++ b/packages/event/feature-shell/tsconfig.spec.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "target": "es2016", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 0c9e8375..ec37c9c2 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -40,8 +40,11 @@ "@devmx/event-data-access": ["packages/event/data-access/src/index.ts"], "@devmx/event-data-source": ["packages/event/data-source/src/index.ts"], "@devmx/event-domain": ["packages/event/domain/src/index.ts"], - "@devmx/event-domain/server": ["packages/event/domain/src/server.ts"], "@devmx/event-domain/client": ["packages/event/domain/src/client.ts"], + "@devmx/event-domain/server": ["packages/event/domain/src/server.ts"], + "@devmx/event-feature-shell": [ + "packages/event/feature-shell/src/index.ts" + ], "@devmx/event-resource": ["packages/event/resource/src/index.ts"], "@devmx/location-data-access": [ "packages/location/data-access/src/index.ts" From 1a1d1a7b418f60aede97cb6032623d942437463f Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Mon, 30 Sep 2024 19:13:09 -0300 Subject: [PATCH 05/11] chore: fix seeds roles --- CONTRIBUTING.md | 91 +++++++++++++++------------- assets/seeds/account-collection.json | 12 ++-- 2 files changed, 55 insertions(+), 48 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index df8d4dc9..8458214c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,7 +33,6 @@ Essas variáveis são usadas no arquivo [docker-compose.yml](./docker-compose.ym > [!IMPORTANT] > Primeiro preencha os valores para `DB_USER`, `DB_PASS`, `JWT_SECRET` no arquivo [.env](./.env), salve e só depois disso execute o docker. - ```sh docker compose up -d ``` @@ -63,7 +62,6 @@ Preparei alguns seeds pra você importar na base de dados, mas primeiro verifiqu > [!NOTE] > Ele é necessário apenas para importar dados iniciais não obrigatórios, como dados de login com permissões distintas e todas as cidades do brasil com latitude e longitude. - Para importar execute, não se esqueça de colocar seu usuário no `--username=seu-user` configurado no [`.env`](./.env). Ao executar, ele irá solicitar a senha que foi configurada no mesmo arquivo. ### Cidades @@ -78,6 +76,19 @@ mongoimport --host=localhost --port=27017 --username= --authenticationDatabase=a mongoimport --host=localhost --port=27017 --username= --authenticationDatabase=admin --db=devparana --collection=accountcollections --file=assets/seeds/account-collection.json ``` +Usuários que serão cadastrados + +| username | password | member | speaker | donor | leader | staff | fellow | manager | director | +| -------- | -------- | :----: | :-----: | :---: | :----: | :---: | :----: | :-----: | :------: | +| member | member | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | +| speaker | speaker | [x] | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | +| donor | donor123 | [x] | [ ] | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | +| leader | leader | [x] | [ ] | [ ] | [x] | [ ] | [ ] | [ ] | [ ] | +| staff | staff123 | [x] | [ ] | [ ] | [ ] | [x] | [ ] | [ ] | [ ] | +| fellow | fellow | [x] | [ ] | [ ] | [ ] | [ ] | [x] | [ ] | [ ] | +| manager | manager | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [x] | [ ] | +| director | director | [x] | [ ] | [ ] | [ ] | [ ] | [ ] | [ ] | [x] | + ## Agora sim! Agora tudo está configurado pra você executar em desenvolvimento, configurei a execução do back-end e front-end no mesmo comando a seguir. @@ -96,14 +107,12 @@ Os commits podem ser feitos em português, mas use inglês para termos técnicos > [!TIP] > Use o comando `pnpm commit`, e apenas responda as perguntas, assim seu commit seguirá a convenção utilizada. - ## Arquitetura Trata-se de responsabilidade e relacionamentos, ou seja, qual a responsabilidade de cada camada e quais camadas podem depender diretamente uma das outras. Esta é uma convenção chamada [enforce module boundaries](https://nx.dev/features/enforce-module-boundaries#enforce-module-boundaries) e quem permite que as regras sejam aplicadas é o [nx](https://nx.dev). ### Responsabilidades e relacionamentos entre tipos de bibliotecas - A tabela a seguir representa a configuração no arquivo [`.eslintrc.json`](.eslintrc.json). | | api | util | domain | data | ui | feature | resource | app | @@ -119,45 +128,43 @@ A tabela a seguir representa a configuração no arquivo [`.eslintrc.json`](.esl Caso tenha interesse em aprofundar neste assunto e descobrir os motivos, recomendo que leia um conteúdo que escrevi ano passado, você pode fazer download através do link [Arquitetura em camadas, uma abordagem sobre responsabilidades e relacionamentos](https://conteudode.dev/pdf/nx). - --- - ``` - .......... - .............. - .................. - ........................ - ............................ - ................................ - .................................... - ........................................ - .................. ................... - ............ ..... ...... .................... - ............ ... ... ...... ...................... - .............. .... ... .... .............. - ........ ..... ..... ..... .... ............... - ........ ...... ....... ..... . .... ......... - ......... .... ...... ....... ....... .... ... ......... - ............. ...... .... ........ ..... ... ............ - ................ ........... ........ ...... ............... - ................ ................. ..... ........ ................ - ................ ................ ......... ................ - ................. .............. ............... ................ - .................. .... ................. ............... - .................... ................. ............ - ........................... ............... ........... - ............................ ....... .......... - .......................... . ............ - ........................ .................... - ...................... ...................... - ................... ................... - ................. ................. - ............... ............... - ............. ............. - ........... ........... - :........ ......... - ...... ...... - .... .... - .. .. + .......... + .............. + .................. + ........................ + ............................ + ................................ + .................................... + ........................................ + .................. ................... + ............ ..... ...... .................... + ............ ... ... ...... ...................... + .............. .... ... .... .............. + ........ ..... ..... ..... .... ............... + ........ ...... ....... ..... . .... ......... + ......... .... ...... ....... ....... .... ... ......... + ............. ...... .... ........ ..... ... ............ + ................ ........... ........ ...... ............... + ................ ................. ..... ........ ................ + ................ ................ ......... ................ + ................. .............. ............... ................ + .................. .... ................. ............... + .................... ................. ............ + ........................... ............... ........... + ............................ ....... .......... + .......................... . ............ + ........................ .................... + ...................... ...................... + ................... ................... + ................. ................. + ............... ............... + ............. ............. + ........... ........... + :........ ......... + ...... ...... + .... .... + .. .. ``` diff --git a/assets/seeds/account-collection.json b/assets/seeds/account-collection.json index d713afe9..99ff8414 100644 --- a/assets/seeds/account-collection.json +++ b/assets/seeds/account-collection.json @@ -1,8 +1,8 @@ {"_id":{"$oid":"66fa1598073adabd63af0680"},"name":{"first":"Member","last":"Paraná"},"username":"member","password":"$2b$10$Tm3kJfirm6dbmYgbUuAWmuzMTByp6163nqf8M0.r.GqOHwahHonNy","email":"member@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"female","photo":"","minibio":"","birthday":"2002-10-10T03:00:00.000Z","active":true,"__v":0} {"_id":{"$oid":"66fa1529073adabd63af0670"},"name":{"first":"Speaker","last":"Paraná"},"username":"speaker","password":"$2b$10$vIGAhmSHgawn2UCp2dvp8eEIg4ZqVN5psF0XltOv5Ok1AvVVVzECC","email":"speaker@devpr.org","roles":{"member":true,"speaker":true,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"male","photo":"","minibio":"","birthday":"1986-12-29T02:00:00.000Z","active":true,"__v":0} -{"_id":{"$oid":"66fa15e5073adabd63af0688"},"name":{"first":"Donor","last":"Paraná"},"username":"donor","password":"$2b$10$gVTbLG4cAkRp2B//hI9G5OPKBazWLVpbTNLspomaJRwORrZ0ZbM8W","email":"donor@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"non-binary","photo":"","minibio":"","birthday":"2004-06-16T03:00:00.000Z","active":true,"__v":0} -{"_id":{"$oid":"66fa1686073adabd63af0690"},"name":{"first":"Leader","last":"Paraná"},"username":"leader","password":"$2b$10$gCQcetNAbiWBzp2KnuQ/juo5wch10sNxHgjYy/ht5bEsvDD0LDL.i","email":"leader@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"gender-fluid","photo":"","minibio":"","birthday":"1997-07-03T03:00:00.000Z","active":true,"__v":0} -{"_id":{"$oid":"66fa16b5073adabd63af0698"},"name":{"first":"Staff","last":"Paraná"},"username":"staff","password":"$2b$10$A0D6enykGCeyqDi20sde9epqfxJqAZGHGZjsqh1RU9BzAc5sOn/Pq","email":"staff@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"agender","photo":"","minibio":"","birthday":"2004-02-18T03:00:00.000Z","active":true,"__v":0} -{"_id":{"$oid":"66fa16d8073adabd63af06a0"},"name":{"first":"Fellow","last":"Paraná"},"username":"fellow","password":"$2b$10$CeZ3Yn3n350lEWi8OoQvIeLXqJMcEHeiCmjalWiWN9quf2/hwEDUG","email":"fellow@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"prefer-not-to-say","photo":"","minibio":"","birthday":"1993-02-09T03:00:00.000Z","active":true,"__v":0} -{"_id":{"$oid":"66fa170c073adabd63af06a8"},"name":{"first":"Manager","last":"Paraná"},"username":"manager","password":"$2b$10$X6ElrWZ5MuUE/RKCM0khaeYm5GSyMavBgDKeJ5xxzJa.Rmo07KVxO","email":"manager@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"male","photo":"","minibio":"","birthday":"1990-09-20T03:00:00.000Z","active":true,"__v":0} -{"_id":{"$oid":"66fa172f073adabd63af06b0"},"name":{"first":"Director","last":"Paraná"},"username":"director","password":"$2b$10$3F83Wt12gNu2PwINiimv..0ao5r6L6WHUzor11cWM0I5hgggavCHy","email":"director@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"male","photo":"","minibio":"","birthday":"1986-12-29T02:00:00.000Z","active":true,"__v":0} +{"_id":{"$oid":"66fa15e5073adabd63af0688"},"name":{"first":"Donor","last":"Paraná"},"username":"donor","password":"$2b$10$gVTbLG4cAkRp2B//hI9G5OPKBazWLVpbTNLspomaJRwORrZ0ZbM8W","email":"donor@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":true,"leader":false,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"non-binary","photo":"","minibio":"","birthday":"2004-06-16T03:00:00.000Z","active":true,"__v":0} +{"_id":{"$oid":"66fa1686073adabd63af0690"},"name":{"first":"Leader","last":"Paraná"},"username":"leader","password":"$2b$10$gCQcetNAbiWBzp2KnuQ/juo5wch10sNxHgjYy/ht5bEsvDD0LDL.i","email":"leader@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":true,"staff":false,"fellow":false,"manager":false,"director":false},"gender":"gender-fluid","photo":"","minibio":"","birthday":"1997-07-03T03:00:00.000Z","active":true,"__v":0} +{"_id":{"$oid":"66fa16b5073adabd63af0698"},"name":{"first":"Staff","last":"Paraná"},"username":"staff","password":"$2b$10$A0D6enykGCeyqDi20sde9epqfxJqAZGHGZjsqh1RU9BzAc5sOn/Pq","email":"staff@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":true,"fellow":false,"manager":false,"director":false},"gender":"agender","photo":"","minibio":"","birthday":"2004-02-18T03:00:00.000Z","active":true,"__v":0} +{"_id":{"$oid":"66fa16d8073adabd63af06a0"},"name":{"first":"Fellow","last":"Paraná"},"username":"fellow","password":"$2b$10$CeZ3Yn3n350lEWi8OoQvIeLXqJMcEHeiCmjalWiWN9quf2/hwEDUG","email":"fellow@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":true,"manager":false,"director":false},"gender":"prefer-not-to-say","photo":"","minibio":"","birthday":"1993-02-09T03:00:00.000Z","active":true,"__v":0} +{"_id":{"$oid":"66fa170c073adabd63af06a8"},"name":{"first":"Manager","last":"Paraná"},"username":"manager","password":"$2b$10$X6ElrWZ5MuUE/RKCM0khaeYm5GSyMavBgDKeJ5xxzJa.Rmo07KVxO","email":"manager@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":true,"director":false},"gender":"male","photo":"","minibio":"","birthday":"1990-09-20T03:00:00.000Z","active":true,"__v":0} +{"_id":{"$oid":"66fa172f073adabd63af06b0"},"name":{"first":"Director","last":"Paraná"},"username":"director","password":"$2b$10$3F83Wt12gNu2PwINiimv..0ao5r6L6WHUzor11cWM0I5hgggavCHy","email":"director@devpr.org","roles":{"member":true,"speaker":false,"neighbor":false,"donor":false,"leader":false,"staff":false,"fellow":false,"manager":false,"director":true},"gender":"male","photo":"","minibio":"","birthday":"1986-12-29T02:00:00.000Z","active":true,"__v":0} From 7e4486a6b5c5a228d6efe87e7950ed4083bce657 Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Mon, 30 Sep 2024 19:14:35 -0300 Subject: [PATCH 06/11] feat(shared-ui-global): add sidenav component --- .../ui-global/src/lib/components/index.ts | 13 +++-- .../components/sidenav/sidenav.component.html | 11 ++++ .../components/sidenav/sidenav.component.scss | 11 ++++ .../components/sidenav/sidenav.component.ts | 19 +++++++ .../components/sidenav/sidenav.provider.ts | 10 ++++ .../src/lib/components/sidenav/sidenav.ts | 50 +++++++++++++++++++ .../components/toolbar/toolbar.component.html | 4 ++ 7 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.html create mode 100644 packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.scss create mode 100644 packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.ts create mode 100644 packages/shared/ui-global/src/lib/components/sidenav/sidenav.provider.ts create mode 100644 packages/shared/ui-global/src/lib/components/sidenav/sidenav.ts diff --git a/packages/shared/ui-global/src/lib/components/index.ts b/packages/shared/ui-global/src/lib/components/index.ts index bf413805..4825e89b 100644 --- a/packages/shared/ui-global/src/lib/components/index.ts +++ b/packages/shared/ui-global/src/lib/components/index.ts @@ -1,8 +1,11 @@ export * from './auth-user/auth-user.component'; -export * from './toolbar/toolbar.component'; -export * from './message/message.component'; -export * from './message/message.service'; export * from './avatar/avatar.component'; -export * from './photo/photo.component'; -export * from './image/image.component'; export * from './file/file.component'; +export * from './image/image.component'; +export * from './message/message.service'; +export * from './message/message.component'; +export * from './photo/photo.component'; +export * from './toolbar/toolbar.component'; +export * from './sidenav/sidenav.component'; +export * from './sidenav/sidenav.provider'; +export * from './sidenav/sidenav'; diff --git a/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.html b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.html new file mode 100644 index 00000000..aadb4dc7 --- /dev/null +++ b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.html @@ -0,0 +1,11 @@ + +

{{ header() }}

+ @for (item of sidenav.itemsByRoles$ | async; track item.path) { + + @if (item.icon) { + {{ item.icon }} + } + {{ item.text }} + + } +
diff --git a/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.scss b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.scss new file mode 100644 index 00000000..6619de04 --- /dev/null +++ b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.scss @@ -0,0 +1,11 @@ +:host { + flex: 1; + display: flex; + flex-direction: column; + + .mat-mdc-subheader { + font-size: 1.2em; + font-weight: 600; + margin: 0 0.8em; + } +} diff --git a/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.ts b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.ts new file mode 100644 index 00000000..59601d0c --- /dev/null +++ b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.component.ts @@ -0,0 +1,19 @@ +import { MatListModule } from '@angular/material/list'; +import { Component, inject, input } from '@angular/core'; +import { MatIconModule } from '@angular/material/icon'; +import { RouterLink } from '@angular/router'; +import { Sidenav } from './sidenav'; +import { AsyncPipe } from '@angular/common'; + +@Component({ + selector: 'devmx-sidenav', + templateUrl: './sidenav.component.html', + styleUrl: './sidenav.component.scss', + imports: [MatListModule, MatIconModule, RouterLink, AsyncPipe], + standalone: true, +}) +export class SidenavComponent { + sidenav = inject(Sidenav); + + header = input(''); +} diff --git a/packages/shared/ui-global/src/lib/components/sidenav/sidenav.provider.ts b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.provider.ts new file mode 100644 index 00000000..c2bc5bb1 --- /dev/null +++ b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.provider.ts @@ -0,0 +1,10 @@ +import { Sidenav, SidenavItem } from './sidenav'; + +export function provideSidenav(items: SidenavItem[]) { + return { + provide: Sidenav, + useFactory() { + return new Sidenav(items); + }, + }; +} diff --git a/packages/shared/ui-global/src/lib/components/sidenav/sidenav.ts b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.ts new file mode 100644 index 00000000..a2dd4ce9 --- /dev/null +++ b/packages/shared/ui-global/src/lib/components/sidenav/sidenav.ts @@ -0,0 +1,50 @@ +import { map, Observable, combineLatest, BehaviorSubject } from 'rxjs'; +import { AccountRole, Role } from '@devmx/shared-api-interfaces'; + +export interface SidenavItem { + path: (string | number)[]; + text: string; + roles: Role[]; + icon?: string; +} + +export class Sidenav { + #items: BehaviorSubject; + + #initialRoles = { + member: false, + speaker: false, + donor: false, + neighbor: false, + leader: false, + staff: false, + fellow: false, + manager: false, + director: false, + }; + + #roles = new BehaviorSubject(this.#initialRoles); + + itemsByRoles$: Observable; + + constructor(items: SidenavItem[] = []) { + this.#items = new BehaviorSubject(items); + + this.itemsByRoles$ = combineLatest([ + this.#items.asObservable(), + this.#roles.asObservable(), + ]).pipe( + map(([items, roles]) => { + return items.filter((item) => item.roles.some((role) => roles[role])); + }) + ); + } + + setRoles(roles: AccountRole) { + this.#roles.next(roles); + } + + resetRoles() { + this.#roles.next(this.#initialRoles); + } +} diff --git a/packages/shared/ui-global/src/lib/components/toolbar/toolbar.component.html b/packages/shared/ui-global/src/lib/components/toolbar/toolbar.component.html index 3fec7600..9fe24d59 100644 --- a/packages/shared/ui-global/src/lib/components/toolbar/toolbar.component.html +++ b/packages/shared/ui-global/src/lib/components/toolbar/toolbar.component.html @@ -11,6 +11,10 @@

{{ subtitle() }}

+ + Eventos + + Apresentações From 76bf7b191189cc25e853135a46bf0ef5635fc746 Mon Sep 17 00:00:00 2001 From: Gui Seek Date: Mon, 30 Sep 2024 19:15:42 -0300 Subject: [PATCH 07/11] fix(account): fix change roles --- packages/account/data-access/src/index.ts | 1 + .../data-access/src/lib/facades/account.ts | 2 +- .../src/lib/interfaces/nav-item.ts | 3 ++ .../src/server/use-cases/change-roles.ts | 22 ++++++++-- .../accounts/accounts.container.html | 2 +- .../accounts/accounts.container.scss | 6 ++- .../containers/accounts/accounts.container.ts | 3 +- .../change-roles/change-roles.dialog.html | 22 +++++++--- .../change-roles/change-roles.dialog.scss | 6 +++ .../change-roles/change-roles.dialog.ts | 5 ++- .../lib/account-feature-shell.component.html | 5 ++- .../lib/account-feature-shell.component.scss | 6 --- .../lib/account-feature-shell.component.ts | 40 +++++++------------ .../src/lib/account-feature-shell.routes.ts | 17 +++++++- .../util-data/src/lib/utils/deep-diff.ts | 26 ++++++++++++ .../shared/util-data/src/lib/utils/index.ts | 1 + 16 files changed, 116 insertions(+), 51 deletions(-) create mode 100644 packages/shared/util-data/src/lib/utils/deep-diff.ts diff --git a/packages/account/data-access/src/index.ts b/packages/account/data-access/src/index.ts index 2c3e41b6..e09c0b2a 100644 --- a/packages/account/data-access/src/index.ts +++ b/packages/account/data-access/src/index.ts @@ -1,4 +1,5 @@ export * from './lib/account.providers'; +export * from './lib/interfaces'; export * from './lib/facades'; export * from './lib/dtos'; diff --git a/packages/account/data-access/src/lib/facades/account.ts b/packages/account/data-access/src/lib/facades/account.ts index 81c90893..7fe12a4a 100644 --- a/packages/account/data-access/src/lib/facades/account.ts +++ b/packages/account/data-access/src/lib/facades/account.ts @@ -141,7 +141,7 @@ export class AccountFacade extends State { changeRoles(data: ChangeRoles) { const request$ = this.changeRolesUseCase.execute(data); - request$.pipe(take(1)).subscribe(() => this.loadOne(data.id)); + request$.pipe(take(1)).subscribe(() => this.load()); } uploadPhoto(photo: Blob) { diff --git a/packages/account/data-access/src/lib/interfaces/nav-item.ts b/packages/account/data-access/src/lib/interfaces/nav-item.ts index 7b905a50..0570aba0 100644 --- a/packages/account/data-access/src/lib/interfaces/nav-item.ts +++ b/packages/account/data-access/src/lib/interfaces/nav-item.ts @@ -1,5 +1,8 @@ +import { Role } from "@devmx/shared-api-interfaces"; + export interface NavItem { path: (string | number)[]; text: string; + roles: Role[] icon?: string; } diff --git a/packages/account/domain/src/server/use-cases/change-roles.ts b/packages/account/domain/src/server/use-cases/change-roles.ts index 54d2e5ab..4f3e9bde 100644 --- a/packages/account/domain/src/server/use-cases/change-roles.ts +++ b/packages/account/domain/src/server/use-cases/change-roles.ts @@ -1,8 +1,12 @@ -import { AccessDeniedError, PersistenceError } from '@devmx/shared-util-errors'; import { Account, UseCase } from '@devmx/shared-api-interfaces'; -import { AccountLevel } from '@devmx/shared-util-data'; +import { AccountLevel, deepDiff } from '@devmx/shared-util-data'; import { ChangeRolesBy } from '../../lib/dtos'; import { AccountsService } from '../services'; +import { + NotFoundError, + PersistenceError, + AccessDeniedError, +} from '@devmx/shared-util-errors'; export class ChangeRolesUseCase implements UseCase { constructor(private accountsService: AccountsService) {} @@ -10,7 +14,17 @@ export class ChangeRolesUseCase implements UseCase { async execute(data: ChangeRolesBy) { const assignerLevel = new AccountLevel(data.assigner); - const assignLevel = new AccountLevel(data.assign); + const account = await this.accountsService.findOne(data.assign.id); + + if (!account) { + throw new NotFoundError('Conta não encontrada'); + } + + const changedRoles = deepDiff(account.roles, data.assign.roles); + + const assign = { id: data.assign.id, roles: changedRoles }; + + const assignLevel = new AccountLevel(assign); if (assignLevel.level > 0 && assignLevel.level > assignerLevel.level) { throw new AccessDeniedError('Permissão insuficiente'); @@ -22,7 +36,7 @@ export class ChangeRolesUseCase implements UseCase { ); if (!changed) { - throw new PersistenceError('Problema ao persistir nova senha'); + throw new PersistenceError('Problema ao persistir novas permissões'); } return changed; diff --git a/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.html b/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.html index a9822cc4..5e5907d4 100644 --- a/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.html +++ b/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.html @@ -23,7 +23,7 @@ diff --git a/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.scss b/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.scss index cb472527..78c99f64 100644 --- a/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.scss +++ b/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.scss @@ -21,6 +21,10 @@ @include mat.elevation-transition(); @include mat.elevation(2); + .mat-mdc-card-title { + font-size: 1.2em; + } + &:active, &:hover { @include mat.elevation(6); @@ -34,7 +38,7 @@ /* Estilo para dispositivos médios: 2 colunas */ @media (min-width: 768px) { .accounts-container { - grid-template-columns: repeat(4, 1fr); /* 2 colunas */ + grid-template-columns: repeat(5, 1fr); /* 2 colunas */ } } diff --git a/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.ts b/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.ts index 7ce10a5e..54348171 100644 --- a/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.ts +++ b/packages/account/feature-admin/src/lib/containers/accounts/accounts.container.ts @@ -59,7 +59,7 @@ export class AccountsContainer implements OnInit { this.accountFacade.load(); } - openRolesSheet(assigner: AuthUser, assign: AccountOut) { + openRoles(assigner: AuthUser, assign: AccountOut) { const changeRoles$ = this.changeRoles .open({ assigner, assign }) .afterClosed(); @@ -67,7 +67,6 @@ export class AccountsContainer implements OnInit { changeRoles$.pipe(take(1)).subscribe((data) => { if (data) { this.accountFacade.changeRoles(data); - this.accountFacade.load(); } }); } diff --git a/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.html b/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.html index 1b188619..90e5006c 100644 --- a/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.html +++ b/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.html @@ -5,15 +5,12 @@

-

Organização

+

Auto atribuíveis

- Organizador(a) - - - Líder + Membro - Fellow + Palestrante
@@ -27,6 +24,19 @@

Apoiador(a)

+ +

Organização

+ + Organizador(a) + + + Líder + + + Fellow + +
+

Conselho

diff --git a/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.scss b/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.scss index f4bf0e08..d1ece5ba 100644 --- a/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.scss +++ b/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.scss @@ -12,6 +12,12 @@ text-overflow: ellipsis; } + .mat-mdc-subheader { + font-size: 1.2em; + font-weight: 600; + margin: 0 0.8em; + } + section { padding: 0 2em; } diff --git a/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.ts b/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.ts index 4616e335..1164057e 100644 --- a/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.ts +++ b/packages/account/feature-admin/src/lib/dialogs/change-roles/change-roles.dialog.ts @@ -45,8 +45,11 @@ export class ChangeRolesDialog implements OnInit { const account = new AccountLevel(assigner); - if (account.level < 4) { + if (account.level < 2) { this.form.disableWorthy(); + } + + if (account.level < 4) { this.form.disableBoard(); } diff --git a/packages/account/feature-shell/src/lib/account-feature-shell.component.html b/packages/account/feature-shell/src/lib/account-feature-shell.component.html index e5be78a9..700d70cf 100644 --- a/packages/account/feature-shell/src/lib/account-feature-shell.component.html +++ b/packages/account/feature-shell/src/lib/account-feature-shell.component.html @@ -22,7 +22,8 @@ fixedTopGap="56" opened > - + +