13 changed files with 343 additions and 32 deletions
@ -0,0 +1,60 @@ |
|||||
|
<!-- |
||||
|
|
||||
|
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. |
||||
|
|
||||
|
--> |
||||
|
<mat-toolbar color="primary"> |
||||
|
<h2>{{ 'image.embed-image' | translate }}</h2> |
||||
|
<span fxFlex></span> |
||||
|
<button mat-icon-button |
||||
|
(click)="cancel()" |
||||
|
type="button"> |
||||
|
<mat-icon class="material-icons">close</mat-icon> |
||||
|
</button> |
||||
|
</mat-toolbar> |
||||
|
<mat-progress-bar color="warn" mode="indeterminate" *ngIf="isLoading$ | async"> |
||||
|
</mat-progress-bar> |
||||
|
<div style="height: 4px;" *ngIf="!(isLoading$ | async)"></div> |
||||
|
<div mat-dialog-content> |
||||
|
<div class="tb-form-panel stroked tb-slide-toggle" *ngIf="!readonly || image.public"> |
||||
|
<mat-expansion-panel class="tb-settings" [expanded]="image.public" disabled> |
||||
|
<mat-expansion-panel-header fxLayout="row wrap"> |
||||
|
<mat-panel-title> |
||||
|
<div *ngIf="!readonly" tb-hint-tooltip-icon="{{ 'image.embed-to-html-hint' | translate }}" |
||||
|
class="tb-form-row no-border no-padding"> |
||||
|
<mat-slide-toggle class="mat-slide" [formControl]="publicStatusControl" (click)="$event.stopPropagation()" |
||||
|
fxLayoutAlign="center"> |
||||
|
<div class="tb-form-panel-title">{{ 'image.embed-to-html' | translate }}</div> |
||||
|
</mat-slide-toggle> |
||||
|
</div> |
||||
|
<div *ngIf="readonly" class="tb-form-panel-title" translate>image.embed-to-html</div> |
||||
|
</mat-panel-title> |
||||
|
</mat-expansion-panel-header> |
||||
|
<ng-template matExpansionPanelContent> |
||||
|
<div class="tb-embed-image-text" [innerHTML]="'image.embed-to-html-text' | translate"></div> |
||||
|
<tb-markdown usePlainMarkdown |
||||
|
containerClass="tb-embed-image-code" |
||||
|
[data]="embedToHtmlCode()"></tb-markdown> |
||||
|
</ng-template> |
||||
|
</mat-expansion-panel> |
||||
|
</div> |
||||
|
<div class="tb-form-panel stroked"> |
||||
|
<div class="tb-form-panel-title" translate>image.embed-to-angular-template</div> |
||||
|
<div class="tb-embed-image-text" [innerHTML]="'image.embed-to-angular-template-text' | translate"></div> |
||||
|
<tb-markdown usePlainMarkdown |
||||
|
containerClass="tb-embed-image-code" |
||||
|
[data]="embedToAngularTemplateCode()"></tb-markdown> |
||||
|
</div> |
||||
|
</div> |
||||
@ -0,0 +1,71 @@ |
|||||
|
/** |
||||
|
* 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 { |
||||
|
.mat-mdc-dialog-content { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 16px; |
||||
|
.tb-embed-image-text { |
||||
|
font-size: 14px; |
||||
|
font-weight: 400; |
||||
|
line-height: 20px; |
||||
|
color: rgba(0,0,0,0.54); |
||||
|
letter-spacing: 0.2px; |
||||
|
} |
||||
|
.tb-form-panel-title { |
||||
|
color: rgba(0, 0, 0, 0.87); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
:host ::ng-deep { |
||||
|
.tb-markdown-view { |
||||
|
max-width: 700px; |
||||
|
.tb-embed-image-code { |
||||
|
.code-wrapper { |
||||
|
padding: 0; |
||||
|
pre[class*=language-] { |
||||
|
margin: 0; |
||||
|
padding: 9px 38px 9px 16px; |
||||
|
} |
||||
|
code[class*="language-"], pre[class*="language-"] { |
||||
|
font-size: 12px; |
||||
|
overflow: hidden; |
||||
|
white-space: normal; |
||||
|
word-break: break-word; |
||||
|
} |
||||
|
button.clipboard-btn { |
||||
|
right: 0; |
||||
|
height: 36px; |
||||
|
p, div { |
||||
|
background: transparent; |
||||
|
} |
||||
|
p { |
||||
|
margin: 0; |
||||
|
padding: 6px; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
div { |
||||
|
top: 0; |
||||
|
padding: 8px; |
||||
|
height: 38px; |
||||
|
width: 38px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,94 @@ |
|||||
|
///
|
||||
|
/// 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 { ImageResourceInfo } from '@shared/models/resource.models'; |
||||
|
import { Component, Inject, OnInit } from '@angular/core'; |
||||
|
import { DialogComponent } from '@shared/components/dialog.component'; |
||||
|
import { Store } from '@ngrx/store'; |
||||
|
import { AppState } from '@core/core.state'; |
||||
|
import { Router } from '@angular/router'; |
||||
|
import { ImageService } from '@core/http/image.service'; |
||||
|
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; |
||||
|
import { FormControl, UntypedFormBuilder } from '@angular/forms'; |
||||
|
|
||||
|
export interface EmbedImageDialogData { |
||||
|
readonly: boolean; |
||||
|
image: ImageResourceInfo; |
||||
|
} |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'tb-embed-image-dialog', |
||||
|
templateUrl: './embed-image-dialog.component.html', |
||||
|
styleUrls: ['./embed-image-dialog.component.scss'] |
||||
|
}) |
||||
|
export class EmbedImageDialogComponent extends |
||||
|
DialogComponent<EmbedImageDialogComponent, ImageResourceInfo> implements OnInit { |
||||
|
|
||||
|
image = this.data.image; |
||||
|
|
||||
|
readonly = this.data.readonly; |
||||
|
|
||||
|
imageChanged = false; |
||||
|
|
||||
|
publicStatusControl = new FormControl(this.image.public); |
||||
|
|
||||
|
constructor(protected store: Store<AppState>, |
||||
|
protected router: Router, |
||||
|
private imageService: ImageService, |
||||
|
@Inject(MAT_DIALOG_DATA) private data: EmbedImageDialogData, |
||||
|
public dialogRef: MatDialogRef<EmbedImageDialogComponent, ImageResourceInfo>, |
||||
|
public fb: UntypedFormBuilder) { |
||||
|
super(store, router, dialogRef); |
||||
|
} |
||||
|
|
||||
|
ngOnInit(): void { |
||||
|
if (!this.readonly) { |
||||
|
this.publicStatusControl.valueChanges.subscribe( |
||||
|
(isPublic) => { |
||||
|
this.updateImagePublicStatus(isPublic); |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
cancel(): void { |
||||
|
this.dialogRef.close(this.imageChanged ? this.image : null); |
||||
|
} |
||||
|
|
||||
|
embedToHtmlCode(): string { |
||||
|
return '```html\n' + |
||||
|
'<img src="'+this.image.publicLink+'" alt="'+this.image.title.replace(/"/g, '"')+'" />' + |
||||
|
'{:copy-code}\n' + |
||||
|
'```'; |
||||
|
} |
||||
|
|
||||
|
embedToAngularTemplateCode(): string { |
||||
|
return '```html\n' + |
||||
|
'<img [src]="\''+this.image.link+'\' | image | async" />' + |
||||
|
'{:copy-code}\n' + |
||||
|
'```'; |
||||
|
} |
||||
|
|
||||
|
private updateImagePublicStatus(isPublic: boolean): void { |
||||
|
this.imageService.updateImagePublicStatus(this.image, isPublic).subscribe( |
||||
|
(image) => { |
||||
|
this.image = image; |
||||
|
this.imageChanged = true; |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
} |
||||
Loading…
Reference in new issue