-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: list resource templates (#821)
- Loading branch information
1 parent
e2d6e3e
commit 5e7e672
Showing
20 changed files
with
476 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
export interface ResourceTemplate { | ||
id: number; | ||
relatedResourceIdentifier: string; | ||
name: string; | ||
targetPath: string; | ||
targetPlatforms: string[]; | ||
fileContent: string; | ||
sourceType?: 'RESOURCE' | 'RESOURCE_TYPE'; | ||
} |
55 changes: 55 additions & 0 deletions
55
AMW_angular/io/src/app/resource/resource-templates.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { Injectable } from '@angular/core'; | ||
import { HttpClient } from '@angular/common/http'; | ||
import { ResourceTemplate } from './resource-template'; | ||
import { catchError, shareReplay, switchMap } from 'rxjs/operators'; | ||
import { Observable, Subject } from 'rxjs'; | ||
import { BaseService } from '../base/base.service'; | ||
import { toSignal } from '@angular/core/rxjs-interop'; | ||
|
||
@Injectable({ providedIn: 'root' }) | ||
export class ResourceTemplatesService extends BaseService { | ||
private templates$: Subject<number> = new Subject<number>(); | ||
private templatesForType$: Subject<number> = new Subject<number>(); | ||
|
||
private templateById$: Observable<ResourceTemplate[]> = this.templates$.pipe( | ||
switchMap((id: number) => this.getResourceTemplates(id)), | ||
shareReplay(1), | ||
); | ||
|
||
private templateByTypeId$: Observable<ResourceTemplate[]> = this.templatesForType$.pipe( | ||
switchMap((id: number) => this.getResourceTypeTemplates(id)), | ||
shareReplay(1), | ||
); | ||
|
||
resourceTemplates = toSignal(this.templateById$, { initialValue: [] }); | ||
|
||
resourceTypeTemplates = toSignal(this.templateByTypeId$, { initialValue: [] }); | ||
|
||
constructor(private http: HttpClient) { | ||
super(); | ||
} | ||
|
||
setIdForResourceTemplateList(id: number) { | ||
this.templates$.next(id); | ||
} | ||
|
||
setIdForResourceTypeTemplateList(id: number) { | ||
this.templatesForType$.next(id); | ||
} | ||
|
||
getResourceTemplates(id: number): Observable<ResourceTemplate[]> { | ||
return this.http | ||
.get<ResourceTemplate[]>(`${this.getBaseUrl()}/resources/templates/${id}`, { | ||
headers: this.getHeaders(), | ||
}) | ||
.pipe(catchError(this.handleError)); | ||
} | ||
|
||
getResourceTypeTemplates(id: number): Observable<ResourceTemplate[]> { | ||
return this.http | ||
.get<ResourceTemplate[]>(`${this.getBaseUrl()}/resources/templates/resourceType/${id}`, { | ||
headers: this.getHeaders(), | ||
}) | ||
.pipe(catchError(this.handleError)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...src/app/resources/resource-edit/resource-functions/resource-functions-list.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
...src/app/resources/resource-edit/resource-templates/resource-templates-list.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<app-loading-indicator [isLoading]="isLoading()"></app-loading-indicator> | ||
<app-tile-component | ||
[title]="'Templates'" | ||
[actionName]="'New Template'" | ||
[canAction]="permissions().canAdd" | ||
[lists]="templatesData()" | ||
(tileAction)="addTemplate()" | ||
(listAction)="doListAction($event)" | ||
></app-tile-component> |
27 changes: 27 additions & 0 deletions
27
.../app/resources/resource-edit/resource-templates/resource-templates-list.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { InputSignal, signal } from '@angular/core'; | ||
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; | ||
import { provideHttpClientTesting } from '@angular/common/http/testing'; | ||
import { ResourceTemplatesListComponent } from './resource-templates-list.component'; | ||
import { Resource } from '../../../resource/resource'; | ||
|
||
describe('ResourceTemplatesComponent', () => { | ||
let component: ResourceTemplatesListComponent; | ||
let fixture: ComponentFixture<ResourceTemplatesListComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [ResourceTemplatesListComponent], | ||
providers: [provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()], | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(ResourceTemplatesListComponent); | ||
component = fixture.componentInstance; | ||
component.resource = signal<Resource>(null) as unknown as InputSignal<Resource>; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
128 changes: 128 additions & 0 deletions
128
...o/src/app/resources/resource-edit/resource-templates/resource-templates-list.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { Component, computed, inject, input, OnDestroy } from '@angular/core'; | ||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; | ||
import { LoadingIndicatorComponent } from '../../../shared/elements/loading-indicator.component'; | ||
import { TileComponent } from '../../../shared/tile/tile.component'; | ||
import { EntryAction, TileListEntryOutput } from '../../../shared/tile/tile-list/tile-list.component'; | ||
import { Action, AuthService } from '../../../auth/auth.service'; | ||
import { Resource } from '../../../resource/resource'; | ||
import { Subject } from 'rxjs'; | ||
import { ResourceTemplatesService } from '../../../resource/resource-templates.service'; | ||
import { ResourceTemplate } from '../../../resource/resource-template'; | ||
|
||
const RESOURCE_PERM = 'RESOURCE_TEMPLATE'; | ||
const RESOURCETYPE_PERM = 'RESOURCETYPE_TEMPLATE'; | ||
|
||
@Component({ | ||
selector: 'app-resource-templates-list', | ||
standalone: true, | ||
imports: [LoadingIndicatorComponent, TileComponent], | ||
templateUrl: './resource-templates-list.component.html', | ||
}) | ||
export class ResourceTemplatesListComponent implements OnDestroy { | ||
private authService = inject(AuthService); | ||
private modalService = inject(NgbModal); | ||
private templatesService = inject(ResourceTemplatesService); | ||
private destroy$ = new Subject<void>(); | ||
|
||
resource = input.required<Resource>(); | ||
contextId = input.required<number>(); | ||
templates = this.templatesService.resourceTemplates; | ||
|
||
isLoading = computed(() => { | ||
if (this.resource() != null) { | ||
this.templatesService.setIdForResourceTemplateList(this.resource().id); | ||
return false; | ||
} | ||
}); | ||
|
||
permissions = computed(() => { | ||
if (this.authService.restrictions().length > 0 && this.resource()) { | ||
return { | ||
canShowInstanceTemplates: this.authService.hasPermission(RESOURCE_PERM, Action.READ), | ||
canShowTypeTemplates: this.authService.hasPermission(RESOURCETYPE_PERM, Action.READ), | ||
canAdd: | ||
(this.contextId() === 1 || this.contextId === null) && | ||
this.authService.hasResourceGroupPermission(RESOURCE_PERM, Action.CREATE, this.resource().resourceGroupId), | ||
canEdit: | ||
(this.contextId() === 1 || this.contextId === null) && | ||
this.authService.hasResourceGroupPermission(RESOURCE_PERM, Action.UPDATE, this.resource().resourceGroupId), | ||
canDelete: | ||
(this.contextId() === 1 || this.contextId === null) && | ||
this.authService.hasResourceGroupPermission(RESOURCE_PERM, Action.DELETE, this.resource().resourceGroupId), | ||
}; | ||
} else { | ||
return { | ||
canShowInstanceTemplates: false, | ||
canShowTypeTemplates: false, | ||
canAdd: false, | ||
canEdit: false, | ||
canDelete: false, | ||
}; | ||
} | ||
}); | ||
|
||
templatesData = computed(() => { | ||
if (this.templates()?.length > 0) { | ||
const instanceTemplates = this.mapListEntries( | ||
this.templates().filter((template) => template.sourceType === 'RESOURCE'), | ||
); | ||
const typeTemplates = this.mapListEntries( | ||
this.templates().filter((template) => template.sourceType === 'RESOURCE_TYPE'), | ||
); | ||
|
||
const result = []; | ||
if (this.permissions().canShowInstanceTemplates) { | ||
result.push({ | ||
title: 'Resource Instance Templates', | ||
entries: instanceTemplates, | ||
canEdit: this.permissions().canEdit, | ||
canDelete: this.permissions().canDelete, | ||
}); | ||
} | ||
if (this.permissions().canShowTypeTemplates) { | ||
result.push({ | ||
title: 'Resource Type Templates', | ||
entries: typeTemplates, | ||
canEdit: false, | ||
canDelete: false, | ||
}); | ||
} | ||
return result; | ||
} else return null; | ||
}); | ||
|
||
ngOnDestroy(): void { | ||
this.destroy$.next(undefined); | ||
} | ||
|
||
doListAction($event: TileListEntryOutput) { | ||
switch ($event.action) { | ||
case EntryAction.edit: | ||
this.editTemplate($event.id); | ||
return; | ||
case EntryAction.delete: | ||
this.deleteTemplate($event.id); | ||
return; | ||
} | ||
} | ||
|
||
mapListEntries(templates: ResourceTemplate[]) { | ||
return templates.map((template) => ({ | ||
name: template.name, | ||
description: template.targetPath, | ||
id: template.id, | ||
})); | ||
} | ||
|
||
addTemplate() { | ||
this.modalService.open('This would open a modal to add a new instance template'); | ||
} | ||
|
||
private editTemplate(id: number) { | ||
this.modalService.open('This would open a modal to edit template with id: ' + id); | ||
} | ||
|
||
private deleteTemplate(id: number) { | ||
this.modalService.open('This would open a modal to delete template with id: ' + id); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.