xxx
This commit is contained in:
77
api/package-lock.json
generated
77
api/package-lock.json
generated
@@ -10,13 +10,16 @@
|
|||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nestjs/axios": "^3.0.3",
|
"@nestjs/axios": "^3.0.3",
|
||||||
|
"@nestjs/cache-manager": "^2.3.0",
|
||||||
"@nestjs/common": "^10.0.0",
|
"@nestjs/common": "^10.0.0",
|
||||||
"@nestjs/config": "^3.2.3",
|
"@nestjs/config": "^3.2.3",
|
||||||
"@nestjs/core": "^10.0.0",
|
"@nestjs/core": "^10.0.0",
|
||||||
"@nestjs/jwt": "^10.2.0",
|
"@nestjs/jwt": "^10.2.0",
|
||||||
|
"@nestjs/mapped-types": "^2.0.5",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"@nestjs/typeorm": "^10.0.2",
|
"@nestjs/typeorm": "^10.0.2",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
|
"cache-manager": "^5.7.6",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
"mysql2": "^3.11.2",
|
"mysql2": "^3.11.2",
|
||||||
@@ -1583,6 +1586,18 @@
|
|||||||
"rxjs": "^6.0.0 || ^7.0.0"
|
"rxjs": "^6.0.0 || ^7.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nestjs/cache-manager": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/cache-manager/-/cache-manager-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-pxeBp9w/s99HaW2+pezM1P3fLiWmUEnTUoUMLa9UYViCtjj0E0A19W/vaT5JFACCzFIeNrwH4/16jkpAhQ25Vw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^9.0.0 || ^10.0.0",
|
||||||
|
"@nestjs/core": "^9.0.0 || ^10.0.0",
|
||||||
|
"cache-manager": "<=5",
|
||||||
|
"rxjs": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nestjs/cli": {
|
"node_modules/@nestjs/cli": {
|
||||||
"version": "10.4.5",
|
"version": "10.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.4.5.tgz",
|
||||||
@@ -1732,6 +1747,26 @@
|
|||||||
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0"
|
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@nestjs/mapped-types": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/mapped-types/-/mapped-types-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-bSJv4pd6EY99NX9CjBIyn4TVDoSit82DUZlL4I3bqNfy5Gt+gXTa86i3I/i0iIV9P4hntcGM5GyO+FhZAhxtyg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0",
|
||||||
|
"class-transformer": "^0.4.0 || ^0.5.0",
|
||||||
|
"class-validator": "^0.13.0 || ^0.14.0",
|
||||||
|
"reflect-metadata": "^0.1.12 || ^0.2.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"class-transformer": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"class-validator": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@nestjs/platform-express": {
|
"node_modules/@nestjs/platform-express": {
|
||||||
"version": "10.4.1",
|
"version": "10.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.4.1.tgz",
|
||||||
@@ -3159,6 +3194,27 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cache-manager": {
|
||||||
|
"version": "5.7.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cache-manager/-/cache-manager-5.7.6.tgz",
|
||||||
|
"integrity": "sha512-wBxnBHjDxF1RXpHCBD6HGvKER003Ts7IIm0CHpggliHzN1RZditb7rXoduE1rplc2DEFYKxhLKgFuchXMJje9w==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
|
"lodash.clonedeep": "^4.5.0",
|
||||||
|
"lru-cache": "^10.2.2",
|
||||||
|
"promise-coalesce": "^1.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/cache-manager/node_modules/lru-cache": {
|
||||||
|
"version": "10.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||||
|
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||||
|
"license": "ISC"
|
||||||
|
},
|
||||||
"node_modules/call-bind": {
|
"node_modules/call-bind": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||||
@@ -4288,6 +4344,12 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eventemitter3": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/events": {
|
"node_modules/events": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
@@ -6365,6 +6427,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/lodash.clonedeep": {
|
||||||
|
"version": "4.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
|
||||||
|
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/lodash.includes": {
|
"node_modules/lodash.includes": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||||
@@ -7262,6 +7330,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||||
},
|
},
|
||||||
|
"node_modules/promise-coalesce": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise-coalesce/-/promise-coalesce-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-zLaJ9b8hnC564fnJH6NFSOGZYYdzrAJn2JUUIwzoQb32fG2QAakpDNM+CZo1km6keXkRXRM+hml1BFAPVnPkxg==",
|
||||||
|
"license": "BSD-3-Clause",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/prompts": {
|
"node_modules/prompts": {
|
||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
|
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
|
||||||
|
|||||||
@@ -21,13 +21,16 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nestjs/axios": "^3.0.3",
|
"@nestjs/axios": "^3.0.3",
|
||||||
|
"@nestjs/cache-manager": "^2.3.0",
|
||||||
"@nestjs/common": "^10.0.0",
|
"@nestjs/common": "^10.0.0",
|
||||||
"@nestjs/config": "^3.2.3",
|
"@nestjs/config": "^3.2.3",
|
||||||
"@nestjs/core": "^10.0.0",
|
"@nestjs/core": "^10.0.0",
|
||||||
"@nestjs/jwt": "^10.2.0",
|
"@nestjs/jwt": "^10.2.0",
|
||||||
|
"@nestjs/mapped-types": "^2.0.5",
|
||||||
"@nestjs/platform-express": "^10.0.0",
|
"@nestjs/platform-express": "^10.0.0",
|
||||||
"@nestjs/typeorm": "^10.0.2",
|
"@nestjs/typeorm": "^10.0.2",
|
||||||
"axios": "^1.7.7",
|
"axios": "^1.7.7",
|
||||||
|
"cache-manager": "^5.7.6",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.1",
|
"class-validator": "^0.14.1",
|
||||||
"mysql2": "^3.11.2",
|
"mysql2": "^3.11.2",
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import { RoleModule } from './modules/role/role.module';
|
|||||||
import { KeyModule } from './modules/key/key.module';
|
import { KeyModule } from './modules/key/key.module';
|
||||||
import { CustomerModule } from './modules/customer/customer.module';
|
import { CustomerModule } from './modules/customer/customer.module';
|
||||||
import { CylinderModule } from './modules/cylinder/cylinder.module';
|
import { CylinderModule } from './modules/cylinder/cylinder.module';
|
||||||
|
import { SystemModule } from './modules/system/system.module';
|
||||||
|
import { CacheInterceptor, CacheModule } from '@nestjs/cache-manager';
|
||||||
|
import { APP_INTERCEPTOR } from '@nestjs/core';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -17,6 +20,7 @@ import { CylinderModule } from './modules/cylinder/cylinder.module';
|
|||||||
envFilePath: ['.env'],
|
envFilePath: ['.env'],
|
||||||
isGlobal: true,
|
isGlobal: true,
|
||||||
}),
|
}),
|
||||||
|
CacheModule.register({ ttl: 5000, isGlobal: true }),
|
||||||
DatabaseModule,
|
DatabaseModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
UserModule,
|
UserModule,
|
||||||
@@ -24,8 +28,16 @@ import { CylinderModule } from './modules/cylinder/cylinder.module';
|
|||||||
KeyModule,
|
KeyModule,
|
||||||
CustomerModule,
|
CustomerModule,
|
||||||
CylinderModule,
|
CylinderModule,
|
||||||
|
SystemModule,
|
||||||
],
|
],
|
||||||
controllers: [AppController],
|
controllers: [AppController],
|
||||||
providers: [AppService, AuthGuard],
|
providers: [
|
||||||
|
AppService,
|
||||||
|
AuthGuard,
|
||||||
|
{
|
||||||
|
provide: APP_INTERCEPTOR,
|
||||||
|
useClass: CacheInterceptor,
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
export class AppModule {}
|
export class AppModule {}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
export * from './login.dto';
|
export * from './login.dto';
|
||||||
export * from './auth-code.dto';
|
export * from './auth-code.dto';
|
||||||
export * from './create-key-system.dto';
|
|
||||||
export * from './handover-key.dto';
|
export * from './handover-key.dto';
|
||||||
|
|||||||
@@ -1,4 +1,14 @@
|
|||||||
import { Controller, Delete, Get, Param, Req, UseGuards } from '@nestjs/common';
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
Req,
|
||||||
|
UseGuards,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { AuthGuard } from 'src/core/guards/auth.guard';
|
import { AuthGuard } from 'src/core/guards/auth.guard';
|
||||||
import { CylinderService } from './cylinder.service';
|
import { CylinderService } from './cylinder.service';
|
||||||
import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface';
|
import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface';
|
||||||
@@ -15,7 +25,23 @@ export class CylinderController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
deleteKey(@Req() req: AuthenticatedRequest, @Param() id: string) {
|
deleteKey(@Req() req: AuthenticatedRequest, @Param('id') id: string) {
|
||||||
return this.service.deleteKey(req.user, id);
|
return this.service.deleteCylinder(req.user, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put()
|
||||||
|
updateCylinder(
|
||||||
|
@Req() req: AuthenticatedRequest,
|
||||||
|
@Body() b: Partial<Cylinder>,
|
||||||
|
) {
|
||||||
|
return this.service.updateCylinder(req.user, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
createCylinder(
|
||||||
|
@Req() req: AuthenticatedRequest,
|
||||||
|
@Body() b: Partial<Cylinder>,
|
||||||
|
) {
|
||||||
|
return this.service.createCylinder(req.user, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,28 @@ export class CylinderService {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteKey(user: User, id: string) {
|
async deleteCylinder(user: User, cylinderid: string) {
|
||||||
const cylinder = await this.cylinderRepo.findOneOrFail({
|
const cylinder = await this.cylinderRepo.findOneOrFail({
|
||||||
where: { id: id, system: { managers: { id: user.id } } },
|
where: { id: cylinderid, system: { managers: { id: user.id } } },
|
||||||
relations: ['keys'],
|
relations: ['keys'],
|
||||||
});
|
});
|
||||||
await this.keyRepo.softRemove(cylinder.keys);
|
await this.keyRepo.softRemove(cylinder.keys);
|
||||||
return this.cylinderRepo.softRemove(cylinder);
|
return this.cylinderRepo.softRemove(cylinder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateCylinder(user: User, cylinder: Partial<Cylinder>) {
|
||||||
|
const original = await this.cylinderRepo.findOneOrFail({
|
||||||
|
where: { id: cylinder.id, system: { managers: { id: user.id } } },
|
||||||
|
relations: ['keys', 'system'],
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(cylinder).forEach((k: string) => {
|
||||||
|
original[k] = cylinder[k];
|
||||||
|
});
|
||||||
|
return this.cylinderRepo.save(original);
|
||||||
|
}
|
||||||
|
|
||||||
|
createCylinder(user: User, cylinder: Partial<Cylinder>) {
|
||||||
|
return this.cylinderRepo.save(this.cylinderRepo.create(cylinder));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { KeyService } from './key.service';
|
|||||||
import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface';
|
import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface';
|
||||||
import { AuthGuard } from 'src/core/guards/auth.guard';
|
import { AuthGuard } from 'src/core/guards/auth.guard';
|
||||||
import { Key } from 'src/model/entitites';
|
import { Key } from 'src/model/entitites';
|
||||||
import { CreateKeySystemDto } from 'src/model/dto/create-key-system.dto';
|
|
||||||
|
|
||||||
@UseGuards(AuthGuard)
|
@UseGuards(AuthGuard)
|
||||||
@Controller('key')
|
@Controller('key')
|
||||||
@@ -45,14 +44,6 @@ export class KeyController {
|
|||||||
return this.service.deleteKey(req.user, id);
|
return this.service.deleteKey(req.user, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post('system')
|
|
||||||
createKeySystem(
|
|
||||||
@Req() req: AuthenticatedRequest,
|
|
||||||
@Body() body: CreateKeySystemDto,
|
|
||||||
) {
|
|
||||||
return this.service.createKeySystem(req.user, body);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Post(':id/handover')
|
@Post(':id/handover')
|
||||||
handoutKey(
|
handoutKey(
|
||||||
@Req() req: AuthenticatedRequest,
|
@Req() req: AuthenticatedRequest,
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
import { CreateKeySystemDto } from 'src/model/dto';
|
|
||||||
import { Cylinder, Key, User } from 'src/model/entitites';
|
import { Cylinder, Key, User } from 'src/model/entitites';
|
||||||
import { IUser } from 'src/model/interface';
|
import { IUser } from 'src/model/interface';
|
||||||
import {
|
import {
|
||||||
@@ -68,17 +67,6 @@ export class KeyService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async createKeySystem(user: User, systemDTO: CreateKeySystemDto) {
|
|
||||||
const sys = this.systemRepo.create(systemDTO);
|
|
||||||
sys.managers = [user];
|
|
||||||
try {
|
|
||||||
const res = await this.systemRepo.save(sys);
|
|
||||||
return res;
|
|
||||||
} catch (e) {
|
|
||||||
throw new HttpException(e.code, HttpStatus.UNPROCESSABLE_ENTITY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async handoverKey(user: IUser, data: any, keyID: string) {
|
async handoverKey(user: IUser, data: any, keyID: string) {
|
||||||
const key: Key = await this.keyrepository.findOneOrFail({
|
const key: Key = await this.keyrepository.findOneOrFail({
|
||||||
where: { id: keyID, cylinder: { system: { managers: { id: user.id } } } },
|
where: { id: keyID, cylinder: { system: { managers: { id: user.id } } } },
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { IsNotEmpty, MaxLength, MinLength } from 'class-validator';
|
import { IsNotEmpty, MaxLength, MinLength } from 'class-validator';
|
||||||
|
|
||||||
export class CreateKeySystemDto {
|
export class CreateSystemDto {
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@MinLength(2)
|
@MinLength(2)
|
||||||
@MaxLength(255)
|
@MaxLength(255)
|
||||||
4
api/src/modules/system/dto/update-system.dto.ts
Normal file
4
api/src/modules/system/dto/update-system.dto.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import { PartialType } from '@nestjs/mapped-types';
|
||||||
|
import { CreateSystemDto } from './create-system.dto';
|
||||||
|
|
||||||
|
export class UpdateSystemDto extends PartialType(CreateSystemDto) {}
|
||||||
50
api/src/modules/system/system.controller.ts
Normal file
50
api/src/modules/system/system.controller.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import {
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
Post,
|
||||||
|
Body,
|
||||||
|
Patch,
|
||||||
|
Param,
|
||||||
|
Delete,
|
||||||
|
Req,
|
||||||
|
UseGuards,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { SystemService } from './system.service';
|
||||||
|
import { CreateSystemDto } from './dto/create-system.dto';
|
||||||
|
import { UpdateSystemDto } from './dto/update-system.dto';
|
||||||
|
import { AuthenticatedRequest } from 'src/model/interface/authenticated-request.interface';
|
||||||
|
import { AuthGuard } from 'src/core/guards/auth.guard';
|
||||||
|
|
||||||
|
@UseGuards(AuthGuard)
|
||||||
|
@Controller('system')
|
||||||
|
export class SystemController {
|
||||||
|
constructor(private readonly systemService: SystemService) {}
|
||||||
|
|
||||||
|
@Post()
|
||||||
|
create(
|
||||||
|
@Req() req: AuthenticatedRequest,
|
||||||
|
@Body() createSystemDto: CreateSystemDto,
|
||||||
|
) {
|
||||||
|
return this.systemService.create(req.user, createSystemDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
findAll(@Req() req: AuthenticatedRequest) {
|
||||||
|
return this.systemService.findAll(req.user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
findOne(@Param('id') id: string) {
|
||||||
|
return this.systemService.findOne(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Patch(':id')
|
||||||
|
update(@Param('id') id: string, @Body() updateSystemDto: UpdateSystemDto) {
|
||||||
|
return this.systemService.update(id, updateSystemDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete(':id')
|
||||||
|
remove(@Param('id') id: string) {
|
||||||
|
return this.systemService.remove(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
12
api/src/modules/system/system.module.ts
Normal file
12
api/src/modules/system/system.module.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { Module } from '@nestjs/common';
|
||||||
|
import { SystemService } from './system.service';
|
||||||
|
import { SystemController } from './system.controller';
|
||||||
|
import { AuthModule } from '../auth/auth.module';
|
||||||
|
import { DatabaseModule } from 'src/shared/database/database.module';
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [SystemController],
|
||||||
|
providers: [SystemService],
|
||||||
|
imports: [AuthModule, DatabaseModule],
|
||||||
|
})
|
||||||
|
export class SystemModule {}
|
||||||
18
api/src/modules/system/system.service.spec.ts
Normal file
18
api/src/modules/system/system.service.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { Test, TestingModule } from '@nestjs/testing';
|
||||||
|
import { SystemService } from './system.service';
|
||||||
|
|
||||||
|
describe('SystemService', () => {
|
||||||
|
let service: SystemService;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
|
providers: [SystemService],
|
||||||
|
}).compile();
|
||||||
|
|
||||||
|
service = module.get<SystemService>(SystemService);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be defined', () => {
|
||||||
|
expect(service).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
42
api/src/modules/system/system.service.ts
Normal file
42
api/src/modules/system/system.service.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
|
||||||
|
import { CreateSystemDto } from './dto/create-system.dto';
|
||||||
|
import { UpdateSystemDto } from './dto/update-system.dto';
|
||||||
|
import { KeySystemRepository } from 'src/model/repositories';
|
||||||
|
import { User } from 'src/model/entitites';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SystemService {
|
||||||
|
constructor(private systemRepo: KeySystemRepository) {}
|
||||||
|
|
||||||
|
async create(user: User, createSystemDto: CreateSystemDto) {
|
||||||
|
const sys = this.systemRepo.create(createSystemDto);
|
||||||
|
sys.managers = [user];
|
||||||
|
try {
|
||||||
|
const res = await this.systemRepo.save(sys);
|
||||||
|
return res;
|
||||||
|
} catch (e) {
|
||||||
|
throw new HttpException(e.code, HttpStatus.UNPROCESSABLE_ENTITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
findAll(user: User) {
|
||||||
|
return this.systemRepo.find({
|
||||||
|
where: { managers: { id: user.id } },
|
||||||
|
order: { name: { direction: 'ASC' } },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
findOne(id: string) {
|
||||||
|
return `This action returns a #${id} system`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
update(id: string, updateSystemDto: UpdateSystemDto) {
|
||||||
|
return `This action updates a #${id} system`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async remove(id: string) {
|
||||||
|
const system = await this.systemRepo.findOne({ where: { id } });
|
||||||
|
return this.systemRepo.softRemove(system);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,13 +8,15 @@ import { DashboardComponent } from './modules/dashboard/dashboard.component';
|
|||||||
import { AllUsersComponent } from './modules/admin/all-users/all-users.component';
|
import { AllUsersComponent } from './modules/admin/all-users/all-users.component';
|
||||||
import { KeysComponent } from './modules/keys/keys.component';
|
import { KeysComponent } from './modules/keys/keys.component';
|
||||||
import { CylinderComponent } from './modules/cylinder/cylinder.component';
|
import { CylinderComponent } from './modules/cylinder/cylinder.component';
|
||||||
|
import { SystemComponent } from './modules/system/system.component';
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{ path: '', component: LayoutComponent, canActivate: [AuthenticatedGuard], children: [
|
{ path: '', component: LayoutComponent, canActivate: [AuthenticatedGuard], children: [
|
||||||
{ path: '', component: DashboardComponent },
|
{ path: '', component: DashboardComponent },
|
||||||
{ path: 'users', component: AllUsersComponent },
|
{ path: 'users', component: AllUsersComponent },
|
||||||
{ path: 'keys', component: KeysComponent },
|
{ path: 'keys', component: KeysComponent },
|
||||||
{ path: 'cylinders', component: CylinderComponent }
|
{ path: 'cylinders', component: CylinderComponent },
|
||||||
|
{ path: 'systems', component: SystemComponent }
|
||||||
]},
|
]},
|
||||||
{ path: 'login', component: LoginComponent},
|
{ path: 'login', component: LoginComponent},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
<button mat-button routerLink="/" routerLinkActive="mat-elevation-z1" [routerLinkActiveOptions]="{exact: true}">Home</button>
|
<button mat-button routerLink="/" routerLinkActive="mat-elevation-z1" [routerLinkActiveOptions]="{exact: true}">Home</button>
|
||||||
<button mat-button routerLink="/keys" routerLinkActive="mat-elevation-z1">Schlüssel</button>
|
<button mat-button routerLink="/keys" routerLinkActive="mat-elevation-z1">Schlüssel</button>
|
||||||
<button mat-button routerLink="/cylinders" routerLinkActive="mat-elevation-z1">Zylinder</button>
|
<button mat-button routerLink="/cylinders" routerLinkActive="mat-elevation-z1">Zylinder</button>
|
||||||
|
<button mat-button routerLink="/systems" routerLinkActive="mat-elevation-z1">System</button>
|
||||||
<button mat-button routerLink="/users" routerLinkActive="mat-elevation-z1">Alle User</button>
|
<button mat-button routerLink="/users" routerLinkActive="mat-elevation-z1">Alle User</button>
|
||||||
</mat-drawer>
|
</mat-drawer>
|
||||||
|
|
||||||
|
|||||||
12
client/src/app/model/interface/cylinder.interface.ts
Normal file
12
client/src/app/model/interface/cylinder.interface.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { IKey } from "./key.interface";
|
||||||
|
|
||||||
|
export interface ICylinder {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
deletedAt: string;
|
||||||
|
system: any;
|
||||||
|
keys: IKey[];
|
||||||
|
keyCount: number;
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
|
import { ICylinder } from "./cylinder.interface";
|
||||||
|
|
||||||
export interface IKey {
|
export interface IKey {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
updatedAt: string;
|
updatedAt: string;
|
||||||
handedOut: boolean;
|
handedOut: boolean;
|
||||||
cylinder: any;
|
cylinder: ICylinder;
|
||||||
nr: number;
|
nr: number;
|
||||||
deletedAt?: string;
|
deletedAt?: string;
|
||||||
}
|
}
|
||||||
@@ -70,7 +70,6 @@ export class AllUsersComponent {
|
|||||||
next: n => {
|
next: n => {
|
||||||
this.gridApi.setGridOption("rowData", n)
|
this.gridApi.setGridOption("rowData", n)
|
||||||
this.gridApi.setGridOption("loading", false);
|
this.gridApi.setGridOption("loading", false);
|
||||||
n.filter(u => u.username == 'mail@bastian-wagner.de').map((u: any) => { console.log(u['lastLogin'])})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -98,7 +97,6 @@ export class AllUsersComponent {
|
|||||||
const self = this;
|
const self = this;
|
||||||
this.gridApi.addEventListener("cellEditingStopped", evt => this.cellEditEnd(evt, self))
|
this.gridApi.addEventListener("cellEditingStopped", evt => this.cellEditEnd(evt, self))
|
||||||
this.loadUsers();
|
this.loadUsers();
|
||||||
console.log(params)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<h2 mat-dialog-title>Zylinder <u>{{key.name}}</u> löschen?</h2>
|
||||||
|
<mat-dialog-content>
|
||||||
|
<p>Soll der Zylinder wirklich gelöscht werden? Alle {{ key.keyCount | number:'0.0-0'}} enthaltenen Schlüssel werden mit entfernt!</p>
|
||||||
|
|
||||||
|
</mat-dialog-content>
|
||||||
|
<mat-dialog-actions>
|
||||||
|
<button mat-button [mat-dialog-close]="false" >Abbrechen</button>
|
||||||
|
<button mat-button [mat-dialog-close]="true" color="warn">Ja, löschen</button>
|
||||||
|
</mat-dialog-actions>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { DeleteCylinderComponent } from './delete-cylinder.component';
|
||||||
|
|
||||||
|
describe('DeleteCylinderComponent', () => {
|
||||||
|
let component: DeleteCylinderComponent;
|
||||||
|
let fixture: ComponentFixture<DeleteCylinderComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [DeleteCylinderComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(DeleteCylinderComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, inject, LOCALE_ID } from '@angular/core';
|
||||||
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-delete-cylinder',
|
||||||
|
standalone: true,
|
||||||
|
imports: [MatDialogModule, MatButtonModule, CommonModule],
|
||||||
|
providers: [{ provide: LOCALE_ID, useValue: 'de-DE' },],
|
||||||
|
templateUrl: './delete-cylinder.component.html',
|
||||||
|
styleUrl: './delete-cylinder.component.scss'
|
||||||
|
})
|
||||||
|
export class DeleteCylinderComponent {
|
||||||
|
readonly dialogRef = inject(MatDialogRef<DeleteCylinderComponent>);
|
||||||
|
readonly key = inject<any>(MAT_DIALOG_DATA);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import { GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
|||||||
import { AgGridAngular } from 'ag-grid-angular';
|
import { AgGridAngular } from 'ag-grid-angular';
|
||||||
import { ApiService } from '../../shared/api.service';
|
import { ApiService } from '../../shared/api.service';
|
||||||
import { DatePipe } from '@angular/common';
|
import { DatePipe } from '@angular/common';
|
||||||
|
import { AgDeleteCylinderComponent } from '../../shared/ag-grid/components/ag-delete-cylinder/ag-delete-cylinder.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-cylinder',
|
selector: 'app-cylinder',
|
||||||
@@ -30,6 +31,12 @@ export class CylinderComponent {
|
|||||||
{ field: 'keyCount', headerName: 'Anzahl Schlüssel', flex: 0, type: 'number' },
|
{ field: 'keyCount', headerName: 'Anzahl Schlüssel', flex: 0, type: 'number' },
|
||||||
{ field: 'createdAt', headerName: 'Angelegt', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
{ field: 'createdAt', headerName: 'Angelegt', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
||||||
{ field: 'updatedAt', headerName: 'Upgedated', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
{ field: 'updatedAt', headerName: 'Upgedated', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
||||||
|
{
|
||||||
|
colId: 'actions'
|
||||||
|
, headerName: 'Aktionen'
|
||||||
|
, width: 120
|
||||||
|
, cellRenderer: AgDeleteCylinderComponent
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,9 +83,7 @@ export class KeysComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteKey(id: string) {
|
deleteKey(id: string) {
|
||||||
this.api.deleteKey(id).subscribe({
|
this.api.deleteKey(id).subscribe()
|
||||||
next: n => console.log(n)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<p>start works!</p>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { Component, inject } from '@angular/core';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-start',
|
|
||||||
standalone: true,
|
|
||||||
imports: [],
|
|
||||||
templateUrl: './start.component.html',
|
|
||||||
styleUrl: './start.component.scss'
|
|
||||||
})
|
|
||||||
export class StartComponent {
|
|
||||||
private http: HttpClient = inject(HttpClient);
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.http.get('/api/').subscribe(res => {
|
|
||||||
console.log(res)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
5
client/src/app/modules/system/system.component.html
Normal file
5
client/src/app/modules/system/system.component.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<ag-grid-angular
|
||||||
|
style="width: 100%; height: 100%;"
|
||||||
|
(gridReady)="onGridReady($event)"
|
||||||
|
[gridOptions]="gridOptions!"
|
||||||
|
/>
|
||||||
0
client/src/app/modules/system/system.component.scss
Normal file
0
client/src/app/modules/system/system.component.scss
Normal file
@@ -1,18 +1,18 @@
|
|||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { StartComponent } from './start.component';
|
import { SystemComponent } from './system.component';
|
||||||
|
|
||||||
describe('StartComponent', () => {
|
describe('SystemComponent', () => {
|
||||||
let component: StartComponent;
|
let component: SystemComponent;
|
||||||
let fixture: ComponentFixture<StartComponent>;
|
let fixture: ComponentFixture<SystemComponent>;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await TestBed.configureTestingModule({
|
await TestBed.configureTestingModule({
|
||||||
imports: [StartComponent]
|
imports: [SystemComponent]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
|
|
||||||
fixture = TestBed.createComponent(StartComponent);
|
fixture = TestBed.createComponent(SystemComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
47
client/src/app/modules/system/system.component.ts
Normal file
47
client/src/app/modules/system/system.component.ts
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import { DatePipe } from '@angular/common';
|
||||||
|
import { Component, inject } from '@angular/core';
|
||||||
|
import { AgGridAngular } from 'ag-grid-angular';
|
||||||
|
import { GridApi, GridOptions, GridReadyEvent } from 'ag-grid-community';
|
||||||
|
import { ApiService } from '../../shared/api.service';
|
||||||
|
import { HELPER } from '../../shared/helper.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-system',
|
||||||
|
standalone: true,
|
||||||
|
imports: [AgGridAngular],
|
||||||
|
providers: [DatePipe],
|
||||||
|
templateUrl: './system.component.html',
|
||||||
|
styleUrl: './system.component.scss'
|
||||||
|
})
|
||||||
|
export class SystemComponent {
|
||||||
|
private api: ApiService = inject(ApiService);
|
||||||
|
private datePipe = inject(DatePipe);
|
||||||
|
|
||||||
|
gridApi!: GridApi;
|
||||||
|
|
||||||
|
gridOptions: GridOptions = HELPER.getGridOptions();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.gridOptions.columnDefs = [
|
||||||
|
{ colId: 'name', field: 'name', headerName: 'Name', sort: 'asc', flex: 1},
|
||||||
|
{ field: 'createdAt', headerName: 'Angelegt', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
||||||
|
{ field: 'updatedAt', headerName: 'Upgedated', cellRenderer: (data: any) => data.value ? this.datePipe.transform(new Date(data.value)) : '-' },
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
loadSystems() {
|
||||||
|
this.api.getSystems().subscribe({
|
||||||
|
next: n => {
|
||||||
|
this.gridApi.setGridOption("rowData", n);
|
||||||
|
this.gridApi.setGridOption("loading", false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onGridReady(params: GridReadyEvent) {
|
||||||
|
this.gridApi = params.api;
|
||||||
|
this.loadSystems();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<p>ag-base-component works!</p>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AgBaseComponentComponent } from './ag-base-component.component';
|
||||||
|
|
||||||
|
describe('AgBaseComponentComponent', () => {
|
||||||
|
let component: AgBaseComponentComponent;
|
||||||
|
let fixture: ComponentFixture<AgBaseComponentComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [AgBaseComponentComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AgBaseComponentComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { Component, inject } from '@angular/core';
|
||||||
|
import { MatDialog, MatDialogModule } from '@angular/material/dialog';
|
||||||
|
import { HotToastService } from '@ngxpert/hot-toast';
|
||||||
|
import { ApiService } from '../../../api.service';
|
||||||
|
import { ICellRendererAngularComp } from 'ag-grid-angular';
|
||||||
|
import { ICellRendererParams } from 'ag-grid-community';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
imports: [MatDialogModule, MatTooltipModule],
|
||||||
|
templateUrl: './ag-base-component.component.html',
|
||||||
|
styleUrl: './ag-base-component.component.scss'
|
||||||
|
})
|
||||||
|
export class AgBaseComponentComponent implements ICellRendererAngularComp {
|
||||||
|
protected api: ApiService = inject(ApiService);
|
||||||
|
protected dialog: MatDialog = inject(MatDialog);
|
||||||
|
protected toast = inject(HotToastService);
|
||||||
|
params!: ICellRendererParams<any, any, any>;
|
||||||
|
|
||||||
|
agInit(params: ICellRendererParams<any, any, any>): void {
|
||||||
|
this.params = params;
|
||||||
|
}
|
||||||
|
refresh(params: ICellRendererParams<any, any, any>): boolean {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<div class="delete icon-btn-sm" (click)="delete()" matTooltip="Löschen" [matTooltipShowDelay]="600"></div>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AgDeleteCylinderComponent } from './ag-delete-cylinder.component';
|
||||||
|
|
||||||
|
describe('AgDeleteCylinderComponent', () => {
|
||||||
|
let component: AgDeleteCylinderComponent;
|
||||||
|
let fixture: ComponentFixture<AgDeleteCylinderComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [AgDeleteCylinderComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(AgDeleteCylinderComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { AgBaseComponentComponent } from '../ag-base-component/ag-base-component.component';
|
||||||
|
import { DeleteCylinderComponent } from '../../../../modules/cylinder/components/delete-cylinder/delete-cylinder.component';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-ag-delete-cylinder',
|
||||||
|
standalone: true,
|
||||||
|
imports: [MatTooltipModule],
|
||||||
|
templateUrl: './ag-delete-cylinder.component.html',
|
||||||
|
styleUrl: './ag-delete-cylinder.component.scss'
|
||||||
|
})
|
||||||
|
export class AgDeleteCylinderComponent extends AgBaseComponentComponent {
|
||||||
|
|
||||||
|
|
||||||
|
delete() {
|
||||||
|
const ref = this.dialog.open(DeleteCylinderComponent, {
|
||||||
|
data: this.params.data,
|
||||||
|
autoFocus: false
|
||||||
|
})
|
||||||
|
|
||||||
|
ref.afterClosed().subscribe({
|
||||||
|
next: n => {
|
||||||
|
if (n) {
|
||||||
|
this.deleteThisCylinder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteThisCylinder() {
|
||||||
|
this.api.deleteCylinder(this.params.data)
|
||||||
|
.pipe(
|
||||||
|
this.toast.observe({
|
||||||
|
loading: 'Löschen...',
|
||||||
|
success: 'Gelöscht!',
|
||||||
|
error: 'Konnte nicht gelöscht werden'
|
||||||
|
})
|
||||||
|
).subscribe({
|
||||||
|
next: () => {
|
||||||
|
const rows = this.params.api.getGridOption("rowData")?.filter(r => r.id != this.params.data.id);
|
||||||
|
this.params.api.setGridOption("rowData", rows);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ import { inject, Injectable } from '@angular/core';
|
|||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { IUser } from '../model/interface/user.interface';
|
import { IUser } from '../model/interface/user.interface';
|
||||||
import { IKey } from '../model/interface/key.interface';
|
import { IKey } from '../model/interface/key.interface';
|
||||||
|
import { ICylinder } from '../model/interface/cylinder.interface';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@@ -37,8 +38,12 @@ export class ApiService {
|
|||||||
return this.http.post<IKey>('api/key', key);
|
return this.http.post<IKey>('api/key', key);
|
||||||
}
|
}
|
||||||
|
|
||||||
postKeySystem(keySystem: any) {
|
createSystem(keySystem: any) {
|
||||||
return this.http.post('api/key/system', keySystem);
|
return this.http.post('api/system', keySystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
getSystems(): Observable<any[]> {
|
||||||
|
return this.http.get<any[]>('api/system');
|
||||||
}
|
}
|
||||||
|
|
||||||
handoverKey(data: any) {
|
handoverKey(data: any) {
|
||||||
@@ -69,7 +74,11 @@ export class ApiService {
|
|||||||
return this.http.put(`api/key/${id}/restore`, null);
|
return this.http.put(`api/key/${id}/restore`, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCylinders(): Observable<any[]> {
|
getCylinders(): Observable<ICylinder[]> {
|
||||||
return this.http.get<any[]>('api/cylinder');
|
return this.http.get<ICylinder[]>('api/cylinder');
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteCylinder(cylinder: ICylinder): Observable<any> {
|
||||||
|
return this.http.delete(`api/cylinder/${cylinder.id}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user