Basic edit-image-modal

This commit is contained in:
Willem Dantuma 2021-03-01 16:56:48 +01:00
parent dd71b49502
commit 7768387f58
14 changed files with 142 additions and 85 deletions

34
package-lock.json generated
View File

@ -1865,25 +1865,23 @@
} }
}, },
"@farmmaps/common": { "@farmmaps/common": {
"version": "0.0.1-prerelease.530", "version": "file:dist/common",
"resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common/-/common-0.0.1-prerelease.530.tgz",
"integrity": "sha512-cvUKFctQvl91gE5zCJvzxhcnZ35XpletqFmxOFwj6qxLr975qs/Ia9VrzwjkqoIoXlsO9xlM/0Cn1PnPsF7nIg==",
"requires": { "requires": {
"tslib": "^2.0.0" "tslib": "^2.0.0"
} }
}, },
"@farmmaps/common-map": { "@farmmaps/common-map": {
"version": "0.0.1-prerelease.530", "version": "0.0.1-prerelease.542",
"resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common-map/-/common-map-0.0.1-prerelease.530.tgz", "resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common-map/-/common-map-0.0.1-prerelease.542.tgz",
"integrity": "sha512-LU4yzsTvja85GciySpJB5LjUD7fndEsnd2KKj0q9+IFZl9jOFfVcP+/3nImsYYmV9CK6sczNdevaSxQW+lpseQ==", "integrity": "sha512-UTz3FnIKEJ9PGgGTGy8UuWqY+ZBY6cW4oIL9VgHrUg9yXtfRt2zT9kaNDTeSUVOiLWcocGbJZX7zt5gjM/50PQ==",
"requires": { "requires": {
"tslib": "^2.0.0" "tslib": "^2.0.0"
} }
}, },
"@farmmaps/common-map3d": { "@farmmaps/common-map3d": {
"version": "0.0.1-prerelease.530", "version": "0.0.1-prerelease.542",
"resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common-map3d/-/common-map3d-0.0.1-prerelease.530.tgz", "resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common-map3d/-/common-map3d-0.0.1-prerelease.542.tgz",
"integrity": "sha512-4OG3yv6vOMJZ5dLZ2e8W9P1F1qvzcYBA/zCIA+kxfS0iiOfrOIiJgDvXPhMot+swATSsWeY4Txh6ydh6KmTzlg==", "integrity": "sha512-igy1g7ritVE2+hgc6jIO4+OriCeV6k2MubQcoszWWG4F6RZYuMgKciIWSdlDZ8yvZsA8WMdtxlT5vJ3wgvmesA==",
"requires": { "requires": {
"tslib": "^2.0.0" "tslib": "^2.0.0"
} }
@ -8604,10 +8602,20 @@
"ts-md5": "^1.2.4" "ts-md5": "^1.2.4"
} }
}, },
"ngx-bootstrap": { "ngx-image-cropper": {
"version": "5.6.2", "version": "3.3.5",
"resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-5.6.2.tgz", "resolved": "https://registry.npmjs.org/ngx-image-cropper/-/ngx-image-cropper-3.3.5.tgz",
"integrity": "sha512-6YHXtdXkGH3w0NQoaUgNYAcrj064Lv5RTO284ha/hvpNTrh55yQz2cVh0VvwBk3MjyY2tdmLH4SuCJDszYdYiw==" "integrity": "sha512-0yRVKG5XAbVo3rOaj/iFDlekGsxEqXKU9iXFbjyvHvRT2DFs+AjwtyvINsHCWw+4ed9yA4Y+wLIUNqzA0bfxLw==",
"requires": {
"tslib": "^1.9.0"
},
"dependencies": {
"tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
}
}
}, },
"ngx-openlayers": { "ngx-openlayers": {
"version": "1.0.0-next.17", "version": "1.0.0-next.17",

View File

@ -31,7 +31,10 @@
"bootstrap": "^4.4.1", "bootstrap": "^4.4.1",
"cesium": "^1.77.0", "cesium": "^1.77.0",
"core-js": "^2.6.11", "core-js": "^2.6.11",
"moment": "^2.27.0",
"ngrx-store-localstorage": "^10.0", "ngrx-store-localstorage": "^10.0",
"ngx-avatar": "^4.0.0",
"ngx-image-cropper": "^3.3.5",
"ngx-openlayers": "1.0.0-next.17", "ngx-openlayers": "1.0.0-next.17",
"ngx-uploadx": "^3.5.1", "ngx-uploadx": "^3.5.1",
"ol": "6.5.0", "ol": "6.5.0",
@ -40,9 +43,7 @@
"rxjs": "^6.5.4", "rxjs": "^6.5.4",
"tassign": "^1.0.0", "tassign": "^1.0.0",
"tslib": "^2.0.0", "tslib": "^2.0.0",
"zone.js": "~0.10.2", "zone.js": "~0.10.2"
"moment": "^2.27.0",
"ngx-avatar": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@angular-builders/custom-webpack": "~10.0.1", "@angular-builders/custom-webpack": "~10.0.1",

View File

@ -18,6 +18,7 @@
"ngx-uploadx": "^3.3.4", "ngx-uploadx": "^3.3.4",
"angular-oauth2-oidc": "^10.0.3", "angular-oauth2-oidc": "^10.0.3",
"moment": "^2.27.0", "moment": "^2.27.0",
"ngx-avatar": "^4.0.0" "ngx-avatar": "^4.0.0",
"ngx-image-cropper": "^3.3.5"
} }
} }

View File

@ -60,9 +60,11 @@ import { AppMenuComponent } from './components/app-menu/app-menu.component';
import { NotificationMenuComponent} from './components/notification-menu/notification-menu.component'; import { NotificationMenuComponent} from './components/notification-menu/notification-menu.component';
import { HelpMenuComponent} from './components/help-menu/help-menu.component'; import { HelpMenuComponent} from './components/help-menu/help-menu.component';
import { BackButtonComponent } from './components/back-button/back-button.component'; import { BackButtonComponent } from './components/back-button/back-button.component';
import { ThumbnailUploadModalComponent } from './components/thumbnail-upload-modal/thumbnail-upload-modal.component'; import { EditImageModalComponent } from './components/edit-image-modal/edit-image-modal.component';
import { AvatarComponent } from './components/avatar/avatar.component'; import { AvatarComponent } from './components/avatar/avatar.component';
import { AvatarModule } from 'ngx-avatar'; import { AvatarModule } from 'ngx-avatar';
import { ImageCropperModule } from 'ngx-image-cropper';
export { export {
SafePipe, SafePipe,
@ -120,7 +122,8 @@ export {
NgbModule, NgbModule,
FormsModule, FormsModule,
UploadxModule, UploadxModule,
AvatarModule AvatarModule,
ImageCropperModule
], ],
declarations: [ declarations: [
AppComponent, AppComponent,
@ -144,7 +147,7 @@ export {
HelpMenuComponent, HelpMenuComponent,
BackButtonComponent, BackButtonComponent,
ThumbnailComponent, ThumbnailComponent,
ThumbnailUploadModalComponent, EditImageModalComponent,
AvatarComponent AvatarComponent
], ],
exports: [ exports: [

View File

@ -0,0 +1,29 @@
<ng-template #upload_modal let-modal>
<div class="modal-header">
<h4 class="modal-title" i18n>Edit image</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<div class="cropper">
<image-cropper #imageCropper
[imageChangedEvent]="imageChangedEvent"
[maintainAspectRatio]="true"
format="jpeg"
[aspectRatio]="aspectRatio"
[autoCrop]="false"
(imageCropped)="imageCropped($event)"
(imageLoaded)="imageLoaded($event)"
(cropperReady)="cropperReady()"
(loadImageFailed)="loadImageFailed()"
></image-cropper>
</div>
<input #fileInput type="file" (change)="fileChangeEvent($event)" style="display:none" accept="image/*"/>
<span class="btn btn-primary" (click)="fileInput.click()" i18n>Select image</span>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" i18n>Apply</button>
<button type="button" autofocus class="btn btn-secondary" (click)="modal.close('Save click')" i18n="@@buttonCancel">Cancel</button>
</div>
</ng-template>

View File

@ -0,0 +1,4 @@
.cropper {
position: relative;
height: calc(60vh);
}

View File

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { EditImageModalComponent } from './edit-image-modal.component';
describe('EditImageModalComponent', () => {
let component: EditImageModalComponent;
let fixture: ComponentFixture<EditImageModalComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ EditImageModalComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(EditImageModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,43 @@
import { Component, OnInit,ViewChild,ElementRef } from '@angular/core';
import {NgbModal} from "@ng-bootstrap/ng-bootstrap"
import { ImageCroppedEvent,LoadedImage } from 'ngx-image-cropper';
@Component({
selector: 'fm-edit-image-modal',
templateUrl: './edit-image-modal.component.html',
styleUrls: ['./edit-image-modal.component.scss']
})
export class EditImageModalComponent implements OnInit {
@ViewChild('upload_modal') modal:ElementRef;
constructor(private modalService: NgbModal) { }
ngOnInit(): void {
}
open(endpoint:string,aspectRatio:number) {
this.aspectRatio= aspectRatio;
this.modalService.open(this.modal,{ size: 'lg' });
}
aspectRatio:number = 4/3;
imageChangedEvent: any = '';
croppedImage: any = '';
fileChangeEvent(event: any): void {
this.imageChangedEvent = event;
}
imageCropped(event: ImageCroppedEvent) {
this.croppedImage = event.base64;
}
imageLoaded(image: LoadedImage) {
}
cropperReady() {
// cropper ready
}
loadImageFailed() {
// show message
}
}

View File

@ -1,25 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ThumbnailUploadModalComponent } from './thumbnail-upload-modal.component';
describe('ThumbnailUploadModalComponent', () => {
let component: ThumbnailUploadModalComponent;
let fixture: ComponentFixture<ThumbnailUploadModalComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ThumbnailUploadModalComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ThumbnailUploadModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -1,15 +0,0 @@
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'fm-thumbnail-upload-modal',
templateUrl: './thumbnail-upload-modal.component.html',
styleUrls: ['./thumbnail-upload-modal.component.scss']
})
export class ThumbnailUploadModalComponent implements OnInit {
constructor() { }
ngOnInit(): void {
}
}

View File

@ -2,21 +2,8 @@
<div class="content"> <div class="content">
<img *ngIf="item.thumbnail" class="card-img-top" [src]="getThumbnailUrl(item)" /> <img *ngIf="item.thumbnail" class="card-img-top" [src]="getThumbnailUrl(item)" />
<div *ngIf="!item.thumbnail" class="large-icon" [style.font-size]="getFontSize()" [style.line-height]="getLineHeight()"><i [ngClass]="itemTypeService.getIcon(item.itemType)"></i></div> <div *ngIf="!item.thumbnail" class="large-icon" [style.font-size]="getFontSize()" [style.line-height]="getLineHeight()"><i [ngClass]="itemTypeService.getIcon(item.itemType)"></i></div>
<div *ngIf="canEdit()" class="edit btn btn-outline-primary rounded-circle" (click)="onEditClick()"><i class="fal fa-camera"></i></div> <div *ngIf="canEdit()" class="edit btn btn-secondary rounded-circle" (click)="onEditClick()"><i class="fal fa-camera"></i></div>
</div> </div>
</div> </div>
<ng-template #thumbnail_upload let-modal>
<div class="modal-header">
<h4 class="modal-title" i18n>Select period</h4>
<button type="button" class="close" aria-label="Close" (click)="modal.dismiss('Cross click')">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
</div> <fm-edit-image-modal #modal></fm-edit-image-modal>
<div class="modal-footer">
<!-- <button type="submit" class="btn btn-primary" (click)="handleSelect($event)" i18n>Select</button> -->
<button type="button" class="btn btn-secondary" (click)="modal.close('Save click')" i18n="@@buttonClose">Close</button>
</div>
</ng-template>

View File

@ -1,8 +1,9 @@
import { Component,Input ,ViewChild,ElementRef} from '@angular/core'; import { Component,Input ,ViewChild,ElementRef} from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import {NgbModal} from "@ng-bootstrap/ng-bootstrap"
import { IListItem } from '../../models/list.item'; import { IListItem } from '../../models/list.item';
import { commonReducers,ItemTypeService } from '../../../public-api' import { commonReducers,ItemTypeService } from '../../../public-api'
import { EditImageModalComponent} from '../edit-image-modal/edit-image-modal.component';
@Component({ @Component({
selector: 'fm-thumbnail', selector: 'fm-thumbnail',
@ -15,9 +16,9 @@ import { commonReducers,ItemTypeService } from '../../../public-api'
@Input() public item: IListItem; @Input() public item: IListItem;
@Input() public edit: boolean = false; @Input() public edit: boolean = false;
@ViewChild('thumbnail') el:ElementRef; @ViewChild('thumbnail') el:ElementRef;
@ViewChild('thumbnail_upload') modal:ElementRef; @ViewChild('modal') modal:EditImageModalComponent;
constructor(public store: Store<commonReducers.State>, public itemTypeService: ItemTypeService,private modalService: NgbModal) { constructor(public store: Store<commonReducers.State>, public itemTypeService: ItemTypeService) {
} }
getThumbnailUrl(item:IListItem):string { getThumbnailUrl(item:IListItem):string {
@ -46,6 +47,6 @@ import { commonReducers,ItemTypeService } from '../../../public-api'
} }
onEditClick() { onEditClick() {
this.modalService.open(this.modal); this.modal.open(this.item.url+"/thumbnail",4/3);
} }
} }