-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Romanchak/2599 image carousel on workshop images (#2611)
* updated cropper and change some fields * Changed function for show message bar about wrong image * Added new method for optimization checking size of image * Add carousel package * Implement image carousel * Add nav buttons * Fix files by linter * Fix uploading/removing images * Fix files by linter * Add tests for image-cropper-modal * Add tests for create-about-form * Add tests for create-description-form * Add tests for create-info-form * Add tests for create-photo-form * Add tests for teacher-form * Add tests for create-provider * Add tests for result * Add tests for image-form-control * Add tests for create-provider * Add tests for image-cropper-modal * Reimplemented tests for image-cropper-modal * Add ua and en version of text * Add test for image-form-control * Fix i18 * Remove !important * Remove extra checking * Remove console.log * Add translation * Rework fileChangeEvent * Create enum for cropper formats * Create config file for carousel options * Control the removal of images internally in the images form control * Implement writeValue function * Fix tests * Remove redundant functionality * Rework image-form-control component * Fix test * Implemented advises from Sonar * Resolved requested changes --------- Co-authored-by: Yaroslav Petryshyn <ya6liszl@gmail.com> Co-authored-by: Yaroslav Petryshyn <100092934+ya6lis@users.noreply.github.com> Co-authored-by: witolDark <witalikspelina@gmail.com>
- Loading branch information
1 parent
93e7b48
commit 3f538a7
Showing
37 changed files
with
586 additions
and
150 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
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
8 changes: 5 additions & 3 deletions
8
src/app/shared/components/image-carousel/image-carousel.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 |
---|---|---|
@@ -1,3 +1,5 @@ | ||
<div class="image-container"> | ||
<img class="image" [src]="images[0]?.path" alt="Image of workshop or provider" height="300" appCustomCarousel /> | ||
</div> | ||
<owl-carousel-o [options]="customOptions"> | ||
<ng-template carouselSlide *ngFor="let image of images"> | ||
<img class="image" [src]="image.path" alt="{{ 'ALT.IMAGE_WORKSHOP_PROVIDER' | translate }}" /> | ||
</ng-template> | ||
</owl-carousel-o> |
62 changes: 57 additions & 5 deletions
62
src/app/shared/components/image-carousel/image-carousel.component.scss
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 |
---|---|---|
@@ -1,8 +1,60 @@ | ||
.image-container { | ||
height: 300px; | ||
$image-height: 400px; | ||
$dots-height: 24px; | ||
$icon-size: 24px; | ||
$button-size: 50px; | ||
$button-bg-color-hover: #3849f9; | ||
$button-padding: 50px; | ||
|
||
.image { | ||
object-fit: contain; | ||
width: 100%; | ||
.image { | ||
object-fit: contain; | ||
width: 100%; | ||
height: $image-height; | ||
position: relative; | ||
} | ||
|
||
:host ::ng-deep .owl-carousel { | ||
position: relative; | ||
|
||
.owl-prev, | ||
.owl-next { | ||
position: absolute; | ||
top: calc(50% - $dots-height); | ||
width: $button-size; | ||
height: $button-size; | ||
transform: translateY(-50%); | ||
padding: 0; | ||
border-radius: 50%; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
transition: background-color 0.1s; | ||
|
||
&:hover { | ||
background-color: $button-bg-color-hover; | ||
} | ||
} | ||
|
||
.owl-prev { | ||
left: 0; | ||
margin-left: $button-padding; | ||
|
||
span { | ||
position: absolute; | ||
left: calc($button-size / 2 - $icon-size / 3); | ||
} | ||
} | ||
|
||
.owl-next { | ||
right: 0; | ||
margin-right: $button-padding; | ||
} | ||
|
||
.owl-dots { | ||
.owl-dot { | ||
&:hover span, | ||
&.active span { | ||
background-color: $button-bg-color-hover; | ||
} | ||
} | ||
} | ||
} |
21 changes: 19 additions & 2 deletions
21
src/app/shared/components/image-carousel/image-carousel.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 |
---|---|---|
@@ -1,11 +1,28 @@ | ||
import { Component, Input } from '@angular/core'; | ||
import { Component, Input, OnInit } from '@angular/core'; | ||
|
||
import { OwlOptions } from 'ngx-owl-carousel-o'; | ||
import { ImgPath } from 'shared/models/carousel.model'; | ||
import { DefaultCarouselOptions } from 'shared/configs/carousel.config'; | ||
|
||
@Component({ | ||
selector: 'app-image-carousel', | ||
templateUrl: './image-carousel.component.html', | ||
styleUrls: ['./image-carousel.component.scss'] | ||
}) | ||
export class ImageCarouselComponent { | ||
export class ImageCarouselComponent implements OnInit { | ||
@Input() public images: ImgPath[] = []; | ||
|
||
protected customOptions: OwlOptions = { ...DefaultCarouselOptions }; | ||
|
||
public ngOnInit(): void { | ||
if (this.images.length <= 1) { | ||
this.customOptions = { | ||
...this.customOptions, | ||
loop: false, | ||
autoplay: false, | ||
nav: false, | ||
dots: false | ||
}; | ||
} | ||
} | ||
} |
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
63 changes: 57 additions & 6 deletions
63
src/app/shared/components/image-cropper-modal/image-cropper-modal.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 |
---|---|---|
@@ -1,34 +1,85 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog'; | ||
import { ImageCropperModule } from 'ngx-image-cropper'; | ||
import { ImageCroppedEvent, LoadedImage } from 'ngx-image-cropper'; | ||
import { NgxsModule, Store } from '@ngxs/store'; | ||
import { TranslateModule } from '@ngx-translate/core'; | ||
|
||
import { ShowMessageBar } from 'shared/store/app.actions'; | ||
import { SnackbarText } from 'shared/enum/enumUA/message-bar'; | ||
import { Cropper } from '../../models/cropper'; | ||
import { ImageCropperModalComponent } from './image-cropper-modal.component'; | ||
|
||
describe('ImageCropperModalComponent', () => { | ||
let component: ImageCropperModalComponent; | ||
let fixture: ComponentFixture<ImageCropperModalComponent>; | ||
let mockDialogRef: MatDialogRef<ImageCropperModalComponent>; | ||
let store: Store; | ||
|
||
const testImage = new Event('test'); | ||
const testCropperConfig = { cropperAspectRatio: 1, cropperMinWidth: 100, cropperMinHeight: 100 } as Cropper; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [ImageCropperModule, MatDialogModule], | ||
imports: [MatDialogModule, NgxsModule.forRoot(), TranslateModule.forRoot()], | ||
declarations: [ImageCropperModalComponent], | ||
providers: [ | ||
{ provide: MAT_DIALOG_DATA, useValue: {} }, | ||
{ provide: MatDialogRef, useValue: {} } | ||
{ provide: MAT_DIALOG_DATA, useValue: { image: testImage, cropperConfig: testCropperConfig } }, | ||
{ provide: MatDialogRef, useValue: { close: jest.fn() } }, | ||
{ provide: Store, useValue: { dispatch: jest.fn() } } | ||
] | ||
}).compileComponents(); | ||
}); | ||
|
||
beforeEach(() => { | ||
fixture = TestBed.createComponent(ImageCropperModalComponent); | ||
component = fixture.componentInstance; | ||
component.data.cropperConfig = {} as Cropper; | ||
component.data.cropperConfig.cropperAspectRatio = 1; | ||
|
||
mockDialogRef = TestBed.inject(MatDialogRef); | ||
store = TestBed.inject(Store); | ||
|
||
component.data.cropperConfig = testCropperConfig; | ||
|
||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
|
||
it('should initialize with provided MAT_DIALOG_DATA', () => { | ||
expect(component.data.image).toBe(testImage); | ||
expect(component.data.cropperConfig).toEqual(testCropperConfig); | ||
}); | ||
|
||
it('should call dialogRef.close with the imageFile when onConfirm is called', () => { | ||
const testImageFile = new File(['test'], 'test-image.png'); | ||
component.imageFile = testImageFile; | ||
|
||
component.onConfirm(); | ||
|
||
expect(mockDialogRef.close).toHaveBeenCalledWith(testImageFile); | ||
}); | ||
|
||
it('should set croppedImage and imageFile when imageCropped is called', () => { | ||
const mockEvent: ImageCroppedEvent = { | ||
base64: null, | ||
blob: new Blob(['test image'], { type: 'image/png' }), | ||
objectUrl: 'http://test.com/test.png', | ||
width: 800, | ||
height: 600, | ||
cropperPosition: { x1: 0, y1: 0, x2: 0, y2: 0 }, | ||
imagePosition: { x1: 0, y1: 0, x2: 0, y2: 0 } | ||
}; | ||
|
||
component.imageCropped(mockEvent); | ||
|
||
expect(component.croppedImage).toBe(mockEvent.objectUrl); | ||
expect(component.imageFile).toEqual(mockEvent.blob); | ||
}); | ||
|
||
it('should dispatch ShowMessageBar action with error message when loadImageFailed is called', () => { | ||
component.loadImageFailed(); | ||
|
||
expect(store.dispatch).toHaveBeenCalledWith(new ShowMessageBar({ message: SnackbarText.errorToLoadImg, type: 'error' })); | ||
}); | ||
}); |
26 changes: 11 additions & 15 deletions
26
src/app/shared/components/image-cropper-modal/image-cropper-modal.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 |
---|---|---|
@@ -1,47 +1,43 @@ | ||
import { Component, Inject } from '@angular/core'; | ||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; | ||
import { ImageCroppedEvent, LoadedImage, base64ToFile } from 'ngx-image-cropper'; | ||
import { ImageCroppedEvent } from 'ngx-image-cropper'; | ||
import { Store } from '@ngxs/store'; | ||
|
||
import { Cropper } from 'shared/models/cropper'; | ||
import { ShowMessageBar } from 'shared/store/app.actions'; | ||
import { SnackbarText } from 'shared/enum/enumUA/message-bar'; | ||
|
||
@Component({ | ||
selector: 'app-image-cropper-modal', | ||
templateUrl: './image-cropper-modal.component.html', | ||
styleUrls: ['./image-cropper-modal.component.scss'] | ||
}) | ||
export class ImageCropperModalComponent { | ||
public imageChangedEvent = ''; | ||
public croppedImage = ''; | ||
public imageFile: Blob; | ||
public invalidMinRequirements = false; | ||
|
||
constructor( | ||
@Inject(MAT_DIALOG_DATA) | ||
public data: { | ||
image: string; | ||
image: Event; | ||
cropperConfig: Cropper; | ||
}, | ||
public dialogRef: MatDialogRef<ImageCropperModalComponent> | ||
public dialogRef: MatDialogRef<ImageCropperModalComponent>, | ||
private readonly store: Store | ||
) {} | ||
|
||
public onConfirm(): void { | ||
this.dialogRef.close(this.imageFile); | ||
} | ||
|
||
public fileChangeEvent(event: string): void { | ||
this.imageChangedEvent = event; | ||
} | ||
|
||
public imageCropped(event: ImageCroppedEvent): void { | ||
this.imageFile = base64ToFile(event.base64); | ||
this.croppedImage = event.base64; | ||
this.croppedImage = event.objectUrl; | ||
this.imageFile = event.blob; | ||
} | ||
|
||
public imageLoaded(image: LoadedImage): void { | ||
const { height, width } = image.original.size; | ||
this.invalidMinRequirements = height < this.data.cropperConfig.cropperMinHeight || width < this.data.cropperConfig.cropperMinWidth; | ||
public loadImageFailed(): void { | ||
this.store.dispatch(new ShowMessageBar({ message: SnackbarText.errorToLoadImg, type: 'error' })); | ||
} | ||
|
||
public loadImageFailed(): void {} | ||
public cropperReady(): void {} | ||
} |
2 changes: 1 addition & 1 deletion
2
src/app/shared/components/image-form-control/image-form-control.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
Oops, something went wrong.