src/app/features/file/edit-photo/edit-photo.component.ts
| changeDetection | ChangeDetectionStrategy.OnPush |
| selector | app-edit-photo |
| standalone | true |
| imports |
MatButtonModule
MatTooltipModule
FontAwesomeModule
|
| styleUrls | ./edit-photo.component.scss |
| templateUrl | ./edit-photo.component.html |
No results matching.
MatButtonModule
MatTooltipModule
FontAwesomeModule
EditFileComponent
OnInit
Properties |
|
Methods |
|
Inputs |
Outputs |
| entity | |
Type : Entity
|
|
|
Inherited from
EditFileComponent
|
|
| formFieldConfig | |
Type : FormFieldConfig
|
|
|
Inherited from
EditFileComponent
|
|
| aria-describedby | |
Type : string
|
|
|
Inherited from
CustomFormControlDirective
|
|
| disabled | |
Type : boolean
|
|
|
Inherited from
CustomFormControlDirective
|
|
| ngControl | |
Type : any
|
|
Default value : inject(NgControl, { optional: true, self: true })
|
|
|
Inherited from
CustomFormControlDirective
|
|
| placeholder | |
Type : string
|
|
|
Inherited from
CustomFormControlDirective
|
|
| required | |
Type : boolean
|
|
|
Inherited from
CustomFormControlDirective
|
|
| value | |
Type : T
|
|
|
Inherited from
CustomFormControlDirective
|
|
| valueChange | |
Type : EventEmitter
|
|
|
Inherited from
CustomFormControlDirective
|
|
| delete |
delete()
|
|
Inherited from
EditFileComponent
|
|
Returns :
void
|
| Protected deleteExistingFile |
deleteExistingFile()
|
|
Inherited from
EditFileComponent
|
|
Returns :
void
|
| Async onFileSelected | ||||||
onFileSelected(file: File)
|
||||||
|
Inherited from
EditFileComponent
|
||||||
|
Parameters :
Returns :
Promise<void>
|
| openPopup |
openPopup()
|
|
Returns :
void
|
| Protected resetFile |
resetFile()
|
|
Inherited from
EditFileComponent
|
|
Returns :
void
|
| formClicked |
formClicked()
|
|
Inherited from
EditFileComponent
|
|
Returns :
void
|
| Protected saveNewFile | ||||||
saveNewFile(file: File)
|
||||||
|
Inherited from
EditFileComponent
|
||||||
|
Parameters :
Returns :
void
|
| Protected setInitialValue |
setInitialValue()
|
|
Inherited from
EditFileComponent
|
|
Template method to allow easy override of mapping the initialValue from the formControl.
Returns :
void
|
| showFile |
showFile()
|
|
Inherited from
EditFileComponent
|
|
Returns :
void
|
| blur |
blur()
|
|
Inherited from
CustomFormControlDirective
|
|
Returns :
void
|
| focus |
focus()
|
|
Inherited from
CustomFormControlDirective
|
|
Returns :
void
|
| onContainerClick | ||||||
onContainerClick(event: MouseEvent)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| registerOnChange | ||||||
registerOnChange(fn: any)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| registerOnTouched | ||||||
registerOnTouched(fn: any)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| setDescribedByIds | ||||||
setDescribedByIds(ids: string[])
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| setDisabledState | ||||||
setDisabledState(isDisabled: boolean)
|
||||||
|
Inherited from
CustomFormControlDirective
|
||||||
|
Parameters :
Returns :
void
|
| writeValue | |||||||||||||||
writeValue(value: T, notifyFormControl: unknown)
|
|||||||||||||||
|
Inherited from
CustomFormControlDirective
|
|||||||||||||||
|
Implementation for Angular ControlValueAccessor interface that links the form control value to the component value
Parameters :
Returns :
void
|
| Readonly imgPath |
Type : unknown
|
Default value : signal<SafeUrl>(this.defaultImage)
|
| acceptedFileTypes |
Type : string
|
Default value : "*"
|
|
Inherited from
EditFileComponent
|
|
The accepted file types for file selection dialog. If not defined, allows any file. |
| Protected fileService |
Type : unknown
|
Default value : inject(FileService)
|
|
Inherited from
EditFileComponent
|
| fileUploadInput |
Type : ElementRef<HTMLInputElement>
|
Decorators :
@ViewChild('fileUpload')
|
|
Inherited from
EditFileComponent
|
| Readonly hasControlValue |
Type : unknown
|
Default value : signal<boolean>(false)
|
|
Inherited from
EditFileComponent
|
| initialValue |
Type : string
|
|
Inherited from
EditFileComponent
|
| Readonly isControlEnabled |
Type : unknown
|
Default value : signal<boolean>(false)
|
|
Inherited from
EditFileComponent
|
| Protected navigator |
Type : unknown
|
Default value : inject<Navigator>(NAVIGATOR_TOKEN)
|
|
Inherited from
EditFileComponent
|
| controlType |
Type : string
|
Default value : "custom-control"
|
|
Inherited from
CustomFormControlDirective
|
| elementRef |
Type : unknown
|
Default value : inject<ElementRef<HTMLElement>>(ElementRef)
|
|
Inherited from
CustomFormControlDirective
|
| Readonly enabled |
Type : Signal<boolean>
|
Default value : computed(() => !this._disabled())
|
|
Inherited from
CustomFormControlDirective
|
|
Whether the control is currently enabled, as a signal (tracks disabled). |
| errorStateMatcher |
Type : unknown
|
Default value : inject(ErrorStateMatcher)
|
|
Inherited from
CustomFormControlDirective
|
| id |
Type : unknown
|
Default value : `custom-form-control-${CustomFormControlDirective.nextId++}`
|
|
Inherited from
CustomFormControlDirective
|
| Static nextId |
Type : number
|
Default value : 0
|
|
Inherited from
CustomFormControlDirective
|
| onChange |
Type : unknown
|
Default value : () => {...}
|
|
Inherited from
CustomFormControlDirective
|
| onTouched |
Type : unknown
|
Default value : () => {...}
|
|
Inherited from
CustomFormControlDirective
|
| parentForm |
Type : unknown
|
Default value : inject(NgForm, { optional: true })
|
|
Inherited from
CustomFormControlDirective
|
| parentFormGroup |
Type : unknown
|
Default value : inject(FormGroupDirective, { optional: true })
|
|
Inherited from
CustomFormControlDirective
|
| stateChanges |
Type : unknown
|
Default value : new Subject<void>()
|
|
Inherited from
CustomFormControlDirective
|
| Readonly valueSignal |
Type : Signal<T>
|
Default value : computed(() => this._value())
|
|
Inherited from
CustomFormControlDirective
|
|
The current value of the control as a signal.
Authoritative in both modes: it reflects the bound |
import {
ChangeDetectionStrategy,
Component,
inject,
OnInit,
signal,
} from "@angular/core";
import { MatButtonModule } from "@angular/material/button";
import { MatDialog } from "@angular/material/dialog";
import { MatTooltipModule } from "@angular/material/tooltip";
import { SafeUrl } from "@angular/platform-browser";
import { FontAwesomeModule } from "@fortawesome/angular-fontawesome";
import { DynamicComponent } from "../../../core/config/dynamic-components/dynamic-component.decorator";
import { EditFileComponent } from "../edit-file/edit-file.component";
import { resizeImage } from "../file-utils";
import { ImagePopupComponent } from "./image-popup/image-popup.component";
@DynamicComponent("EditPhoto")
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: "app-edit-photo",
templateUrl: "./edit-photo.component.html",
styleUrls: ["./edit-photo.component.scss"],
imports: [MatButtonModule, MatTooltipModule, FontAwesomeModule],
})
export class EditPhotoComponent extends EditFileComponent implements OnInit {
private dialog = inject(MatDialog);
private readonly defaultImage = "assets/child.png";
private compression = 480;
private initialImg: SafeUrl = this.defaultImage;
readonly imgPath = signal<SafeUrl>(this.defaultImage);
override async onFileSelected(file: File): Promise<void> {
const cvs = await resizeImage(file, this.compression);
this.imgPath.set(cvs.toDataURL());
const blob = await new Promise<Blob>((res) => cvs.toBlob(res));
const reducedFile = new File([blob], file.name, {
type: file.type,
lastModified: file.lastModified,
});
return super.onFileSelected(reducedFile);
}
override ngOnInit() {
this.acceptedFileTypes = "image/*";
this.compression =
this.formFieldConfig()?.additional?.imageCompression ?? this.compression;
super.ngOnInit();
const entity = this.entity();
const formFieldConfig = this.formFieldConfig();
if (this.formControl.value && entity && formFieldConfig) {
this.fileService.loadFile(entity, formFieldConfig.id).subscribe((res) => {
this.imgPath.set(res);
this.initialImg = res;
});
}
}
override delete() {
this.resetPreview(this.defaultImage);
super.delete();
}
protected override resetFile() {
this.resetPreview(this.initialImg);
super.resetFile();
}
private resetPreview(resetImage: SafeUrl) {
if (this.imgPath() !== this.initialImg) {
URL.revokeObjectURL(this.imgPath() as string);
}
this.imgPath.set(resetImage);
}
protected override deleteExistingFile() {
URL.revokeObjectURL(this.initialImg as string);
this.initialImg = this.defaultImage;
super.deleteExistingFile();
}
openPopup() {
this.dialog.open(ImagePopupComponent, { data: { url: this.imgPath() } });
}
}
<div class="photo-container">
<img
[src]="imgPath()"
i18n-alt
alt="Image"
class="image"
(click)="openPopup()"
/>
<div
class="img-controls"
[matTooltipDisabled]="!(isControlEnabled() && !navigator.onLine)"
matTooltip="Changes to files are not possible offline."
i18n-matTooltip
>
@if (hasControlValue() && isControlEnabled()) {
<button
type="button"
mat-icon-button
(click)="delete()"
i18n-matTooltip="Tooltip remove file"
matTooltip="Remove file"
[disabled]="!navigator.onLine"
>
<fa-icon icon="xmark"></fa-icon>
</button>
}
@if (isControlEnabled()) {
<button
type="button"
mat-icon-button
(click)="fileUpload.click()"
i18n-matTooltip="Tooltip upload file button"
matTooltip="Upload file"
[disabled]="!navigator.onLine"
>
<fa-icon icon="upload"></fa-icon>
</button>
}
</div>
<input
type="file"
style="display: none"
(change)="onFileSelected($event.target['files'][0])"
[accept]="acceptedFileTypes"
#fileUpload
/>
</div>
./edit-photo.component.scss
@use "variables/colors";
.image {
width: 150px;
height: 150px;
border-radius: 50%;
object-fit: cover;
cursor: pointer;
background: lightgrey;
display: block;
}
.img-controls {
display: flex;
align-items: flex-end;
height: 48px;
}
.img-label {
margin: auto;
color: rgba(0, 0, 0, 0.6);
}
.img-label.invalid {
color: colors.$error;
}
.photo-container {
display: flex;
flex-direction: column;
align-items: center;
}