diff --git a/goofy-client/angular.json b/goofy-client/angular.json index c67e9e28f09e91cae6f454c57adbba40b0d27620..92328c2e29b3e70c1d2e13fc5b214d5788dbb569 100644 --- a/goofy-client/angular.json +++ b/goofy-client/angular.json @@ -512,6 +512,31 @@ } } } + }, + "file-shared": { + "projectType": "library", + "root": "libs/file-shared", + "sourceRoot": "libs/file-shared/src", + "prefix": "goofy-client", + "architect": { + "lint": { + "builder": "@nrwl/linter:eslint", + "options": { + "lintFilePatterns": [ + "libs/file-shared/src/**/*.ts", + "libs/file-shared/src/**/*.html" + ] + } + }, + "test": { + "builder": "@nrwl/jest:jest", + "outputs": ["coverage/libs/file-shared"], + "options": { + "jestConfig": "libs/file-shared/jest.config.js", + "passWithNoTests": true + } + } + } } }, "cli": { diff --git a/goofy-client/jest.config.js b/goofy-client/jest.config.js index 4ec0d6903f55fa4e360c5d88fe613147aeb03f15..f6293f398d35cc5614ad5626aff4c5d5d4b4236c 100644 --- a/goofy-client/jest.config.js +++ b/goofy-client/jest.config.js @@ -14,5 +14,6 @@ module.exports = { '<rootDir>/libs/command-shared', '<rootDir>/libs/wiedervorlage-shared', '<rootDir>/libs/wiedervorlage', + '<rootDir>/libs/file-shared', ], }; diff --git a/goofy-client/libs/file-shared/.eslintrc.json b/goofy-client/libs/file-shared/.eslintrc.json new file mode 100644 index 0000000000000000000000000000000000000000..3f74eaa7e24d347f2d7c0860dad0b8d197e2ecaa --- /dev/null +++ b/goofy-client/libs/file-shared/.eslintrc.json @@ -0,0 +1,33 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": [ + "plugin:@nrwl/nx/angular", + "plugin:@angular-eslint/template/process-inline-templates" + ], + "parserOptions": { "project": ["libs/file-shared/tsconfig.*?.json"] }, + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "goofy-client", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { "type": "element", "prefix": "goofy-client", "style": "kebab-case" } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/goofy-client/libs/file-shared/README.md b/goofy-client/libs/file-shared/README.md new file mode 100644 index 0000000000000000000000000000000000000000..2f16a06ab6c7cef9687bf923fae8db6137468542 --- /dev/null +++ b/goofy-client/libs/file-shared/README.md @@ -0,0 +1,7 @@ +# file-shared + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test file-shared` to execute the unit tests. diff --git a/goofy-client/libs/file-shared/jest.config.js b/goofy-client/libs/file-shared/jest.config.js new file mode 100644 index 0000000000000000000000000000000000000000..33f444fdb82356ea6890e006847991bd5eec98c8 --- /dev/null +++ b/goofy-client/libs/file-shared/jest.config.js @@ -0,0 +1,23 @@ +module.exports = { + displayName: 'file-shared', + preset: '../../jest.preset.js', + setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], + globals: { + 'ts-jest': { + tsConfig: '<rootDir>/tsconfig.spec.json', + stringifyContentPathRegex: '\\.(html|svg)$', + astTransformers: { + before: [ + 'jest-preset-angular/build/InlineFilesTransformer', + 'jest-preset-angular/build/StripStylesTransformer', + ], + }, + }, + }, + coverageDirectory: '../../coverage/libs/file-shared', + snapshotSerializers: [ + 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js', + 'jest-preset-angular/build/AngularSnapshotSerializer.js', + 'jest-preset-angular/build/HTMLCommentSerializer.js', + ], +}; diff --git a/goofy-client/libs/file-shared/src/index.ts b/goofy-client/libs/file-shared/src/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..c9ddfe4bb218779a575b86f791cf0d9ea68463bc --- /dev/null +++ b/goofy-client/libs/file-shared/src/index.ts @@ -0,0 +1,3 @@ +export * from './lib/file-shared.module'; +export * from './lib/file.linkrel'; +export * from './lib/file.model'; diff --git a/goofy-client/libs/file-shared/src/lib/file-shared.module.spec.ts b/goofy-client/libs/file-shared/src/lib/file-shared.module.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..99ee6a644da8a2c11053806ab36870f4a16b979b --- /dev/null +++ b/goofy-client/libs/file-shared/src/lib/file-shared.module.spec.ts @@ -0,0 +1,14 @@ +import { TestBed } from '@angular/core/testing'; +import { FileSharedModule } from './file-shared.module'; + +describe('FileSharedModule', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [FileSharedModule], + }).compileComponents(); + }); + + it('should create', () => { + expect(FileSharedModule).toBeDefined(); + }); +}); \ No newline at end of file diff --git a/goofy-client/libs/file-shared/src/lib/file-shared.module.ts b/goofy-client/libs/file-shared/src/lib/file-shared.module.ts new file mode 100644 index 0000000000000000000000000000000000000000..c5b0477a8aeaaf4e3b80acd2557572a12f2189f8 --- /dev/null +++ b/goofy-client/libs/file-shared/src/lib/file-shared.module.ts @@ -0,0 +1,7 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@NgModule({ + imports: [CommonModule], +}) +export class FileSharedModule {} diff --git a/goofy-client/libs/file-shared/src/lib/file.linkrel.ts b/goofy-client/libs/file-shared/src/lib/file.linkrel.ts new file mode 100644 index 0000000000000000000000000000000000000000..bd7718b29480078d2bce852b6cf085d77aa86eb7 --- /dev/null +++ b/goofy-client/libs/file-shared/src/lib/file.linkrel.ts @@ -0,0 +1,7 @@ +export enum FileLinkRel { + DOWNLOAD = 'download' +} + +export enum FileListLinkRel { + FILE_LIST = 'fileList' +} \ No newline at end of file diff --git a/goofy-client/libs/file-shared/src/lib/file.model.ts b/goofy-client/libs/file-shared/src/lib/file.model.ts new file mode 100644 index 0000000000000000000000000000000000000000..2b08388a66771ae3acbe21a41c224fa4dac7332c --- /dev/null +++ b/goofy-client/libs/file-shared/src/lib/file.model.ts @@ -0,0 +1,11 @@ +import { ListResource } from '@goofy-client/tech-shared'; +import { Resource } from '@ngxp/rest'; + +export interface File { + name: string, + size: number +} + +export interface FileResource extends File, Resource { } + +export interface FileListResource extends ListResource { } \ No newline at end of file diff --git a/goofy-client/libs/file-shared/src/lib/file.service.ts b/goofy-client/libs/file-shared/src/lib/file.service.ts new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/goofy-client/libs/file-shared/src/test-setup.ts b/goofy-client/libs/file-shared/src/test-setup.ts new file mode 100644 index 0000000000000000000000000000000000000000..8d88704e8ff09145a6310d3df98f124042268bfe --- /dev/null +++ b/goofy-client/libs/file-shared/src/test-setup.ts @@ -0,0 +1 @@ +import 'jest-preset-angular'; diff --git a/goofy-client/libs/tech-shared/test/file.ts b/goofy-client/libs/file-shared/test/file.ts similarity index 56% rename from goofy-client/libs/tech-shared/test/file.ts rename to goofy-client/libs/file-shared/test/file.ts index a394249398a4c8fd5b292b25a0ae37450b20d324..eaf5573a0569c54635a04d5c1bca11c1836a7282 100644 --- a/goofy-client/libs/tech-shared/test/file.ts +++ b/goofy-client/libs/file-shared/test/file.ts @@ -1,7 +1,8 @@ +import { FileListLinkRel } from '@goofy-client/file-shared'; import * as faker from 'faker'; -import { File, FileResource } from '../src/lib/tech.model'; -import { toResource } from './resource'; +import { toResource } from 'libs/tech-shared/test/resource'; import { times } from 'lodash-es'; +import { File, FileListResource, FileResource } from '../src/lib/file.model'; export function createFile(): File { return { @@ -17,3 +18,9 @@ export function createFileResource(linkRelations: string[] = []): FileResource { export function createFileResources(linkRelations: string[] = []): FileResource[] { return times(10, () => toResource(createFileResource(), [...linkRelations])); } + +export function createFileListResource(linkRelations: string[] = []): FileListResource { + return toResource({}, [...linkRelations], { + [FileListLinkRel.FILE_LIST]: createFileResources() + }) +} \ No newline at end of file diff --git a/goofy-client/libs/file-shared/tsconfig.json b/goofy-client/libs/file-shared/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..62ebbd946474cea997e774d20fffc4d585c184f3 --- /dev/null +++ b/goofy-client/libs/file-shared/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/goofy-client/libs/file-shared/tsconfig.lib.json b/goofy-client/libs/file-shared/tsconfig.lib.json new file mode 100644 index 0000000000000000000000000000000000000000..d5befaafb6f871f62279559d6efec18a4a19e665 --- /dev/null +++ b/goofy-client/libs/file-shared/tsconfig.lib.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "target": "es2015", + "declaration": true, + "declarationMap": true, + "inlineSources": true, + "types": [], + "lib": ["dom", "es2018"] + }, + "angularCompilerOptions": { + "skipTemplateCodegen": true, + "strictMetadataEmit": true, + "enableResourceInlining": true + }, + "exclude": ["src/test-setup.ts", "**/*.spec.ts"], + "include": ["**/*.ts"] +} diff --git a/goofy-client/libs/file-shared/tsconfig.spec.json b/goofy-client/libs/file-shared/tsconfig.spec.json new file mode 100644 index 0000000000000000000000000000000000000000..cfff29a544fb49a8c26a7cbf9cd836c87efb7fe8 --- /dev/null +++ b/goofy-client/libs/file-shared/tsconfig.spec.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "files": ["src/test-setup.ts"], + "include": ["**/*.spec.ts", "**/*.d.ts"] +} diff --git a/goofy-client/libs/tech-shared/src/lib/tech.model.ts b/goofy-client/libs/tech-shared/src/lib/tech.model.ts index f25c95c113fbe0071f1c60a19f38041b18bf6f03..61cb5050dc01e8621770fc868e219dd1184574cb 100644 --- a/goofy-client/libs/tech-shared/src/lib/tech.model.ts +++ b/goofy-client/libs/tech-shared/src/lib/tech.model.ts @@ -1,5 +1,3 @@ -import { Resource } from '@ngxp/rest'; - export interface ApiError { issues: Issue[] } @@ -15,14 +13,3 @@ export interface IssueParam { name: string, value: string; } - -export interface File { - name: string, - size: number -} - -export enum FileLinkRel { - DOWNLOAD = 'download' -} - -export interface FileResource extends File, Resource { } diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.html deleted file mode 100644 index fa34234e1163f44232302bec4860a395d4b02de3..0000000000000000000000000000000000000000 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.html +++ /dev/null @@ -1,7 +0,0 @@ -<div class="files" *ngIf="vorgangWithEingang | hasLink: linkRel.ATTACHMENTS; else emptyAnhaenge"> - <goofy-client-file *ngFor="let file of files" [fileResource]="file"></goofy-client-file> -</div> - -<ng-template #emptyAnhaenge> - <p>keine Anhänge vorhanden</p> -</ng-template> diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.spec.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.spec.ts deleted file mode 100644 index 61967a70eb7d16f2ba144d7f8c42287ba604a6b1..0000000000000000000000000000000000000000 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.spec.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { AnhaengeComponent } from './anhaenge.component'; -import { HasLinkPipe } from '@goofy-client/tech-shared'; -import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; -import { VorgangWithEingangLinkRel } from '@goofy-client/vorgang-shared'; -import { MockComponent } from 'ng-mocks'; -import { FileComponent } from './file/file.component'; -import { createFileResources } from '../../../../../../tech-shared/test/file'; - -describe('AnhaengeComponent', () => { - let component: AnhaengeComponent; - let fixture: ComponentFixture<AnhaengeComponent>; - - const eingangWithoutAttachment = createVorgangWithEingangResource(); - const eingangWithAttachment = createVorgangWithEingangResource([VorgangWithEingangLinkRel.ATTACHMENTS]); - const fileElementSelector = 'goofy-client-file'; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [ - AnhaengeComponent, - HasLinkPipe, - MockComponent(FileComponent) - ] - }) - .compileComponents(); - }); - - beforeEach(() => { - fixture = TestBed.createComponent(AnhaengeComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); - - describe('empty attachments text', () => { - - const text = 'keine Anhänge vorhanden'; - - it('should not visible', () => { - component.vorgangWithEingang = eingangWithoutAttachment; - fixture.detectChanges(); - - expect(fixture.nativeElement).toHaveTextContent(text) - }) - - it('should visible', () => { - component.vorgangWithEingang = eingangWithAttachment; - fixture.detectChanges(); - - expect(fixture.nativeElement).not.toHaveTextContent(text); - }) - }) - - describe('files', () => { - beforeEach(() => { - component.vorgangWithEingang = eingangWithAttachment; - fixture.detectChanges(); - }) - - it('should not visible initially', () => { - const element = fixture.nativeElement.querySelector(fileElementSelector); - - expect(element).not.toBeInstanceOf(HTMLElement); - }) - - it('should have length of 10', () => { - component.files = createFileResources(); - fixture.detectChanges(); - - const elements = fixture.nativeElement.querySelectorAll(fileElementSelector); - - expect(elements).toHaveLength(10); - }) - }); -}); diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.ts deleted file mode 100644 index d768ad1bf32a0bb6b9c061d59aa2e838065bb283..0000000000000000000000000000000000000000 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Component, Input } from '@angular/core'; -import { VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@goofy-client/vorgang-shared'; -import { FileResource } from '@goofy-client/tech-shared'; - -@Component({ - selector: 'goofy-client-anhaenge', - templateUrl: './anhaenge.component.html', - styleUrls: ['./anhaenge.component.scss'] -}) -export class AnhaengeComponent { - - @Input() vorgangWithEingang: VorgangWithEingangResource; - - files: FileResource[]; - - readonly linkRel = VorgangWithEingangLinkRel; -} diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.html deleted file mode 100644 index f507631031f22fe531f6c429f3bfae2077e90c98..0000000000000000000000000000000000000000 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.html +++ /dev/null @@ -1,5 +0,0 @@ -<div class="file" [matTooltip]="fileResource.name"> - <mat-icon>file_present</mat-icon> - <span class="name">{{ fileResource.name }}</span> - <span class="size" [innerHTML]="fileResource.size | fileSize"></span> -</div> diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.ts deleted file mode 100644 index f628ca993fa5c38b4c7836dda34c39256c4d4d97..0000000000000000000000000000000000000000 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { FileLinkRel, FileResource } from '@goofy-client/tech-shared'; - -@Component({ - selector: 'goofy-client-file', - templateUrl: './file.component.html', - styleUrls: ['./file.component.scss'] -}) -export class FileComponent implements OnInit { - - @Input() fileResource: FileResource; - - fileLinkRel = FileLinkRel; - - constructor() { } - - ngOnInit(): void { - } - -} diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.html new file mode 100644 index 0000000000000000000000000000000000000000..a00a533b5497337b34f0e800aede9855568449d3 --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.html @@ -0,0 +1 @@ +<goofy-client-file *ngFor="let file of (attachmentList | toEmbeddedResources: fileListRel.FILE_LIST)" [file]="file"></goofy-client-file> \ No newline at end of file diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.scss b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.scss similarity index 100% rename from goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component.scss rename to goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.scss diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.spec.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..62ae9b8f66d3882024bf13e4d9e1f8a15ae31be6 --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.spec.ts @@ -0,0 +1,45 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { createFileListResource } from 'libs/file-shared/test/file'; +import { ToEmbeddedResourcesPipe } from 'libs/tech-shared/src/lib/pipes/embedded-resource'; +import { MockComponent } from 'ng-mocks'; +import { AnhaengeComponent } from './anhaenge.component'; +import { FileComponent } from './file/file.component'; + +describe('AnhaengeComponent', () => { + let component: AnhaengeComponent; + let fixture: ComponentFixture<AnhaengeComponent>; + + const fileElementSelector = 'goofy-client-file'; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + AnhaengeComponent, + ToEmbeddedResourcesPipe, + MockComponent(FileComponent) + ] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AnhaengeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('files', () => { + + it('should have length of 10', () => { + component.attachmentList = createFileListResource(); + fixture.detectChanges(); + + const elements = fixture.nativeElement.querySelectorAll(fileElementSelector); + + expect(elements).toHaveLength(10); + }) + }); +}); diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..12c0627abda1f51dd63d7a1ef85bfe25140c029e --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component.ts @@ -0,0 +1,14 @@ +import { Component, Input } from '@angular/core'; +import { FileListLinkRel, FileListResource } from '@goofy-client/file-shared'; + +@Component({ + selector: 'goofy-client-anhaenge', + templateUrl: './anhaenge.component.html', + styleUrls: ['./anhaenge.component.scss'] +}) +export class AnhaengeComponent { + + @Input() attachmentList: FileListResource; + + readonly fileListRel = FileListLinkRel; +} diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.html new file mode 100644 index 0000000000000000000000000000000000000000..6c408ba57fa0b698347078764a1a04f82fdcdc77 --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.html @@ -0,0 +1,5 @@ +<div class="file" [matTooltip]="file.name"> + <mat-icon>file_present</mat-icon> + <span class="name">{{ file.name }}</span> + <span class="size" [innerHTML]="file.size | fileSize"></span> +</div> diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.scss b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.scss similarity index 100% rename from goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.scss rename to goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.scss diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.spec.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.spec.ts similarity index 65% rename from goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.spec.ts rename to goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.spec.ts index 3d61023de109a24a197cfb88c9c529e2a89d3e9e..16aa4bb53343a407a4851b4b35a64b46b30c8aea 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component.spec.ts +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.spec.ts @@ -1,35 +1,34 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { FileComponent } from './file.component'; import { MatIcon } from '@angular/material/icon'; -import { FileLinkRel, FileSizePipe, ToResourceUriPipe } from '@goofy-client/tech-shared'; -import { createFileResource } from 'libs/tech-shared/test/file'; import { MatTooltip } from '@angular/material/tooltip'; +import { FileLinkRel, FileResource } from '@goofy-client/file-shared'; +import { FileSizePipe, ToResourceUriPipe } from '@goofy-client/tech-shared'; +import { createFileResource } from 'libs/file-shared/test/file'; import { MockComponent } from 'ng-mocks'; +import { FileComponent } from './file.component'; describe('FileComponent', () => { let component: FileComponent; let fixture: ComponentFixture<FileComponent>; - const fileResource = createFileResource([FileLinkRel.DOWNLOAD]); + const file: FileResource = createFileResource([FileLinkRel.DOWNLOAD]); beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ FileComponent, MatIcon, - MockComponent(MatTooltip), FileSizePipe, - ToResourceUriPipe + ToResourceUriPipe, + MockComponent(MatTooltip) ] - }) - .compileComponents(); + }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(FileComponent); component = fixture.componentInstance; - component.fileResource = fileResource; + component.file = file; fixture.detectChanges(); }); diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..0fefc7351cacc7612b3c1d9df6ddb7beab34e930 --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component.ts @@ -0,0 +1,14 @@ +import { Component, Input } from '@angular/core'; +import { FileLinkRel, FileResource } from '@goofy-client/file-shared'; + +@Component({ + selector: 'goofy-client-file', + templateUrl: './file.component.html', + styleUrls: ['./file.component.scss'] +}) +export class FileComponent { + + @Input() file: FileResource; + + readonly fileLinkRel = FileLinkRel; +} diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.html new file mode 100644 index 0000000000000000000000000000000000000000..0982f8207aebb6f7f5d44f803b08b766cc3d215a --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.html @@ -0,0 +1,11 @@ +<ng-container *ngIf="attachmentStateResource$ | async as attachmentStateResource"> + + <div class="files" *ngIf="vorgangWithEingang | hasLink: linkRel.ATTACHMENTS; else emptyAnhaenge"> + <goofy-client-anhaenge data-test-id="anhaenge" [attachmentList]="attachmentStateResource.resource"></goofy-client-anhaenge> + </div> + + <ng-template #emptyAnhaenge> + <p data-test-id="empty-anhaenge">keine Anhänge vorhanden</p> + </ng-template> + +</ng-container> \ No newline at end of file diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.scss b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..35fb962dd31b4a692426f0849a2f050343508e68 --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.scss @@ -0,0 +1,10 @@ +.files { + display: flex; + flex-direction: column; + max-width: 100%; + align-items: flex-start; +} + +p { + color: #999; +} diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.spec.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..aedb20344d3f71cebb20fc3ca7b5d069a3a62e03 --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.spec.ts @@ -0,0 +1,96 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { createEmptyStateResource, HasLinkPipe } from '@goofy-client/tech-shared'; +import { mock } from '@goofy-client/test-utils'; +import { VorgangService, VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@goofy-client/vorgang-shared'; +import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; +import { MockComponent } from 'ng-mocks'; +import { of } from 'rxjs'; +import { AnhaengeComponent } from './anhaenge/anhaenge.component'; +import { AnhangListContainerComponent } from './anhang-list-container.component'; + +describe('AnhangListContainerComponent', () => { + let component: AnhangListContainerComponent; + let fixture: ComponentFixture<AnhangListContainerComponent>; + + const eingangWithAttachment: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.ATTACHMENTS]); + const eingangWithoutAttachment: VorgangWithEingangResource = createVorgangWithEingangResource(); + + const vorgangService = mock(VorgangService); + + const emptyAnhaenge: string = "[data-test-id='empty-anhaenge']"; + const anhaenge: string = "[data-test-id='anhaenge']"; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ + AnhangListContainerComponent, + HasLinkPipe, + MockComponent(AnhaengeComponent) + ], + providers: [ + { + provide: VorgangService, + useValue: vorgangService + } + ] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(AnhangListContainerComponent); + component = fixture.componentInstance; + component.attachmentStateResource$ = of(createEmptyStateResource()); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('on vorgang with "attachment" link', () => { + + beforeEach(() => { + setVorgang(eingangWithAttachment); + }) + + it('should attachments visible', () => { + expectInstanceOfHtmlElement(fixture, anhaenge); + }) + + it('should empty attachments not visible', () => { + expectNotInstanceOfHtmlElement(fixture, emptyAnhaenge); + }) + }) + + describe('on vorgang without "attachment" link', () => { + + beforeEach(() => { + setVorgang(eingangWithoutAttachment); + }) + + it('should attachments not visible', () => { + expectNotInstanceOfHtmlElement(fixture, anhaenge); + }) + + it('should empty attachments visible', () => { + expectInstanceOfHtmlElement(fixture, emptyAnhaenge); + }) + }) + + function setVorgang(vorgang: VorgangWithEingangResource): void { + component.vorgangWithEingang = vorgang; + fixture.detectChanges(); + } + + function expectInstanceOfHtmlElement(fixture: ComponentFixture<any>, selector: string): void { + const element = fixture.nativeElement.querySelector(selector); + + expect(element).toBeInstanceOf(HTMLElement); + } + + function expectNotInstanceOfHtmlElement(fixture: ComponentFixture<any>, selector: string): void { + const element = fixture.nativeElement.querySelector(selector); + + expect(element).not.toBeInstanceOf(HTMLElement); + } +}); diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..812595100b1647d61d5afa34449a869c8539aa50 --- /dev/null +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component.ts @@ -0,0 +1,25 @@ +import { Component, Input, OnChanges } from '@angular/core'; +import { FileListResource } from '@goofy-client/file-shared'; +import { StateResource } from '@goofy-client/tech-shared'; +import { VorgangService, VorgangWithEingangLinkRel, VorgangWithEingangResource } from '@goofy-client/vorgang-shared'; +import { Observable } from 'rxjs'; + +@Component({ + selector: 'goofy-client-anhang-list-container', + templateUrl: './anhang-list-container.component.html', + styleUrls: ['./anhang-list-container.component.scss'] +}) +export class AnhangListContainerComponent implements OnChanges{ + + @Input() vorgangWithEingang: VorgangWithEingangResource; + + readonly linkRel = VorgangWithEingangLinkRel; + + attachmentStateResource$: Observable<StateResource<FileListResource>>; + + constructor(private vorgangService: VorgangService) { } + + ngOnChanges(): void { + this.attachmentStateResource$ = this.vorgangService.getAttachments(); + } +} \ No newline at end of file diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html index 4d54736465ebd7824e4d86cbc3d1313a95243e17..8882f074d8540537abaf636ba5fd689807cb3d71 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.html @@ -14,7 +14,7 @@ <div class="section"> <goofy-client-expansion-panel headline="Anhänge"> - <goofy-client-anhaenge [vorgangWithEingang]="vorgangStateResource.resource"></goofy-client-anhaenge> + <goofy-client-anhang-list-container [vorgangWithEingang]="vorgangStateResource.resource"></goofy-client-anhang-list-container> </goofy-client-expansion-panel> <goofy-client-expansion-panel headline="Vorgang weiterleiten" data-test-id="redirect-area" diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts index f7c82830d99f0b154b1eaf4ce3a935af82cd31d0..1f21120b42898423f2a35d815fb30011196326cb 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component.spec.ts @@ -7,7 +7,7 @@ import { SpinnerComponent } from 'libs/ui/src/lib/ui/spinner/spinner.component'; import { createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { MockComponent } from 'ng-mocks'; import { ToEmbeddedResourcesPipe } from '../../../../../tech-shared/src/lib/pipes/embedded-resource'; -import { AnhaengeComponent } from './anhaenge/anhaenge.component'; +import { AnhangListContainerComponent } from './anhang-list-container/anhang-list-container.component'; import { VorgangDetailAreaComponent } from './vorgang-detail-area.component'; import { VorgangDetailBodyComponent } from './vorgang-detail-body/vorgang-detail-body.component'; import { VorgangDetailFormularButtonsComponent } from './vorgang-detail-formular-buttons/vorgang-detail-formular-buttons.component'; @@ -34,7 +34,7 @@ describe('VorgangDetailAreaComponent', () => { MockComponent(ButtonWithSpinnerComponent), MockComponent(WiedervorlageListInVorgangContainerComponent), MockComponent(VorgangRedirectContainerComponent), - MockComponent(AnhaengeComponent), + MockComponent(AnhangListContainerComponent), HasLinkPipe, ToEmbeddedResourcesPipe ] diff --git a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts index 1306e5f548ac3d811612fb0481118211cf7680c6..7ca61ccf36527c9ea08a38a9aa30afa3ef420c8e 100644 --- a/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts +++ b/goofy-client/libs/vorgang-detail/src/lib/vorgang-detail.module.ts @@ -5,8 +5,9 @@ import { TechSharedModule } from '@goofy-client/tech-shared'; import { UiModule } from '@goofy-client/ui'; import { VorgangSharedModule } from '@goofy-client/vorgang-shared'; import { WiedervorlageModule } from '@goofy-client/wiedervorlage'; -import { AnhaengeComponent } from './vorgang-detail-page/vorgang-detail-area/anhaenge/anhaenge.component'; -import { FileComponent } from './vorgang-detail-page/vorgang-detail-area/anhaenge/file/file.component'; +import { AnhaengeComponent } from './vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/anhaenge.component'; +import { FileComponent } from './vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhaenge/file/file.component'; +import { AnhangListContainerComponent } from './vorgang-detail-page/vorgang-detail-area/anhang-list-container/anhang-list-container.component'; import { VorgangDetailActionButtonsComponent } from './vorgang-detail-page/vorgang-detail-area/vorgang-detail-action-buttons/vorgang-detail-action-buttons.component'; import { VorgangDetailAreaComponent } from './vorgang-detail-page/vorgang-detail-area/vorgang-detail-area.component'; import { AntragstellerComponent } from './vorgang-detail-page/vorgang-detail-area/vorgang-detail-body/antragsteller/antragsteller.component'; @@ -46,7 +47,8 @@ const routes: Routes = [ VorgangDetailFormularButtonsComponent, VorgangRedirectContainerComponent, AnhaengeComponent, - FileComponent + FileComponent, + AnhangListContainerComponent ] }) export class VorgangDetailModule { } diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang-shared.module.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang-shared.module.ts index bbc265557583bbaf3b1c4ec9dd6eccffcd75ed1d..f6bc76513d9edb9e381d133b8a71a98ec4e97a39 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang-shared.module.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang-shared.module.ts @@ -1,6 +1,7 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { CommandSharedModule } from '@goofy-client/command-shared'; +import { FileSharedModule } from '@goofy-client/file-shared'; import { TechSharedModule } from '@goofy-client/tech-shared'; import { RestModule } from '@ngxp/rest'; import { AktenzeichenComponent } from './aktenzeichen/aktenzeichen.component'; @@ -11,7 +12,8 @@ import { StatusDotComponent } from './status-dot/status-dot.component'; CommonModule, RestModule, TechSharedModule, - CommandSharedModule + CommandSharedModule, + FileSharedModule ], declarations: [ StatusDotComponent, diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.spec.ts index ce775437a2a7fd468278ffd3eb4c008dade3ff43..09b8474d6c51fab3210ea07c129855fa690ef729 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.spec.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.spec.ts @@ -1,20 +1,22 @@ import { ApiRootResource, ApiRootSharedLinkrels } from '@goofy-client/api-root-shared'; import { mock, useFromMock } from '@goofy-client/test-utils'; import { getUrl, ResourceFactory } from '@ngxp/rest'; -import { ResourceWrapper } from '@ngxp/rest/lib/resource-wrapper'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; -import { createVorgangListResource, createVorgangWithEingangResource, createVorgangResource } from 'libs/vorgang-shared/test/vorgang'; -import { VorgangHeaderLinkRel, VorgangListLinkRel } from './vorgang.linkrels'; -import { VorgangListResource, VorgangWithEingangResource, VorgangResource } from './vorgang.model'; +import { createVorgangListResource, createVorgangResource, createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; +import { VorgangHeaderLinkRel, VorgangListLinkRel, VorgangWithEingangLinkRel } from './vorgang.linkrels'; +import { VorgangListResource, VorgangResource, VorgangWithEingangResource } from './vorgang.model'; import { VorgangRepository } from './vorgang.repository'; describe('VorgangRepository', () => { let repository: VorgangRepository; let resourceFactory = mock(ResourceFactory); - let resourceWrapper: ResourceWrapper = <any>{ get: jest.fn() }; + let resourceWrapper = { get: jest.fn() }; beforeEach(() => { repository = new VorgangRepository(useFromMock(resourceFactory)); + + resourceFactory.fromId.mockReturnValue(resourceWrapper); + resourceFactory.from.mockReturnValue(resourceWrapper); }) describe('loadVorgangList', () => { @@ -22,8 +24,7 @@ describe('VorgangRepository', () => { const apiRootResource: ApiRootResource = createApiRootResource(); beforeEach(() => { - (<any>resourceFactory).from.mockReturnValue(resourceWrapper); - (<any>resourceWrapper).get.mockReturnValue(vorgangListResource); + resourceWrapper.get.mockReturnValue(vorgangListResource); }) it('should call resourceFactory with resource', () => { @@ -50,8 +51,7 @@ describe('VorgangRepository', () => { const vorgangListResource: VorgangListResource = createVorgangListResource([VorgangListLinkRel.NEXT]); beforeEach(() => { - (<any>resourceFactory).from.mockReturnValue(resourceWrapper); - (<any>resourceWrapper).get.mockReturnValue(vorgangListResource); + resourceWrapper.get.mockReturnValue(vorgangListResource); }) it('should call resourceFactory with resource', () => { @@ -80,8 +80,7 @@ describe('VorgangRepository', () => { const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource(); beforeEach(() => { - (<any>resourceFactory).fromId.mockReturnValue(resourceWrapper); - (<any>resourceWrapper).get.mockReturnValue(vorgangWithEingangResource); + resourceWrapper.get.mockReturnValue(vorgangWithEingangResource); }) it('should call resourceFactory with resource', () => { @@ -103,4 +102,32 @@ describe('VorgangRepository', () => { expect(result).toBe(vorgangWithEingangResource); }) }) + + describe('getAttachments', () => { + + const vorgangWithEingangResource: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.ATTACHMENTS]); + + beforeEach(() => { + resourceWrapper.get.mockReturnValue(vorgangWithEingangResource); + }) + + it('should call resourceFactory with resource', () => { + repository.getAttachments(vorgangWithEingangResource); + + expect(resourceFactory.from).toHaveBeenCalledWith(vorgangWithEingangResource); + }) + + it('should call resourceWrapper with link', () => { + repository.getAttachments(vorgangWithEingangResource); + + expect(resourceWrapper.get).toHaveBeenCalledWith(VorgangWithEingangLinkRel.ATTACHMENTS) + }) + + it('should return result', () => { + let result = repository.getAttachments(vorgangWithEingangResource); + + expect(result).not.toBeNull(); + expect(result).toBe(vorgangWithEingangResource); + }) + }) }) diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.ts index a1702d39b31453c55fa4932d6dbc8052e09ad459..cd971924ebfe406085bea02eac2f11e53f9bb6fd 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang.repository.ts @@ -1,8 +1,9 @@ import { Injectable } from '@angular/core'; import { ApiRootResource, ApiRootSharedLinkrels } from '@goofy-client/api-root-shared'; +import { FileListResource } from '@goofy-client/file-shared'; import { ResourceFactory, ResourceUri } from '@ngxp/rest'; import { Observable } from 'rxjs/internal/Observable'; -import { VorgangListLinkRel } from './vorgang.linkrels'; +import { VorgangListLinkRel, VorgangWithEingangLinkRel } from './vorgang.linkrels'; import { VorgangListResource, VorgangWithEingangResource } from './vorgang.model'; @Injectable({ providedIn: 'root' }) @@ -20,4 +21,8 @@ export class VorgangRepository { public getVorgang(vorgangWithEingangUrl: ResourceUri): Observable<VorgangWithEingangResource> { return this.resourceFactory.fromId(vorgangWithEingangUrl).get(); } + + public getAttachments(vorgang: VorgangWithEingangResource): Observable<FileListResource> { + return this.resourceFactory.from(vorgang).get(VorgangWithEingangLinkRel.ATTACHMENTS); + } } diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts index 741b5396e615c694735c6453a5e68593beaa8f4f..b593f5eaa99fe29734487372b8561e33859f1838 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.spec.ts @@ -10,6 +10,7 @@ import { ApiRootService } from 'libs/api-root-shared/src/lib/api-root.service'; import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; import { CommandLinkRel } from 'libs/command-shared/src/lib/command.linkrel'; import { createCommandResource } from 'libs/command-shared/test/command'; +import { createFileListResource } from 'libs/file-shared/test/file'; import { createVorgangListResource, createVorgangResource, createVorgangWithEingangResource } from 'libs/vorgang-shared/test/vorgang'; import { of } from 'rxjs'; import { VorgangListLinkRel, VorgangWithEingangLinkRel } from './vorgang.linkrels'; @@ -404,6 +405,7 @@ describe('VorgangService', () => { beforeEach(() => { service.loadPendingCommandsByVorgang = jest.fn(); + service.loadAttachments = jest.fn(); }) it('should load pendingCommands', () => { @@ -411,42 +413,72 @@ describe('VorgangService', () => { expect(service.loadPendingCommandsByVorgang).toHaveBeenCalled(); }) - }) - - describe('loadPendingCommandsByVorgang', () => { - const vorgangWithEingang = createVorgangWithEingangResource([VorgangWithEingangLinkRel.PENDING_COMMANDS]); - - beforeEach(() => { - commandService.getPendingCommands = jest.fn(); - commandService.getPendingCommands.mockReturnValue(of(createCommandResource())); - - service.clearPendingCommands = jest.fn(); - }) - it('should call commandService', () => { - service.loadPendingCommandsByVorgang(vorgangWithEingang); - - expect(commandService.getPendingCommands).toHaveBeenCalledWith(vorgangWithEingang, VorgangWithEingangLinkRel.PENDING_COMMANDS); - }); - - it('should clear pendingCommands on Navigation', () => { - service.onNavigation({}); + it('should load attachments', () => { + service.updateVorgang(createVorgangWithEingangResource()); - expect(service.clearPendingCommands).toHaveBeenCalled(); + expect(service.loadAttachments).toHaveBeenCalled(); }) }) - + describe('on leaving vorgang detail page', () => { it('should clear vorgang', () => { (<any>service).vorgangWithEingang$.next(createVorgangWithEingangResource()); - + service.onNavigation({}); - + expect((<any>service).vorgangWithEingang$.value).toStrictEqual(createEmptyStateResource()); }); }); }); + describe('loadPendingCommandsByVorgang', () => { + const vorgangWithEingang = createVorgangWithEingangResource([VorgangWithEingangLinkRel.PENDING_COMMANDS]); + + beforeEach(() => { + commandService.getPendingCommands = jest.fn(); + commandService.getPendingCommands.mockReturnValue(of(createCommandResource())); + + service.clearPendingCommands = jest.fn(); + }) + + it('should call commandService', () => { + service.loadPendingCommandsByVorgang(vorgangWithEingang); + + expect(commandService.getPendingCommands).toHaveBeenCalledWith(vorgangWithEingang, VorgangWithEingangLinkRel.PENDING_COMMANDS); + }); + + it('should clear pendingCommands on Navigation', () => { + service.onNavigation({}); + + expect(service.clearPendingCommands).toHaveBeenCalled(); + }) + }) + + describe('loadAttachments', () => { + + beforeEach(() => { + repository.getAttachments.mockReturnValue(of(createFileListResource())); + service.doRepositoryCall = jest.fn(); + }) + + it('should call repository', () => { + const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource([VorgangWithEingangLinkRel.ATTACHMENTS]); + + service.loadAttachments(vorgang); + + expect(service.doRepositoryCall).toHaveBeenCalledWith(service.getAttachments(), repository.getAttachments(vorgang)); + }) + + it('should NOT call repository', () => { + const vorgang: VorgangWithEingangResource = createVorgangWithEingangResource(); + + service.loadAttachments(vorgang); + + expect(service.doRepositoryCall).not.toHaveBeenCalled(); + }) + }) + describe('addVorgangListToVorgaenge', () => { const vorgangResource: VorgangResource = createVorgangResource(); diff --git a/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts b/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts index 807b2162be383d53eed44681b01a63485aa54892..f15656fa1df1540439e20c263e8674a566289be2 100644 --- a/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts +++ b/goofy-client/libs/vorgang-shared/src/lib/vorgang.service.ts @@ -2,6 +2,7 @@ import { Injectable } from '@angular/core'; import { Params } from '@angular/router'; import { ApiRootResource } from '@goofy-client/api-root-shared'; import { CommandListResource, CommandResource, CommandService, CreateCommand, isDone } from '@goofy-client/command-shared'; +import { FileListResource } from '@goofy-client/file-shared'; import { createEmptyStateResource, createStateResource, doIfLoadingRequired, NavigationService, StateResource } from '@goofy-client/tech-shared'; import { SnackBarService } from '@goofy-client/ui'; import { getUrl, hasLink, ResourceUri } from '@ngxp/rest'; @@ -27,6 +28,8 @@ export class VorgangService { private readonly revokeCommand$: BehaviorSubject<StateResource<CommandResource>> = new BehaviorSubject(createEmptyStateResource()); private readonly pendingCommands$: BehaviorSubject<StateResource<CommandListResource>> = new BehaviorSubject(createEmptyStateResource()); + private readonly attachments$: BehaviorSubject<StateResource<FileListResource>> = new BehaviorSubject(createEmptyStateResource()); + private subscription: Subscription; public static readonly vorgangWithEingangUrl: string = 'vorgangWithEingangUrl'; @@ -64,11 +67,11 @@ export class VorgangService { return this.vorgangWithEingang$; } - private getVorgangWithEingangUrl(): ResourceUri { + private getVorgangWithEingangUrl(): ResourceUri { return this.navigationService.getDecodedParam(VorgangService.vorgangWithEingangUrl); } - reloadCurrentVorgang(){ + reloadCurrentVorgang(): void{ this.loadVorgangWithEingang(this.navigationService.getDecodedParam(VorgangService.vorgangWithEingangUrl)); } @@ -80,22 +83,49 @@ export class VorgangService { updateVorgang(vorgang: VorgangWithEingangResource): void { this.vorgangWithEingang$.next(createStateResource(vorgang)); this.loadPendingCommandsByVorgang(vorgang); + this.loadAttachments(vorgang); } - loadPendingCommandsByVorgang(vorgang: VorgangWithEingangResource) { - if (hasLink(vorgang, VorgangWithEingangLinkRel.PENDING_COMMANDS)){ + loadPendingCommandsByVorgang(vorgang: VorgangWithEingangResource): void { + if (this.hasPendingCommands(vorgang)){ this.setStateResourceOnLoading(this.pendingCommands$); - const subscription: Subscription = this.commandService.getPendingCommands(vorgang, VorgangWithEingangLinkRel.PENDING_COMMANDS).subscribe((pendingCommands) => { - this.pendingCommands$.next(pendingCommands); + const subscription: Subscription = this.commandService.getPendingCommands(vorgang, VorgangWithEingangLinkRel.PENDING_COMMANDS).subscribe(result => { + this.pendingCommands$.next(result); subscription.unsubscribe(); }) } } + private hasPendingCommands(vorgang: VorgangWithEingangResource): boolean { + return hasLink(vorgang, VorgangWithEingangLinkRel.PENDING_COMMANDS); + } + setStateResourceOnLoading(stateResource$: BehaviorSubject<StateResource<any>>): void { stateResource$.next({ ...stateResource$.value, loading: true }); } + loadAttachments(vorgang: VorgangWithEingangResource): void{ + if (this.hasAttachments(vorgang)){ + this.doRepositoryCall(this.attachments$, this.vorgangRepository.getAttachments(vorgang)); + } + } + + doRepositoryCall(stateSubject: BehaviorSubject<StateResource<FileListResource>>, repositoryCall: Observable<any>): void { + this.setStateResourceOnLoading(stateSubject); + const subscription: Subscription = repositoryCall.subscribe(result => { + stateSubject.next(createStateResource(result)); + subscription.unsubscribe(); + }) + } + + private hasAttachments(vorgang: VorgangWithEingangResource): boolean { + return hasLink(vorgang, VorgangWithEingangLinkRel.ATTACHMENTS); + } + + getAttachments(): Observable<StateResource<FileListResource>> { + return this.attachments$; + } + private listenForLeavingVorgang(): void { this.unsubscribe(); this.subscription = this.navigationService.urlChanged().subscribe(params => this.onNavigation(params)); diff --git a/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts b/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts index b9bb44cb1ef859d3c7d6e2abbfbd948c344ccfc5..6d148c3f0622673b87c8657c9a7ec9052757b2a8 100644 --- a/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts +++ b/goofy-client/libs/wiedervorlage-shared/src/lib/wiedervorlage.service.ts @@ -24,7 +24,7 @@ export class WiedervorlageService implements OnDestroy { readonly wiedervorlageList$: BehaviorSubject<StateResource<WiedervorlageListResource>> = new BehaviorSubject<StateResource<WiedervorlageListResource>>(createEmptyStateResource()); readonly wiedervorlage$: BehaviorSubject<StateResource<WiedervorlageResource>> = new BehaviorSubject<StateResource<WiedervorlageResource>>(createEmptyStateResource()); - subscription: Subscription; + private subscription: Subscription; constructor( private repository: WiedervorlageRepository, diff --git a/goofy-client/nx.json b/goofy-client/nx.json index 8a6a4507491638d37282ca5f4ee343ca3a5a1f5c..5f194aad0598012f0f863f2ba9e87109daac29f8 100644 --- a/goofy-client/nx.json +++ b/goofy-client/nx.json @@ -30,6 +30,7 @@ "vorgang-detail": { "tags": [] }, "command-shared": { "tags": [] }, "wiedervorlage-shared": { "tags": [] }, - "wiedervorlage": { "tags": [] } + "wiedervorlage": { "tags": [] }, + "file-shared": { "tags": [] } } } diff --git a/goofy-client/package.json b/goofy-client/package.json index c197213b86b95d6f865762a93165cedeec64b1d8..23ccedb799db9e711ee875cd814224b0b488353d 100644 --- a/goofy-client/package.json +++ b/goofy-client/package.json @@ -1,115 +1,115 @@ { - "name": "goofy-client", - "version": "0.0.0", - "license": "MIT", - "scripts": { - "nx": "nx", - "ng": "nx", - "postinstall": "node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points", - "start": "run-s \"nx -- serve --port 4300 --disable-host-check --proxy-config proxy.conf.json\" --", - "start:devbe": "run-s \"nx -- serve --port 4300 --disable-host-check --proxy-config proxy.dev.conf.json\" --", - "build": "ng build", - "test": "jest test a", - "test:cov": "jest --coverage", - "test:lib": "run-s \"ng -- test {1} --watchAll\" --", - "test:debug:lib": "run-s \"ng -- test {1} --detectOpenHandles --watchAll\" --", - "ci-build": "ng build --outputHashing=all", - "ci-prodBuild": "ng build --prod --outputHashing=all --prod", - "ci-test": "jest test a --ci --coverage --testResultsProcessor='jest-sonar-reporter'", - "ci-sonar": "sonar-scanner", - "lint": "nx workspace-lint && ng lint", - "affected:apps": "nx affected:apps", - "affected:libs": "nx affected:libs", - "affected:build": "nx affected:build", - "affected:e2e": "nx affected:e2e", - "affected:test": "nx affected:test", - "affected:lint": "nx affected:lint", - "affected:dep-graph": "nx affected:dep-graph", - "affected": "nx affected", - "format": "nx format:write", - "format:write": "nx format:write", - "format:check": "nx format:check", - "update": "ng update @nrwl/workspace", - "dep-graph": "nx dep-graph", - "help": "nx help", - "favicon": "real-favicon generate favicon/faviconDescription.json favicon/faviconData.json src/favicon", - "cypress:open": "npx cypress open --project apps/goofy-e2e", - "cypress:run": "npx cypress run --project apps/goofy-e2e", - "cypress:version": "npx cypress version", - "cypress:merge-report": "mochawesome-merge apps/goofy-e2e/reports/mochawesome-report/*.json > apps/goofy-e2e/reports/report.json", - "cypress:generate-html": "marge apps/goofy-e2e/reports/report.json -f report -o apps/goofy-e2e/reports/", - "cypress:delete-old-reports": "node apps/goofy-e2e/src/support/delete-old-reports.ts", - "cypress:generate-report": "npm run cypress:merge-report ; npm run cypress:generate-html", - "cypress:ci-run": "npm run cypress:delete-old-reports ; npm run cypress:run -- --config-file ./cypress-ci.json ; test=$(echo \"$?\") ; npm run cypress:generate-report ; exit $test", - "workspace-generator": "nx workspace-generator", - "sonar-scanner": "jest test a --coverage --testResultsProcessor='jest-sonar-reporter' && sonar-scanner -Dsonar.host.url=https://sonarqube.ozg-sh.de/ -Dsonar.login=25dfb9ee83a79b0f4af445c63405651fcf391ee8" - }, - "private": true, - "dependencies": { - "@angular/animations": "11.1.2", - "@angular/cdk": "^11.1.2", - "@angular/common": "11.1.2", - "@angular/compiler": "11.1.2", - "@angular/core": "11.1.2", - "@angular/forms": "11.1.2", - "@angular/material": "^11.1.2", - "@angular/material-moment-adapter": "^11.2.3", - "@angular/platform-browser": "11.1.2", - "@angular/platform-browser-dynamic": "11.1.2", - "@angular/router": "11.1.2", - "@ngxp/rest": "^4.0.0", - "@nrwl/angular": "11.2.12", - "angular-oauth2-oidc": "^10.0.3", - "angular-oauth2-oidc-jwks": "^9.0.0", - "faker": "^5.4.0", - "include-media": "^1.4.9", - "lodash-es": "^4.17.21", - "material-design-icons-iconfont": "^6.1.0", - "mongodb": "^3.6.3", - "ng-mocks": "^11.9.0", - "rxjs": "~6.5.5", - "tslib": "^2.0.0", - "typeface-roboto": "^1.1.13", - "whatwg-fetch": "^3.6.2", - "zone.js": "^0.10.2" - }, - "devDependencies": { - "@angular-devkit/build-angular": "0.1100.7", - "@angular-eslint/eslint-plugin": "~1.0.0", - "@angular-eslint/eslint-plugin-template": "~1.0.0", - "@angular-eslint/template-parser": "~1.0.0", - "@angular/cli": "11.0.7", - "@angular/compiler-cli": "11.1.2", - "@angular/language-service": "11.1.2", - "@nrwl/cli": "11.2.12", - "@nrwl/cypress": "11.2.12", - "@nrwl/eslint-plugin-nx": "11.2.12", - "@nrwl/jest": "11.2.12", - "@nrwl/workspace": "11.2.12", - "@testing-library/jest-dom": "^5.11.9", - "@types/jest": "26.0.8", - "@types/lodash-es": "^4.17.3", - "@types/node": "12.12.38", - "@typescript-eslint/eslint-plugin": "4.3.0", - "@typescript-eslint/parser": "4.3.0", - "codelyzer": "6.0.1", - "cypress": "^6.6.0", - "cypress-mochawesome-reporter": "^1.3.0", - "dotenv": "6.2.0", - "eslint": "7.10.0", - "eslint-config-prettier": "6.0.0", - "eslint-plugin-cypress": "^2.10.3", - "jest": "^26.2.2", - "jest-createspyobj": "^2.0.0", - "jest-junit": "^12.0.0", - "jest-marbles": "^2.5.1", - "jest-preset-angular": "8.3.2", - "jest-sonar-reporter": "^2.0.0", - "prettier": "2.2.1", - "sonarqube-scanner": "^2.8.0", - "ts-jest": "26.4.0", - "ts-node": "9.1.1", - "tslint": "6.1.3", - "typescript": "^4.0.7" - } + "name": "goofy-client", + "version": "0.0.0", + "license": "MIT", + "scripts": { + "nx": "nx", + "ng": "nx", + "postinstall": "node ./decorate-angular-cli.js && ngcc --properties es2015 browser module main --first-only --create-ivy-entry-points", + "start": "run-s \"nx -- serve --port 4300 --disable-host-check --proxy-config proxy.conf.json\" --", + "start:devbe": "run-s \"nx -- serve --port 4300 --disable-host-check --proxy-config proxy.dev.conf.json\" --", + "build": "ng build", + "test": "jest test a", + "test:cov": "jest --coverage", + "test:lib": "run-s \"ng -- test {1} --watchAll\" --", + "test:debug:lib": "run-s \"ng -- test {1} --detectOpenHandles --watchAll\" --", + "ci-build": "ng build --outputHashing=all", + "ci-prodBuild": "ng build --prod --outputHashing=all --prod", + "ci-test": "jest test a --ci --coverage --testResultsProcessor='jest-sonar-reporter'", + "ci-sonar": "sonar-scanner", + "lint": "nx workspace-lint && ng lint", + "affected:apps": "nx affected:apps", + "affected:libs": "nx affected:libs", + "affected:build": "nx affected:build", + "affected:e2e": "nx affected:e2e", + "affected:test": "nx affected:test", + "affected:lint": "nx affected:lint", + "affected:dep-graph": "nx affected:dep-graph", + "affected": "nx affected", + "format": "nx format:write", + "format:write": "nx format:write", + "format:check": "nx format:check", + "update": "ng update @nrwl/workspace", + "dep-graph": "nx dep-graph", + "help": "nx help", + "favicon": "real-favicon generate favicon/faviconDescription.json favicon/faviconData.json src/favicon", + "cypress:open": "npx cypress open --project apps/goofy-e2e", + "cypress:run": "npx cypress run --project apps/goofy-e2e", + "cypress:version": "npx cypress version", + "cypress:merge-report": "mochawesome-merge apps/goofy-e2e/reports/mochawesome-report/*.json > apps/goofy-e2e/reports/report.json", + "cypress:generate-html": "marge apps/goofy-e2e/reports/report.json -f report -o apps/goofy-e2e/reports/", + "cypress:delete-old-reports": "node apps/goofy-e2e/src/support/delete-old-reports.ts", + "cypress:generate-report": "npm run cypress:merge-report ; npm run cypress:generate-html", + "cypress:ci-run": "npm run cypress:delete-old-reports ; npm run cypress:run -- --config-file ./cypress-ci.json ; test=$(echo \"$?\") ; npm run cypress:generate-report ; exit $test", + "workspace-generator": "nx workspace-generator", + "sonar-scanner": "jest test a --coverage --testResultsProcessor='jest-sonar-reporter' && sonar-scanner -Dsonar.host.url=https://sonarqube.ozg-sh.de/ -Dsonar.login=25dfb9ee83a79b0f4af445c63405651fcf391ee8" + }, + "private": true, + "dependencies": { + "@angular/animations": "11.1.2", + "@angular/cdk": "^11.1.2", + "@angular/common": "11.1.2", + "@angular/compiler": "11.1.2", + "@angular/core": "11.1.2", + "@angular/forms": "11.1.2", + "@angular/material": "^11.1.2", + "@angular/material-moment-adapter": "^11.2.3", + "@angular/platform-browser": "11.1.2", + "@angular/platform-browser-dynamic": "11.1.2", + "@angular/router": "11.1.2", + "@ngxp/rest": "^4.0.0", + "@nrwl/angular": "11.2.12", + "angular-oauth2-oidc": "^10.0.3", + "angular-oauth2-oidc-jwks": "^9.0.0", + "faker": "^5.4.0", + "include-media": "^1.4.9", + "lodash-es": "^4.17.21", + "material-design-icons-iconfont": "^6.1.0", + "mongodb": "^3.6.3", + "ng-mocks": "^11.9.0", + "rxjs": "~6.5.5", + "tslib": "^2.0.0", + "typeface-roboto": "^1.1.13", + "whatwg-fetch": "^3.6.2", + "zone.js": "^0.10.2" + }, + "devDependencies": { + "@angular-devkit/build-angular": "0.1100.7", + "@angular-eslint/eslint-plugin": "~1.0.0", + "@angular-eslint/eslint-plugin-template": "~1.0.0", + "@angular-eslint/template-parser": "~1.0.0", + "@angular/cli": "11.0.7", + "@angular/compiler-cli": "11.1.2", + "@angular/language-service": "11.1.2", + "@nrwl/cli": "11.2.12", + "@nrwl/cypress": "11.2.12", + "@nrwl/eslint-plugin-nx": "11.2.12", + "@nrwl/jest": "11.2.12", + "@nrwl/workspace": "11.2.12", + "@testing-library/jest-dom": "^5.11.9", + "@types/jest": "26.0.8", + "@types/lodash-es": "^4.17.3", + "@types/node": "12.12.38", + "@typescript-eslint/eslint-plugin": "4.3.0", + "@typescript-eslint/parser": "4.3.0", + "codelyzer": "6.0.1", + "cypress": "^6.6.0", + "cypress-mochawesome-reporter": "^1.3.0", + "dotenv": "6.2.0", + "eslint": "7.10.0", + "eslint-config-prettier": "6.0.0", + "eslint-plugin-cypress": "^2.10.3", + "jest": "^26.2.2", + "jest-createspyobj": "^2.0.0", + "jest-junit": "^12.0.0", + "jest-marbles": "^2.5.1", + "jest-preset-angular": "8.3.2", + "jest-sonar-reporter": "^2.0.0", + "prettier": "2.2.1", + "sonarqube-scanner": "^2.8.0", + "ts-jest": "26.4.0", + "ts-node": "9.1.1", + "tslint": "6.1.3", + "typescript": "^4.0.7" + } } diff --git a/goofy-client/tsconfig.base.json b/goofy-client/tsconfig.base.json index f945eed2c2923e39a1a47da7f669946547eafa4d..e274f82cf1d55b23480fc6a732aec11649f868da 100644 --- a/goofy-client/tsconfig.base.json +++ b/goofy-client/tsconfig.base.json @@ -32,7 +32,8 @@ "@goofy-client/wiedervorlage-shared": [ "libs/wiedervorlage-shared/src/index.ts" ], - "@goofy-client/wiedervorlage": ["libs/wiedervorlage/src/index.ts"] + "@goofy-client/wiedervorlage": ["libs/wiedervorlage/src/index.ts"], + "@goofy-client/file-shared": ["libs/file-shared/src/index.ts"] } }, "exclude": ["node_modules", "tmp"]