Merge branch 'feature/thumbnail_upload' into develop
Some checks failed
FarmMaps.Develop/FarmMapsLib/pipeline/head There was a failure building this commit
Some checks failed
FarmMaps.Develop/FarmMapsLib/pipeline/head There was a failure building this commit
This commit is contained in:
commit
e262f7c65d
36
package-lock.json
generated
36
package-lock.json
generated
@ -1865,25 +1865,25 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@farmmaps/common": {
|
"@farmmaps/common": {
|
||||||
"version": "0.0.1-prerelease.530",
|
"version": "0.0.1-prerelease.548",
|
||||||
"resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common/-/common-0.0.1-prerelease.530.tgz",
|
"resolved": "https://repository.akkerweb.nl/repository/npm-group/@farmmaps/common/-/common-0.0.1-prerelease.548.tgz",
|
||||||
"integrity": "sha512-cvUKFctQvl91gE5zCJvzxhcnZ35XpletqFmxOFwj6qxLr975qs/Ia9VrzwjkqoIoXlsO9xlM/0Cn1PnPsF7nIg==",
|
"integrity": "sha512-gI+5kwpdimDkJUqU51PsyfZ0My5QRrEtwHGpCivd4kHxBZJ053cz6vHFnH1HquxesIXBVmDxjyeYGCrxhXVIOA==",
|
||||||
"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.548",
|
||||||
"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.548.tgz",
|
||||||
"integrity": "sha512-LU4yzsTvja85GciySpJB5LjUD7fndEsnd2KKj0q9+IFZl9jOFfVcP+/3nImsYYmV9CK6sczNdevaSxQW+lpseQ==",
|
"integrity": "sha512-rrlYUZvq4r1ANlbinucdasy5iRidOt8DI9V7ra4pKcgZqlsD5hteeosX45DnDlbSvcNzTtY3A0E28e4WXd25jA==",
|
||||||
"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.548",
|
||||||
"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.548.tgz",
|
||||||
"integrity": "sha512-4OG3yv6vOMJZ5dLZ2e8W9P1F1qvzcYBA/zCIA+kxfS0iiOfrOIiJgDvXPhMot+swATSsWeY4Txh6ydh6KmTzlg==",
|
"integrity": "sha512-l3XQMSclt6x0fIjKw4K9j1IAr+L+0alHLd/9p80jfCkhB0qo1jZf/TorA636PSYB9NIBioiXOKMDVqTuPi+s/w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"tslib": "^2.0.0"
|
"tslib": "^2.0.0"
|
||||||
}
|
}
|
||||||
@ -8604,10 +8604,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",
|
||||||
|
14
package.json
14
package.json
@ -19,9 +19,9 @@
|
|||||||
"@angular/platform-browser": "~10.2.4",
|
"@angular/platform-browser": "~10.2.4",
|
||||||
"@angular/platform-browser-dynamic": "~10.2.4",
|
"@angular/platform-browser-dynamic": "~10.2.4",
|
||||||
"@angular/router": "~10.2.4",
|
"@angular/router": "~10.2.4",
|
||||||
"@farmmaps/common": ">=0.0.1-prerelease.530 <0.0.1",
|
"@farmmaps/common": ">=0.0.1-prerelease.548 <0.0.1",
|
||||||
"@farmmaps/common-map": ">=0.0.1-prerelease.530 <0.0.1",
|
"@farmmaps/common-map": ">=0.0.1-prerelease.548 <0.0.1",
|
||||||
"@farmmaps/common-map3d": ">=0.0.1-prerelease.530 <0.0.1",
|
"@farmmaps/common-map3d": ">=0.0.1-prerelease.548 <0.0.1",
|
||||||
"@microsoft/signalr": "^3.1.3",
|
"@microsoft/signalr": "^3.1.3",
|
||||||
"@ng-bootstrap/ng-bootstrap": "^7.0",
|
"@ng-bootstrap/ng-bootstrap": "^7.0",
|
||||||
"@ngrx/effects": "^10.0",
|
"@ngrx/effects": "^10.0",
|
||||||
@ -31,8 +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-bootstrap": "^5.6.1",
|
"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",
|
||||||
@ -41,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",
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
<div *ngIf="item;let item">
|
<div *ngIf="item;let item">
|
||||||
<div class="card border-0">
|
<div class="card border-0">
|
||||||
<img *ngIf="item.thumbnail" class="card-img-top" [src]="getThumbnailUrl(item)" />
|
<fm-thumbnail [item]="item" [edit]="item.isEditable"></fm-thumbnail>
|
||||||
<div *ngIf="!item.thumbnail" class="big-icon" [style.background-color]="itemTypeService.getColor(item.itemType)">
|
|
||||||
<i [ngClass]="itemTypeService.getIcon(item.itemType)"></i>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import { ItemService } from './services/item.service';
|
|||||||
import { EventService } from './services/event.service';
|
import { EventService } from './services/event.service';
|
||||||
import { TypeaheadService } from './services/typeahead.service';
|
import { TypeaheadService } from './services/typeahead.service';
|
||||||
import { UserService } from './services/user.service';
|
import { UserService } from './services/user.service';
|
||||||
|
import { ImageService } from './services/image.service';
|
||||||
import { WeatherService} from './services/weather.service';
|
import { WeatherService} from './services/weather.service';
|
||||||
import { AppConfig } from './shared/app.config';
|
import { AppConfig } from './shared/app.config';
|
||||||
import { AccessTokenInterceptor } from "./shared/accesstoken.interceptor";
|
import { AccessTokenInterceptor } from "./shared/accesstoken.interceptor";
|
||||||
@ -42,6 +43,7 @@ export {
|
|||||||
EventService,
|
EventService,
|
||||||
TypeaheadService,
|
TypeaheadService,
|
||||||
UserService,
|
UserService,
|
||||||
|
ImageService,
|
||||||
WeatherService,
|
WeatherService,
|
||||||
AppConfig,
|
AppConfig,
|
||||||
AccessTokenInterceptor,
|
AccessTokenInterceptor,
|
||||||
|
@ -60,8 +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 { 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,
|
||||||
@ -119,7 +122,8 @@ export {
|
|||||||
NgbModule,
|
NgbModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
UploadxModule,
|
UploadxModule,
|
||||||
AvatarModule
|
AvatarModule,
|
||||||
|
ImageCropperModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
@ -143,6 +147,7 @@ export {
|
|||||||
HelpMenuComponent,
|
HelpMenuComponent,
|
||||||
BackButtonComponent,
|
BackButtonComponent,
|
||||||
ThumbnailComponent,
|
ThumbnailComponent,
|
||||||
|
EditImageModalComponent,
|
||||||
AvatarComponent
|
AvatarComponent
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
<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">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="cropper">
|
||||||
|
<div *ngIf="!isImageLoaded" class="no-image" (click)="fileInput.click()">
|
||||||
|
<i class="fal fa-image"></i>
|
||||||
|
<div i18n>No image selected</div>
|
||||||
|
</div>
|
||||||
|
<image-cropper #imageCropper
|
||||||
|
[imageChangedEvent]="imageChangedEvent"
|
||||||
|
[maintainAspectRatio]="true"
|
||||||
|
format="jpeg"
|
||||||
|
[aspectRatio]="aspectRatio"
|
||||||
|
[autoCrop]="true"
|
||||||
|
(imageCropped)="imageCropped($event)"
|
||||||
|
(imageLoaded)="imageLoaded($event)"
|
||||||
|
(cropperReady)="cropperReady()"
|
||||||
|
(loadImageFailed)="loadImageFailed()"
|
||||||
|
[imageURL]="imageUrl"
|
||||||
|
></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 [disabled]="!isImageLoaded" (click)="save()">Apply</button>
|
||||||
|
<button type="button" autofocus class="btn btn-secondary" (click)="modal.close('Save click')" i18n="@@buttonCancel">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
@ -0,0 +1,13 @@
|
|||||||
|
.cropper {
|
||||||
|
position: relative;
|
||||||
|
height: calc(60vh);
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-image {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-image i {
|
||||||
|
font-size: calc(50vh);
|
||||||
|
color: gray;
|
||||||
|
}
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,62 @@
|
|||||||
|
import { Component, OnInit,ViewChild,ElementRef,EventEmitter, Output } from '@angular/core';
|
||||||
|
import { HttpClient, HttpParams,HttpHeaders } from "@angular/common/http";
|
||||||
|
import {NgbModal} from "@ng-bootstrap/ng-bootstrap"
|
||||||
|
import { ImageCroppedEvent,LoadedImage } from 'ngx-image-cropper';
|
||||||
|
import {ImageService } from '../../services/image.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'fm-edit-image-modal',
|
||||||
|
templateUrl: './edit-image-modal.component.html',
|
||||||
|
styleUrls: ['./edit-image-modal.component.scss']
|
||||||
|
})
|
||||||
|
export class EditImageModalComponent implements OnInit {
|
||||||
|
|
||||||
|
@Output() changed = new EventEmitter();
|
||||||
|
@ViewChild('upload_modal') modal:ElementRef;
|
||||||
|
|
||||||
|
constructor(private modalService: NgbModal,public imageService:ImageService) { }
|
||||||
|
|
||||||
|
isImageLoaded:boolean = false;
|
||||||
|
aspectRatio:number = 4/3;
|
||||||
|
imageChangedEvent: any = '';
|
||||||
|
croppedImage: string = '';
|
||||||
|
endpointUrl:string = null;
|
||||||
|
imageUrl:string = null;
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
|
||||||
|
open(endpoint:string,aspectRatio:number) {
|
||||||
|
this.endpointUrl = endpoint;
|
||||||
|
this.imageUrl = endpoint;
|
||||||
|
this.aspectRatio= aspectRatio;
|
||||||
|
this.modalService.open(this.modal,{ size: 'lg' });
|
||||||
|
}
|
||||||
|
|
||||||
|
fileChangeEvent(event: any): void {
|
||||||
|
this.imageChangedEvent = event;
|
||||||
|
}
|
||||||
|
imageCropped(event: ImageCroppedEvent) {
|
||||||
|
this.croppedImage = event.base64;
|
||||||
|
}
|
||||||
|
imageLoaded(image: LoadedImage) {
|
||||||
|
this.isImageLoaded=true;
|
||||||
|
}
|
||||||
|
cropperReady() {
|
||||||
|
// cropper ready
|
||||||
|
}
|
||||||
|
loadImageFailed() {
|
||||||
|
// show message
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
if(this.croppedImage) {
|
||||||
|
|
||||||
|
var body = this.croppedImage.substr(23);
|
||||||
|
this.imageService.putImage(this.endpointUrl,this.imageService.b64toBlob(body,"image/jpeg")).subscribe(() => {
|
||||||
|
this.changed.emit({});
|
||||||
|
});
|
||||||
|
this,this.modalService.dismissAll("Save");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
<div class="thumbnail">
|
<div #thumbnail class="thumbnail" [style.background-color]="itemTypeService.getColor(item.itemType)" >
|
||||||
<img *ngIf="item.thumbnail" class="card-img-top" [src]="getThumbnailUrl(item)" />
|
<div class="content">
|
||||||
<div *ngIf="!item.thumbnail" class="big-icon" [style.background-color]="itemTypeService.getColor(item.itemType)">
|
<img *ngIf="item.thumbnail" class="card-img-top" [src]="getThumbnailUrl(item)" />
|
||||||
<i [ngClass]="itemTypeService.getIcon(item.itemType)"></i>
|
<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-secondary rounded-circle" (click)="onEditClick()"><i class="fal fa-camera"></i></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<fm-edit-image-modal #modal (changed)="onChanged()"></fm-edit-image-modal>
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
.thumbnail {
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
padding-top: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.large-icon i {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
width: 2.5rem;
|
||||||
|
height: 2.5rem;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 2.5rem;
|
||||||
|
}
|
@ -1,7 +1,10 @@
|
|||||||
import { Component,Input } from '@angular/core';
|
import { Component,Input ,ViewChild,ElementRef,ChangeDetectorRef} from '@angular/core';
|
||||||
import { Store } from '@ngrx/store';
|
import { Store } from '@ngrx/store';
|
||||||
import { IItem } from '../../models/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';
|
||||||
|
import { AppConfig } from "../../shared/app.config";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'fm-thumbnail',
|
selector: 'fm-thumbnail',
|
||||||
@ -11,12 +14,48 @@ import { commonReducers,ItemTypeService } from '../../../public-api'
|
|||||||
|
|
||||||
|
|
||||||
export class ThumbnailComponent {
|
export class ThumbnailComponent {
|
||||||
@Input() public item: IItem;
|
@Input() public item: IListItem;
|
||||||
|
@Input() public edit: boolean = false;
|
||||||
|
@ViewChild('thumbnail') el:ElementRef;
|
||||||
|
@ViewChild('modal') modal:EditImageModalComponent;
|
||||||
|
|
||||||
constructor(public store: Store<commonReducers.State>, public itemTypeService: ItemTypeService) {
|
constructor(public store: Store<commonReducers.State>, public itemTypeService: ItemTypeService,public appConfig: AppConfig,private changeDetector:ChangeDetectorRef) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getThumbnailUrl(item:IItem):string {
|
getThumbnailUrl(item:IListItem):string {
|
||||||
return item.url+'/thumbnail?v=' + Date.parse(item.updated);
|
return this.appConfig.getConfig("apiEndPoint")+item.url+'/thumbnail?v=' + Date.parse(item.updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFontSize():string {
|
||||||
|
if(this.el) {
|
||||||
|
var h = this.el.nativeElement.offsetHeight - (this.el.nativeElement.offsetHeight / 5 )
|
||||||
|
return h + "px";
|
||||||
|
} else {
|
||||||
|
return "1em";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getLineHeight():string {
|
||||||
|
if(this.el) {
|
||||||
|
return this.el.nativeElement.offsetHeight + "px";
|
||||||
|
} else {
|
||||||
|
return "1em";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
canEdit():boolean {
|
||||||
|
return this.edit && this.item != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditClick() {
|
||||||
|
var endpoint = `${this.appConfig.getConfig("apiEndPoint")}/api/v1/items/${this.item.code}/thumbnail`;
|
||||||
|
this.modal.open(endpoint,4/3);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChanged() {
|
||||||
|
if(this.item) {
|
||||||
|
this.item.updated = new Date(new Date().getTime()).toISOString();
|
||||||
|
this.changeDetector.detectChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,4 @@
|
|||||||
.menu-button {
|
.menu-button {
|
||||||
background-color: purple;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 2.5em;
|
width: 2.5em;
|
||||||
height: 2.5em;
|
height: 2.5em;
|
||||||
|
44
projects/common/src/fm/services/image.service.ts
Normal file
44
projects/common/src/fm/services/image.service.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { IUser } from '../models/user';
|
||||||
|
import { HttpClient,HttpHeaders } from "@angular/common/http";
|
||||||
|
import { AppConfig } from "../shared/app.config";
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class ImageService {
|
||||||
|
constructor(public httpClient: HttpClient, public appConfig: AppConfig) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ApiEndpoint() {
|
||||||
|
return this.appConfig.getConfig("apiEndPoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
putImage(endpoint:string,blob:Blob) {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', blob,blob.type);
|
||||||
|
return this.httpClient.put<any>(endpoint,formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
b64toBlob(b64Data:string, contentType?:string):Blob {
|
||||||
|
const sliceSize = 512;
|
||||||
|
const byteCharacters = atob(b64Data);
|
||||||
|
const byteArrays = [];
|
||||||
|
|
||||||
|
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
||||||
|
const slice = byteCharacters.slice(offset, offset + sliceSize);
|
||||||
|
|
||||||
|
const byteNumbers = new Array(slice.length);
|
||||||
|
for (let i = 0; i < slice.length; i++) {
|
||||||
|
byteNumbers[i] = slice.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
const byteArray = new Uint8Array(byteNumbers);
|
||||||
|
byteArrays.push(byteArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
const blob = new Blob(byteArrays, {type: contentType});
|
||||||
|
return blob;
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"issuer": "https://accounts.test.farmmaps.eu",
|
"issuer": "https://accounts.test.farmmaps.eu",
|
||||||
"clientId": "farmmapsdev",
|
"clientId": "farmmapsdev",
|
||||||
"audience": "https://test.farmmaps.eu",
|
"audience": "http://localhost:8082",
|
||||||
"requireHttps": true,
|
"requireHttps": true,
|
||||||
"apiEndPoint": "https://test.farmmaps.eu",
|
"apiEndPoint": "http://localhost:8082",
|
||||||
"grantType":"code"
|
"grantType":"code"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user