39 changed files with 959 additions and 164 deletions
@ -0,0 +1,49 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2023 The Thingsboard Authors |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
|
|||
--> |
|||
<ng-container *ngIf="simpleList; else complexEntityReferences"> |
|||
<ng-container *ngTemplateOutlet="referencesList; context:{entriesList: referencedEntitiesList, showDetailsLink: true}"></ng-container> |
|||
</ng-container> |
|||
<ng-template #complexEntityReferences> |
|||
<ng-container *ngIf="contentReady; else loading"> |
|||
<ul> |
|||
<ng-container *ngFor="let entry of referencedEntitiesEntries"> |
|||
<li *ngIf="isSystem(entry[0]); else tenantEntities"> |
|||
{{ 'image.system-entities' | translate }} |
|||
<ng-container *ngTemplateOutlet="referencesList; context:{entriesList: entry[1].entities, showDetailsLink: true}"></ng-container> |
|||
</li> |
|||
<ng-template #tenantEntities> |
|||
<li> |
|||
{{ 'tenant.tenant' | translate }} <a [routerLink]="entry[1].tenantDetailsUrl">{{ '"' + entry[1].tenantName + '"' }}</a> {{ 'image.entities' | translate }} |
|||
<ng-container *ngTemplateOutlet="referencesList; context:{entriesList: entry[1].entities, showDetailsLink: false}"></ng-container> |
|||
</li> |
|||
</ng-template> |
|||
</ng-container> |
|||
</ul> |
|||
</ng-container> |
|||
</ng-template> |
|||
<ng-template #referencesList let-entriesList="entriesList" let-showDetailsLink="showDetailsLink"> |
|||
<ul> |
|||
<li *ngFor="let referencedEntity of entriesList"> |
|||
{{ referencedEntity.typeName }} <a *ngIf="showDetailsLink" [routerLink]="referencedEntity.detailsUrl">{{ '"' + referencedEntity.entity.name + '"' }}</a> |
|||
<b *ngIf="!showDetailsLink">{{ '"' + referencedEntity.entity.name + '"' }}</b> |
|||
</li> |
|||
</ul> |
|||
</ng-template> |
|||
<ng-template #loading> |
|||
<mat-spinner [diameter]="32" strokeWidth="2"></mat-spinner> |
|||
</ng-template> |
|||
@ -0,0 +1,171 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; |
|||
import { Store } from '@ngrx/store'; |
|||
import { AppState } from '@core/core.state'; |
|||
import { ImageReferences } from '@shared/models/resource.models'; |
|||
import { EntityType, entityTypeTranslations } from '@shared/models/entity-type.models'; |
|||
import { TranslateService } from '@ngx-translate/core'; |
|||
import { getEntityDetailsPageURL } from '@core/utils'; |
|||
import { getCurrentAuthUser } from '@core/auth/auth.selectors'; |
|||
import { NULL_UUID } from '@shared/models/id/has-uuid'; |
|||
import { Authority } from '@shared/models/authority.enum'; |
|||
import { Observable } from 'rxjs'; |
|||
import { EntityService } from '@core/http/entity.service'; |
|||
import { BaseData, HasId } from '@shared/models/base-data'; |
|||
import { HasTenantId } from '@shared/models/entity.models'; |
|||
import { map } from 'rxjs/operators'; |
|||
import { TbPopoverComponent } from '@shared/components/popover.component'; |
|||
|
|||
interface ReferencedEntityInfo { |
|||
entity: BaseData<HasId> & HasTenantId; |
|||
typeName: string; |
|||
detailsUrl: string; |
|||
} |
|||
|
|||
interface TenantReferencedEntities { |
|||
tenantName?: string; |
|||
tenantDetailsUrl?: string; |
|||
entities: ReferencedEntityInfo[]; |
|||
} |
|||
|
|||
type ReferencedEntities = {[tenantId: string]: TenantReferencedEntities}; |
|||
type ReferencedEntitiesEntry = [string, TenantReferencedEntities]; |
|||
|
|||
@Component({ |
|||
selector: 'tb-image-references', |
|||
templateUrl: './image-references.component.html', |
|||
styleUrls: [] |
|||
}) |
|||
export class ImageReferencesComponent implements OnInit { |
|||
|
|||
@Input() |
|||
references: ImageReferences; |
|||
|
|||
popoverComponent: TbPopoverComponent<ImageReferencesComponent>; |
|||
|
|||
contentReady = false; |
|||
|
|||
authUser = getCurrentAuthUser(this.store); |
|||
|
|||
simpleList = true; |
|||
|
|||
referencedEntitiesList: ReferencedEntityInfo[]; |
|||
|
|||
referencedEntitiesEntries: ReferencedEntitiesEntry[]; |
|||
|
|||
constructor(protected store: Store<AppState>, |
|||
private entityService: EntityService, |
|||
private cd: ChangeDetectorRef, |
|||
private translate: TranslateService) { |
|||
} |
|||
|
|||
ngOnInit(): void { |
|||
if (this.authUser.authority === Authority.SYS_ADMIN && this.hasNonSystemEntities(this.references)) { |
|||
this.simpleList = false; |
|||
this.toReferencedEntitiesEntries(this.references).subscribe( |
|||
(entries) => { |
|||
this.referencedEntitiesEntries = entries; |
|||
this.contentReady = true; |
|||
this.cd.detectChanges(); |
|||
if (this.popoverComponent) { |
|||
Promise.resolve().then(() => { |
|||
this.popoverComponent.updatePosition(); |
|||
}); |
|||
} |
|||
} |
|||
); |
|||
} else { |
|||
this.referencedEntitiesList = this.toReferencedEntitiesList(this.references); |
|||
this.contentReady = true; |
|||
} |
|||
} |
|||
|
|||
isSystem(tenantId: string): boolean { |
|||
return tenantId === NULL_UUID; |
|||
} |
|||
|
|||
private hasNonSystemEntities(references: ImageReferences): boolean { |
|||
for (const entityTypeStr of Object.keys(references)) { |
|||
const entities = this.references[entityTypeStr]; |
|||
if (entities.some(e => e.tenantId && e.tenantId.id && e.tenantId.id !== NULL_UUID)) { |
|||
return true; |
|||
} |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
private toReferencedEntitiesList(references: ImageReferences): ReferencedEntityInfo[] { |
|||
const result: ReferencedEntityInfo[] = []; |
|||
for (const entityTypeStr of Object.keys(references)) { |
|||
const entityType = entityTypeStr as EntityType; |
|||
const entityTypeName = this.translate.instant(entityTypeTranslations.get(entityType).type); |
|||
const entities = references[entityTypeStr]; |
|||
for (const entity of entities) { |
|||
const detailsUrl = getEntityDetailsPageURL(entity.id.id, entityType); |
|||
result.push({ |
|||
entity, |
|||
typeName: entityTypeName, |
|||
detailsUrl |
|||
}); |
|||
} |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
private toReferencedEntitiesEntries(references: ImageReferences): Observable<ReferencedEntitiesEntry[]> { |
|||
let referencedEntities: ReferencedEntities = {}; |
|||
const referencedEntitiesList = this.toReferencedEntitiesList(references); |
|||
for (const referencedEntityInfo of referencedEntitiesList) { |
|||
const tenantId = referencedEntityInfo.entity.tenantId?.id || NULL_UUID; |
|||
let tenantEntitiesInfo = referencedEntities[tenantId]; |
|||
if (!tenantEntitiesInfo) { |
|||
tenantEntitiesInfo = { |
|||
entities: [] |
|||
}; |
|||
referencedEntities[tenantId] = tenantEntitiesInfo; |
|||
} |
|||
tenantEntitiesInfo.entities.push(referencedEntityInfo); |
|||
} |
|||
referencedEntities = Object.keys(referencedEntities).sort((tenantId1, tenantId2) => { |
|||
if (tenantId1 === NULL_UUID) { |
|||
return -1; |
|||
} else if (tenantId2 === NULL_UUID) { |
|||
return 1; |
|||
} |
|||
return 0; |
|||
}).reduce( |
|||
(obj, key) => { |
|||
obj[key] = referencedEntities[key]; |
|||
return obj; |
|||
}, |
|||
{} |
|||
); |
|||
const tenantIds = Object.keys(referencedEntities).filter(id => id !== NULL_UUID); |
|||
return this.entityService.getEntities(EntityType.TENANT, tenantIds).pipe( |
|||
map((tenants) => { |
|||
for (const tenant of tenants) { |
|||
const tenantEntitiesInfo = referencedEntities[tenant.id.id]; |
|||
tenantEntitiesInfo.tenantName = tenant.name; |
|||
tenantEntitiesInfo.tenantDetailsUrl = getEntityDetailsPageURL(tenant.id.id, EntityType.TENANT); |
|||
} |
|||
return Object.entries(referencedEntities); |
|||
}) |
|||
); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,130 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { CollectionViewer, DataSource, SelectionModel } from '@angular/cdk/collections'; |
|||
import { ImageResourceInfo } from '@shared/models/resource.models'; |
|||
import { BehaviorSubject, Observable, of, ReplaySubject, Subject } from 'rxjs'; |
|||
import { emptyPageData, PageData } from '@shared/models/page/page-data'; |
|||
import { ImageService } from '@core/http/image.service'; |
|||
import { EntityBooleanFunction } from '@home/models/entity/entities-table-config.models'; |
|||
import { PageLink } from '@shared/models/page/page-link'; |
|||
import { catchError, map, take, tap } from 'rxjs/operators'; |
|||
|
|||
export class ImagesDatasource implements DataSource<ImageResourceInfo> { |
|||
private entitiesSubject: Subject<ImageResourceInfo[]>; |
|||
private readonly pageDataSubject: Subject<PageData<ImageResourceInfo>>; |
|||
|
|||
public pageData$: Observable<PageData<ImageResourceInfo>>; |
|||
|
|||
public selection = new SelectionModel<ImageResourceInfo>(true, []); |
|||
|
|||
public dataLoading = true; |
|||
|
|||
constructor(private imageService: ImageService, |
|||
private images: ImageResourceInfo[], |
|||
private selectionEnabledFunction: EntityBooleanFunction<ImageResourceInfo>) { |
|||
if (this.images && this.images.length) { |
|||
this.entitiesSubject = new BehaviorSubject<ImageResourceInfo[]>(this.images); |
|||
} else { |
|||
this.entitiesSubject = new BehaviorSubject<ImageResourceInfo[]>([]); |
|||
this.pageDataSubject = new BehaviorSubject<PageData<ImageResourceInfo>>(emptyPageData<ImageResourceInfo>()); |
|||
this.pageData$ = this.pageDataSubject.asObservable(); |
|||
} |
|||
} |
|||
|
|||
connect(collectionViewer: CollectionViewer): |
|||
Observable<ImageResourceInfo[] | ReadonlyArray<ImageResourceInfo>> { |
|||
return this.entitiesSubject.asObservable(); |
|||
} |
|||
|
|||
disconnect(collectionViewer: CollectionViewer): void { |
|||
this.entitiesSubject.complete(); |
|||
if (this.pageDataSubject) { |
|||
this.pageDataSubject.complete(); |
|||
} |
|||
} |
|||
|
|||
reset() { |
|||
this.entitiesSubject.next([]); |
|||
if (this.pageDataSubject) { |
|||
this.pageDataSubject.next(emptyPageData<ImageResourceInfo>()); |
|||
} |
|||
} |
|||
|
|||
loadEntities(pageLink: PageLink): Observable<PageData<ImageResourceInfo>> { |
|||
this.dataLoading = true; |
|||
const result = new ReplaySubject<PageData<ImageResourceInfo>>(); |
|||
this.fetchEntities(pageLink).pipe( |
|||
tap(() => { |
|||
this.selection.clear(); |
|||
}), |
|||
catchError(() => of(emptyPageData<ImageResourceInfo>())), |
|||
).subscribe( |
|||
(pageData) => { |
|||
this.entitiesSubject.next(pageData.data); |
|||
this.pageDataSubject.next(pageData); |
|||
result.next(pageData); |
|||
this.dataLoading = false; |
|||
} |
|||
); |
|||
return result; |
|||
} |
|||
|
|||
fetchEntities(pageLink: PageLink): Observable<PageData<ImageResourceInfo>> { |
|||
return this.imageService.getImages(pageLink); |
|||
} |
|||
|
|||
isAllSelected(): Observable<boolean> { |
|||
const numSelected = this.selection.selected.length; |
|||
return this.entitiesSubject.pipe( |
|||
map((entities) => numSelected === entities.length) |
|||
); |
|||
} |
|||
|
|||
isEmpty(): Observable<boolean> { |
|||
return this.entitiesSubject.pipe( |
|||
map((entities) => !entities.length) |
|||
); |
|||
} |
|||
|
|||
total(): Observable<number> { |
|||
return this.pageDataSubject.pipe( |
|||
map((pageData) => pageData.totalElements) |
|||
); |
|||
} |
|||
|
|||
masterToggle() { |
|||
this.entitiesSubject.pipe( |
|||
tap((entities) => { |
|||
const numSelected = this.selection.selected.length; |
|||
if (numSelected === this.selectableEntitiesCount(entities)) { |
|||
this.selection.clear(); |
|||
} else { |
|||
entities.forEach(row => { |
|||
if (this.selectionEnabledFunction(row)) { |
|||
this.selection.select(row); |
|||
} |
|||
}); |
|||
} |
|||
}), |
|||
take(1) |
|||
).subscribe(); |
|||
} |
|||
|
|||
private selectableEntitiesCount(entities: Array<ImageResourceInfo>): number { |
|||
return entities.filter((entity) => this.selectionEnabledFunction(entity)).length; |
|||
} |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
<!-- |
|||
|
|||
Copyright © 2016-2023 The Thingsboard Authors |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); |
|||
you may not use this file except in compliance with the License. |
|||
You may obtain a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, |
|||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
See the License for the specific language governing permissions and |
|||
limitations under the License. |
|||
|
|||
--> |
|||
<h2 mat-dialog-title>{{title | translate}}</h2> |
|||
<div mat-dialog-content class="tb-images-in-use-content" [class]="{multiple: data.multiple}"> |
|||
<div [innerHTML]="message | translate | safe: 'html'"></div> |
|||
<ng-container *ngIf="data.multiple; else singleImageReferences"> |
|||
<div class="table-container"> |
|||
<table mat-table [dataSource]="dataSource"> |
|||
<ng-container matColumnDef="select" sticky> |
|||
<mat-header-cell *matHeaderCellDef style="width: 30px;"> |
|||
<mat-checkbox (change)="$event ? dataSource.masterToggle() : null" |
|||
[checked]="dataSource.selection.hasValue() && (dataSource.isAllSelected() | async)" |
|||
[indeterminate]="dataSource.selection.hasValue() && (dataSource.isAllSelected() | async) === false"> |
|||
</mat-checkbox> |
|||
</mat-header-cell> |
|||
<mat-cell *matCellDef="let image"> |
|||
<mat-checkbox (click)="$event.stopPropagation()" |
|||
(change)="$event ? dataSource.selection.toggle(image) : null" |
|||
[checked]="dataSource.selection.isSelected(image)"> |
|||
</mat-checkbox> |
|||
</mat-cell> |
|||
</ng-container> |
|||
<ng-container matColumnDef="preview"> |
|||
<mat-header-cell *matHeaderCellDef style="width: 50px; min-width: 50px;"></mat-header-cell> |
|||
<mat-cell *matCellDef="let image"> |
|||
<img class="tb-image-preview" [src]="image.link | image: {preview: true} | async" alt="{{ image.title }}"> |
|||
</mat-cell> |
|||
</ng-container> |
|||
<ng-container matColumnDef="title"> |
|||
<mat-header-cell *matHeaderCellDef style="width: 100%;"> |
|||
<ng-container *ngIf="dataSource.selection.isEmpty(); else selectedImages"> |
|||
{{ 'image.name' | translate }} |
|||
</ng-container> |
|||
<ng-template #selectedImages> |
|||
{{ translate.get('image.selected-images', {count: dataSource.selection.selected.length}) | async }} |
|||
</ng-template> |
|||
</mat-header-cell> |
|||
<mat-cell *matCellDef="let image"> |
|||
{{ image.title }} |
|||
</mat-cell> |
|||
</ng-container> |
|||
<ng-container matColumnDef="references"> |
|||
<mat-header-cell *matHeaderCellDef></mat-header-cell> |
|||
<mat-cell *matCellDef="let image"> |
|||
<button #showReferencesButton |
|||
mat-stroked-button |
|||
color="primary" |
|||
(click)="toggleShowReferences($event, image, showReferencesButton)">{{ 'image.references' | translate }}</button> |
|||
</mat-cell> |
|||
</ng-container> |
|||
<mat-header-row [ngClass]="{'mat-row-select': true}" *matHeaderRowDef="['select', 'preview', 'title', 'references']; sticky: true"></mat-header-row> |
|||
<mat-row [ngClass]="{'mat-row-select': true, |
|||
'mat-selected': dataSource.selection.isSelected(image)}" |
|||
*matRowDef="let image; columns: ['select', 'preview', 'title', 'references'];"></mat-row> |
|||
</table> |
|||
</div> |
|||
</ng-container> |
|||
</div> |
|||
<div mat-dialog-actions fxLayoutAlign="end center"> |
|||
<button mat-button color="primary" (click)="cancel()">{{'action.cancel' | translate}}</button> |
|||
<button mat-raised-button color="accent" (click)="delete()" [disabled]="data.multiple && dataSource.selection.isEmpty()" |
|||
cdkFocusInitial>{{ (data.multiple ? 'action.delete-selected' : 'action.delete-anyway') | translate}}</button> |
|||
</div> |
|||
<ng-template #singleImageReferences> |
|||
<tb-image-references [references]="references"></tb-image-references> |
|||
<div [innerHTML]="'image.delete-image-in-use-text' | translate | safe: 'html'"></div> |
|||
</ng-template> |
|||
@ -0,0 +1,39 @@ |
|||
/** |
|||
* Copyright © 2016-2023 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0 |
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
:host { |
|||
.tb-images-in-use-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
&.multiple { |
|||
gap: 16px; |
|||
} |
|||
.table-container { |
|||
overflow: auto; |
|||
.mat-mdc-cell.mat-column-preview { |
|||
width: 50px; |
|||
height: 50px; |
|||
padding: 2px 12px; |
|||
display: block; |
|||
} |
|||
} |
|||
.tb-image-preview { |
|||
width: 50px; |
|||
height: 50px; |
|||
object-fit: contain; |
|||
border-radius: 4px; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,112 @@ |
|||
///
|
|||
/// Copyright © 2016-2023 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { Component, Inject, OnInit, Renderer2, ViewContainerRef } from '@angular/core'; |
|||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; |
|||
import { Store } from '@ngrx/store'; |
|||
import { AppState } from '@core/core.state'; |
|||
import { DialogComponent } from '@shared/components/dialog.component'; |
|||
import { Router } from '@angular/router'; |
|||
import { ImageReferences, ImageResourceInfo, ImageResourceInfoWithReferences } from '@shared/models/resource.models'; |
|||
import { ImagesDatasource } from '@home/components/image/images-datasource'; |
|||
import { MatButton } from '@angular/material/button'; |
|||
import { TbPopoverService } from '@shared/components/popover.service'; |
|||
import { ImageReferencesComponent } from '@home/components/image/image-references.component'; |
|||
import { TranslateService } from '@ngx-translate/core'; |
|||
|
|||
export interface ImagesInUseDialogData { |
|||
multiple: boolean; |
|||
images: ImageResourceInfoWithReferences[]; |
|||
} |
|||
|
|||
@Component({ |
|||
selector: 'tb-images-in-use-dialog', |
|||
templateUrl: './images-in-use-dialog.component.html', |
|||
styleUrls: ['./images-in-use-dialog.component.scss'] |
|||
}) |
|||
export class ImagesInUseDialogComponent extends |
|||
DialogComponent<ImagesInUseDialogComponent, ImageResourceInfo[]> implements OnInit { |
|||
|
|||
title: string; |
|||
message: string; |
|||
|
|||
references: ImageReferences; |
|||
|
|||
dataSource: ImagesDatasource; |
|||
|
|||
constructor(protected store: Store<AppState>, |
|||
protected router: Router, |
|||
@Inject(MAT_DIALOG_DATA) public data: ImagesInUseDialogData, |
|||
public dialogRef: MatDialogRef<ImagesInUseDialogComponent, ImageResourceInfo[]>, |
|||
public translate: TranslateService, |
|||
private renderer: Renderer2, |
|||
private viewContainerRef: ViewContainerRef, |
|||
private popoverService: TbPopoverService) { |
|||
super(store, router, dialogRef); |
|||
} |
|||
|
|||
ngOnInit(): void { |
|||
if (this.data.multiple) { |
|||
this.title = 'image.images-are-in-use'; |
|||
this.message = 'image.images-are-in-use-text'; |
|||
this.dataSource = new ImagesDatasource(null, this.data.images, entity => true); |
|||
} else { |
|||
this.title = 'image.image-is-in-use'; |
|||
this.message = 'image.image-is-in-use-text'; |
|||
this.references = this.data.images[0].references; |
|||
} |
|||
} |
|||
|
|||
cancel() { |
|||
this.dialogRef.close(null); |
|||
} |
|||
|
|||
delete() { |
|||
if (this.data.multiple) { |
|||
this.dialogRef.close(this.dataSource.selection.selected); |
|||
} else { |
|||
this.dialogRef.close(this.data.images); |
|||
} |
|||
} |
|||
|
|||
toggleShowReferences($event: Event, image: ImageResourceInfoWithReferences, referencesButton: MatButton) { |
|||
if ($event) { |
|||
$event.stopPropagation(); |
|||
} |
|||
const trigger = referencesButton._elementRef.nativeElement; |
|||
if (this.popoverService.hasPopover(trigger)) { |
|||
this.popoverService.hidePopover(trigger); |
|||
} else { |
|||
const referencesPopover = this.popoverService.displayPopover(trigger, this.renderer, |
|||
this.viewContainerRef, ImageReferencesComponent, 'top', true, null, |
|||
{ |
|||
references: image.references |
|||
}, {}, {}, {}, |
|||
false, |
|||
visible => { |
|||
const addClasses = visible ? 'mdc-button--unelevated mat-mdc-unelevated-button' : 'mdc-button--outlined mat-mdc-outlined-button'; |
|||
const removeClasses = visible ? 'mdc-button--outlined mat-mdc-outlined-button' : 'mdc-button--unelevated mat-mdc-unelevated-button'; |
|||
addClasses.split(' ').forEach(clazz => { |
|||
this.renderer.addClass(trigger, clazz); |
|||
}); |
|||
removeClasses.split(' ').forEach(clazz => { |
|||
this.renderer.removeClass(trigger, clazz); |
|||
}); |
|||
}); |
|||
referencesPopover.tbComponentRef.instance.popoverComponent = referencesPopover; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue