src/app/modules/certificate/components/browse-image-popup/browse-image-popup.component.ts
OnInit
selector | browse-image-popup |
styleUrls | ./browse-image-popup.component.scss |
templateUrl | ./browse-image-popup.component.html |
Properties |
|
Methods |
Inputs |
Outputs |
constructor(uploadCertificateService: UploadCertificateService, toasterService: ToasterService, resourceService: ResourceService, userService: UserService)
|
|||||||||||||||
Parameters :
|
enableUploadSignature | |
Type : boolean
|
|
Default value : false
|
|
logoType | |
Type : any
|
|
showSelectImageModal | |
Type : boolean
|
|
Default value : false
|
|
showUploadUserModal | |
Type : boolean
|
|
Default value : false
|
|
assetData | |
Type : EventEmitter
|
|
close | |
Type : EventEmitter
|
|
back |
back()
|
Returns :
void
|
browseImages |
browseImages()
|
Returns :
void
|
closeModel |
closeModel()
|
Returns :
void
|
dimentionCheck | ||||
dimentionCheck(image)
|
||||
Parameters :
Returns :
boolean
|
Async fileChange | ||||
fileChange(ev)
|
||||
Parameters :
Returns :
any
|
getAllImages |
getAllImages()
|
Returns :
void
|
getAssetList |
getAssetList()
|
Returns :
void
|
getImageProperties | ||||
getImageProperties(ev)
|
||||
Parameters :
Returns :
any
|
getImageURLs |
getImageURLs()
|
converting images files as data URLs
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
searchImage | ||||
searchImage(type?)
|
||||
Parameters :
Returns :
void
|
selectAndUseLogo |
selectAndUseLogo()
|
Returns :
void
|
Async selectLogo | ||||
selectLogo(logo)
|
||||
Parameters :
Returns :
any
|
showUploadSignature |
showUploadSignature()
|
Returns :
void
|
upload |
upload()
|
Returns :
void
|
uploadBlob | ||||
uploadBlob(data)
|
||||
Parameters :
Returns :
void
|
allImagesList |
Type : []
|
Default value : []
|
fileObj |
Type : any
|
imageDimensions |
Type : object
|
Default value : {
'LOGO': { type: 'PNG', dimensions: '88px X 88px' },
'SIGN': { type: 'PNG', dimensions: '112px X 46px' }
}
|
imageName |
imagesList |
Type : []
|
Default value : []
|
Public resourceService |
Type : ResourceService
|
selectedLogo |
Type : any
|
sign |
Type : string
|
Default value : 'SIGN'
|
Public toasterService |
Type : ToasterService
|
Public uploadCertificateService |
Type : UploadCertificateService
|
uploadForm |
Type : UntypedFormGroup
|
Public userService |
Type : UserService
|
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { UploadCertificateService } from '../../services/upload-certificate/upload-certificate.service';
import { ToasterService, ResourceService } from '@sunbird/shared';
import * as _ from 'lodash-es';
import { UserService } from '@sunbird/core';
import { UntypedFormGroup, UntypedFormControl, Validators } from '@angular/forms';
@Component({
selector: 'browse-image-popup',
templateUrl: './browse-image-popup.component.html',
styleUrls: ['./browse-image-popup.component.scss']
})
export class BrowseImagePopupComponent implements OnInit {
@Input() showSelectImageModal = false;
@Input() logoType;
@Input() enableUploadSignature = false;
@Output() assetData = new EventEmitter();
@Output() close = new EventEmitter();
@Input() showUploadUserModal = false;
imageName;
imagesList = [];
uploadForm: UntypedFormGroup;
fileObj: any;
selectedLogo: any;
sign = 'SIGN';
imageDimensions = {
'LOGO': { type: 'PNG', dimensions: '88px X 88px' },
'SIGN': { type: 'PNG', dimensions: '112px X 46px' }
};
allImagesList = [];
constructor(public uploadCertificateService: UploadCertificateService,
public toasterService: ToasterService,
public resourceService: ResourceService,
public userService: UserService) {
this.uploadForm = new UntypedFormGroup({
assetCaption: new UntypedFormControl('', [Validators.required]),
creator: new UntypedFormControl('', [Validators.required]),
creatorId: new UntypedFormControl('', [Validators.required])
});
}
ngOnInit() {
// this.getAssetList();
}
getAssetList() {
this.imageName = '';
this.selectedLogo = null;
this.uploadCertificateService.getAssetData().subscribe(res => {
this.imagesList = res.result.content;
}, error => {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
});
}
searchImage(type?) {
this.uploadCertificateService.getAssetData(this.imageName, type).subscribe(res => {
if (res && res.result) {
if (!type) {
this.imagesList = res.result.content;
} else {
this.allImagesList = res.result.content;
}
}
}, error => {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
});
}
async fileChange(ev) {
this.uploadForm.reset();
const imageProperties = await this.getImageProperties(ev.target.files[0]);
const isDimensionMatched = this.dimentionCheck(imageProperties);
const isTypeMatched = _.get(imageProperties, 'type').includes('png');
const isSizeMatched = _.get(imageProperties, 'size') < 1;
if (imageProperties && isSizeMatched && isTypeMatched && isDimensionMatched) {
this.fileObj = ev.target.files[0];
const fileName = _.get(this.fileObj, 'name').split('.')[0];
const userName = `${_.get(this.userService, 'userProfile.firstName') || ''} ${_.get(this.userService, 'userProfile.lastName') || ''}`;
this.uploadForm.patchValue({
'assetCaption': fileName,
'creator': userName,
'creatorId': _.get(this.userService, 'userProfile.id')
});
} else {
this.toasterService.error(_.get(this.resourceService, 'frmelmnts.cert.lbl.imageErrorMsg'));
}
}
getAllImages() {
this.imageName = '';
this.selectedLogo = null;
this.uploadCertificateService.getAssetData(null, 'all').subscribe(res => {
this.allImagesList = res.result.content;
}, error => {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
});
}
dimentionCheck(image) {
let flag = false;
if (image) {
const dimension = `${_.get(image, 'width')}px X ${_.get(image, 'height')}px`;
const logoType = _.get(this.logoType, 'type');
const requiredDimensions = this.imageDimensions[logoType]['dimensions'];
flag = _.isEqual(dimension, requiredDimensions);
}
return flag;
}
getImageProperties(ev) {
return new Promise((resolve, reject) => {
let imageData;
const file = ev;
const img = new Image();
if (file.url) {
img.src = file.url;
} else {
img.src = window.URL.createObjectURL(file);
}
img.onload = () => {
const width = img.naturalWidth;
const height = img.naturalHeight;
imageData = {
'height': height,
'width': width,
'size': _.toNumber((file.size / (1024 * 1024)).toFixed(2)),
'type': file.type
};
resolve(imageData);
};
});
}
browseImages() {
this.showUploadUserModal = true;
this.selectedLogo = null;
}
upload() {
// TODO: have to make more dynamic (use input variable autoUpload)
if (this.logoType.type !== this.sign) {
this.uploadCertificateService.createAsset(this.uploadForm.value, this.logoType.type).subscribe(res => {
if (res && res.result) {
this.uploadBlob(res);
}
}, error => {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
});
} else {
this.getImageURLs();
}
}
/**
* converting images files as data URLs
*/
getImageURLs() {
const file = this.fileObj;
const reader = new FileReader();
if (file) {
reader.readAsDataURL(file);
reader.onload = () => {
const imageURL = reader.result as string;
const image = {
'name': this.uploadForm.controls.assetCaption.value,
'url': imageURL,
'type': this.logoType.type,
'key': this.logoType.key,
'index': this.logoType.index
};
this.assetData.emit(image);
this.uploadForm.reset();
this.closeModel();
};
}
}
uploadBlob(data) {
if (data) {
const identifier = _.get(data, 'result.content_id');
this.uploadCertificateService.storeAsset(this.fileObj, identifier).subscribe(imageData => {
if (imageData.result) {
this.showUploadUserModal = false;
this.showSelectImageModal = false;
const image = {
'name': this.uploadForm.controls.assetCaption.value,
'url': imageData.result.artifactUrl,
'type': this.logoType.type,
'key': this.logoType.key,
'index': this.logoType.index
};
this.assetData.emit(image);
this.uploadForm.reset();
this.closeModel();
}
}, error => {
this.toasterService.error(_.get(this.resourceService, 'messages.fmsg.m0004'));
this.closeModel();
this.uploadForm.reset();
});
}
}
async selectLogo(logo) {
const file = {
url: logo.artifactUrl,
type: logo.mimeType,
size: logo.size
};
const imageProperties = await this.getImageProperties(file);
const isDimensionMatched = this.dimentionCheck(imageProperties);
const isTypeMatched = _.get(imageProperties, 'type').includes('png');
const isSizeMatched = _.get(imageProperties, 'size') < 1;
if (imageProperties && isSizeMatched && isTypeMatched && isDimensionMatched) {
this.selectedLogo = logo;
} else {
this.toasterService.error(_.get(this.resourceService, 'frmelmnts.cert.lbl.imageErrorMsg'));
}
}
back() {
if (this.logoType.type === this.sign) {
this.closeModel();
} else {
this.showUploadUserModal = false;
this.showSelectImageModal = true;
this.uploadForm.reset();
// this.close.emit();
this.selectedLogo = null;
}
}
closeModel() {
this.uploadForm.reset();
this.showUploadUserModal = false;
this.showSelectImageModal = false;
this.selectedLogo = null;
this.close.emit();
}
selectAndUseLogo() {
const image = {
'name': this.selectedLogo.name,
'url': this.selectedLogo.artifactUrl,
'type': this.logoType.type,
'key': this.logoType.key,
'index': this.logoType.index
};
this.assetData.emit(image);
this.selectedLogo = null;
this.closeModel();
}
showUploadSignature() {
this.logoType = { type: 'SIGN', index: 0, key: 'SIGN1' };
this.showSelectImageModal = false;
this.showUploadUserModal = true;
}
}
<app-modal-wrapper *ngIf="showSelectImageModal" [config]="{disableClose: true, size: 'large'}" (dismiss)="closeModel()"
#modal>
<ng-template sbModalContent>
<div class="sb-modal">
<div class="transition ui dimmer page modals active visible">
<div class="ui modal transition active visible large">
<div class="d-flex flex-ai-center sb-modal-header">
<img src="assets/images/image.svg" width="24px" height="20px" class="mr-8">
{{resourceService.frmelmnts?.lbl?.selectImage}}
</div>
<div class="sb-modal-content">
<div class="image-tabs px-8">
<input class="image-input" id="tab1" type="radio" name="tabs" checked>
<label for="tab1" (click)="getAssetList()" tabindex="0"
class="image-label mr-8">{{resourceService.frmelmnts?.lbl?.myImages}}</label>
<input class="image-input" id="tab2" type="radio" name="tabs">
<label (click)="getAllImages()" tabindex="0" for="tab2"
class="image-label">{{resourceService.frmelmnts?.lbl?.allImages}}</label>
<section id="content1">
<div class="twelve wide column">
<div class="sb-search-box mb-16">
<div class="input-div relative">
<input class="sb-search-input" [(ngModel)]="imageName" (keyup.enter)="searchImage()" type="text"
[placeholder]="resourceService?.frmelmnts?.cert?.prmpt?.searchImage" />
<i (click)="getAssetList()" tabindex="0" class="close icon"></i>
<i class="search icon"></i>
</div>
</div>
<div class="ui grid m-0">
<div class="three wide column p-8" *ngFor="let image of imagesList">
<div class="ui card text-center common-contribution-card active">
<div class="content">
<img [src]="image?.artifactUrl" tabindex="0" (click)="selectLogo(image)" rel="placeholder">
</div>
<div *ngIf="image?.versionKey === selectedLogo?.versionKey" class="selected-mark"><img
src="assets/images/checkbox-icon.svg" width="24px" height="24px"></div>
</div>
</div>
</div>
</div>
</section>
<section id="content2">
<div class="twelve wide column">
<div class="sb-search-box mb-16">
<div class="input-div relative">
<input class="sb-search-input" [(ngModel)]="imageName" (keyup.enter)="searchImage('all')"
type="text" [placeholder]="resourceService?.frmelmnts?.cert?.prmpt?.searchImage" />
<i (click)="getAllImages()" tabindex="0" class="close icon"></i>
<i class="search icon"></i>
</div>
</div>
<div class="ui grid m-0">
<div class="three wide column p-8" *ngFor="let image of allImagesList">
<div class="ui card text-center common-contribution-card active">
<div class="content">
<img [src]="image?.artifactUrl" tabindex="0" (click)="selectLogo(image)" rel="placeholder">
</div>
<div *ngIf="image?.versionKey === selectedLogo?.versionKey" class="selected-mark"><img
src="assets/images/checkbox-icon.svg" width="24px" height="24px"></div>
</div>
</div>
</div>
</div>
</section>
</div>
</div>
<div class="sb-modal-actions d-flex flex-jc-space-between flex-ai-center">
<div class="d-flex flex-ai-center relative">
<button class="sb-btn sb-btn-normal sb-btn-error mr-4" tabindex="0" (click)="closeModel()">
{{resourceService?.frmelmnts?.btn?.cancel}}
</button>
<div class="or-toggle">
<span>{{resourceService.frmelmnts?.lbl?.or}}</span>
</div>
<button class="sb-btn sb-btn-normal sb-btn-primary" [disabled]="!selectedLogo"
[ngClass]="{'sb-btn-disabled' : !selectedLogo}" tabindex="0" (click)="selectAndUseLogo()">
{{resourceService?.frmelmnts?.lbl?.Select}}
</button>
</div>
<div class="d-flex flex-ai-center relative">
<button class="sb-btn sb-btn-normal sb-btn-primary mr-8" tabindex="0" (click)="browseImages()">
{{resourceService.frmelmnts?.lbl?.uploadAndUse}}
</button>
<button *ngIf="enableUploadSignature" class="sb-btn sb-btn-normal sb-btn-primary" tabindex="1" (click)="showUploadSignature()">
{{resourceService.frmelmnts?.lbl?.uploadSignature}}
</button>
</div>
</div>
</div>
</div>
</div>
</ng-template>
</app-modal-wrapper>
<app-modal-wrapper *ngIf="showUploadUserModal" [config]="{disableClose: true, size: 'large'}" (dismiss)="closeModel()" #modal>
<ng-template sbModalContent>
<div class="sb-modal">
<div class="transition ui dimmer page modals active visible">
<div class="ui modal transition active visible large">
<div class="d-flex flex-ai-center sb-modal-header">
<img src="assets/images/upload.svg" width="24px" height="20px" class="mr-8">
{{resourceService.frmelmnts?.lbl?.uploadAndUse}}
</div>
<div class="sb-modal-content px-24 sb-bg-color-white">
<div class="twelve wide column">
<div class='ui stackable grid mt-0'>
<div class="six wide column">
<label>{{resourceService?.frmelmnts?.lbl?.chooseImageNote}}</label>
<div class="choose-img-box"><input (change)="fileChange($event)"
class="sb-btn-upload upload-btn fnormal" name="file" type="file"></div>
<div class="ui info message">
<ol class="ui list">
<li class="fsmall">{{resourceService?.frmelmnts?.lbl?.chooseImageType}}
{{imageDimensions[logoType.type]?.type}}</li>
<li class="fsmall">{{resourceService?.frmelmnts?.lbl?.chooseImageSize}}</li>
<li class="fsmall">{{resourceService?.frmelmnts?.lbl?.chooseImagedimensions}}
{{imageDimensions[logoType.type]?.dimensions}}</li>
</ol>
</div>
<div>
<label>{{resourceService?.frmelmnts?.lbl?.copyrights}}<span class="asterik">*</span></label>
<p class="fsmall">{{resourceService?.frmelmnts?.lbl?.uploadlicense}}</p>
</div>
</div>
<div class="six wide column pl-0">
<div [formGroup]="uploadForm" class="border-line">
<div class="ui info message p-16">
<div class="d-flex">
<img src="assets/images/information-icon.svg" width="24px" height="22px" class="mr-8">
<div class="fsmall" class="drop-img-text fsmall">
{{resourceService?.frmelmnts?.lbl?.imageDrapAndDrop}}
</div>
</div>
</div>
<div class="sb-field mb-16">
<label>{{resourceService?.frmelmnts?.lbl?.assetCaption}} <span class="asterik">*</span></label>
<div class="sb-field">
<input formControlName="assetCaption" class="sb-form-control is-valid"
placeholder="Enter asset caption">
</div>
</div>
<div class="sb-field">
<label>{{resourceService?.frmelmnts?.lbl?.creator}}</label>
<div class="sb-field">
<input formControlName="creator" class="sb-form-control is-valid" placeholder="Enter Name">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sb-modal-actions d-flex flex-jc-space-between flex-ai-center">
<div class="d-flex flex-ai-center relative">
<button class="sb-btn sb-btn-normal sb-btn-error mr-4" (click)="back()" tabindex="0">
{{resourceService?.frmelmnts?.btn?.cancel}}
</button>
<div class="or-toggle">
<span>{{resourceService.frmelmnts?.lbl?.or}}</span>
</div>
<button class="sb-btn sb-btn-normal sb-btn-primary"
[ngClass]="{'sb-btn-disabled': (!uploadForm.valid || !fileObj)}"
[disabled]="(!uploadForm.valid || !fileObj)" (click)="upload()">
{{resourceService.frmelmnts?.lbl?.uploadAndUse}}
</button>
</div>
<button class="sb-btn sb-btn-normal sb-btn-gray" (click)="back()" tabindex="0">
{{resourceService?.frmelmnts?.btn?.back }}
</button>
</div>
</div>
</div>
</div>
</ng-template>
</app-modal-wrapper>
./browse-image-popup.component.scss
@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;
// image modal css //
.sb-imagemodal {
.sb-modal-content {
.asterik{
color: var(--red-400);
}
.image-tabs {
margin: 0 auto;
background: var(--white);
}
.image-input {
display: none;
}
.image-label {
display: inline-block;
margin: 0 0 -0.0625rem;
padding: calculateRem(14px) calculateRem(24px);
font-weight: 600;
text-align: center;
color: var(--gray-200);
border: calculateRem(1px) solid transparent;
}
.image-label:before {
font-family: fontawesome;
font-weight: normal;
margin-right: calculateRem(10px);
}
.image-label:hover {
color: var(--gray-200);
cursor: pointer;
}
.image-input:checked+.image-label {
color: var(--gray-800);
border-bottom: calculateRem(3px) solid var(--primary-400);
}
#tab1:checked~#content1,
#tab2:checked~#content2 {
display: block;
}
section {
display: none;
padding: calculateRem(16px) 0 0;
border-top: calculateRem(1px) solid var(--rc-dddddd);
.sb-search-box .sb-search-input {
padding: 0.75rem 2.75rem;
}
.sb-search-box .icon {
position: absolute;
margin: 0;
height: calculateRem(24px);
width: calculateRem(24px);
border-radius: 50%;
background: var(--gray-200);
}
i.icon.search:before {
content: "\f002";
background: var(--gray-200);
position: relative;
top:calculateRem(2px);
color: var(--white);
font-size: calculateRem(12px);
}
i.icon.close:before {
content: "\f00d";
position: relative;
top: calculateRem(3px);
}
.ui.card:last-child {
margin-bottom: 0;
}
.ui.card:first-child {
margin-top: 0;
}
.common-contribution-card {
box-sizing: border-box;
border: calculateRem(0.5px) solid rgba(123, 134, 244, .39);
border-radius: .25rem;
background-color: var(--white);
box-shadow: none;
height: 100%;
}
.ui.card {
margin: 1em 0;
}
.ui.card,
.ui.cards>.card {
max-width: 100%;
position: relative;
display: flex;
flex-direction: column;
width: calculateRem(292px);
min-height: 0;
background: var(--white);
padding: 0;
border: none;
border-radius: .28571429rem;
box-shadow: 0 calculateRem(1px) calculateRem(3px) 0 var(--gray-100), 0 0 0 calculateRem(1px) var(--gray-100);
transition: box-shadow .1s ease, transform .1s ease;
z-index: '';
position: relative;
.selected-mark{
display: none;
}
&.active {
transform: scale(1.03, 1.03);
.selected-mark{
position: absolute;
right:calculateRem(4px);
top:0;
display: block;
}
}
&:hover {
transform: scale(1.03, 1.03);
}
}
.ui.card>.content,
.ui.cards>.card>.content {
flex-grow: 1;
border: none;
border-top: calculateRem(1px) solid rgba(var(--rc-rgba-black), .1);
background: 0 0;
margin: 0;
padding: 0;
box-shadow: none;
font-size: 1em;
border-radius: 0;
}
.ui.card .content img,
.ui.cards>.card .content img {
display: inline-block;
vertical-align: middle;
width: 100%;
height: calculateRem(150px);
}
}
}
.sb-modal-actions {
.or-toggle {
background: var(--white);
border-radius: 50%;
width: calculateRem(24px);
height: calculateRem(24px);
position: absolute;
left: 42%;
z-index: 2;
span {
position: relative;
top: calculateRem(3px);
left: calculateRem(5px);
font-size: calculateRem(14px);
}
}
}
}
.sb-uploadmodal {
.sb-modal-content {
.asterik{
color: var(--red-400);
}
.choose-img-box{
border: calculateRem(3px) solid var(--black);
padding: calculateRem(24px);
border-style: dashed;
border-radius: calculateRem(4px);
}
.border-line{
border-left: calculateRem(2px) solid var(--rc-dddddd);
height: 100%;
padding-left: calculateRem(16px);
html[dir='rtl'] & {
border-right: calculateRem(2px) solid var(--rc-dddddd);
height: 100%;
padding-right: calculateRem(16px);
}
}
.drop-img-text{
line-height: 1.4em;
}
.sb-field {
.tags {
list-style: none;
margin: 0;
overflow: hidden;
padding: 0;
border-bottom: calculateRem(1px) solid var(--gray-200);
}
.tags li {
float: left;
margin-bottom: 0;
position: relative;
img{
position: absolute;
right: calculateRem(10px);
}
}
.tag {
background: var(--primary);
border-radius: calculateRem(3px) 0 0 calculateRem(3px);
color: var(--white);
display: inline-block;
height: calculateRem(26px);
line-height: calculateRem(26px);
padding: 0 calculateRem(20px) 0 calculateRem(23px);
position: relative;
margin: 0 calculateRem(10px) calculateRem(10px) 0;
text-decoration: none;
-webkit-transition: color 0.2s;
}
.tag::before {
background: var(--white);
border-radius: calculateRem(10px);
box-shadow: inset 0 calculateRem(1px) rgba(var(--rc-rgba-black), 0.25);
content: '';
height: 0.375rem;
left: 0.625rem;
position: absolute;
width: 0.375rem;
top: 0.625rem;
}
.tag::after {
background: var(--white);
border-bottom: 0.8125rem solid transparent;
border-left: 0.625rem solid 0.625rem solid var(--primary);;
border-top: 0.8125rem solid transparent;
content: '';
position: absolute;
right: 0;
top: 0;
}
}
}
.sb-modal-actions {
.or-toggle {
background: var(--white);
border-radius: 50%;
width: 1.5rem;
height: 1.5rem;
position: absolute;
left: 31%;
z-index: 2;
span {
position: relative;
top: 0.1875rem;
left: 0.3125rem;
font-size: 0.875rem;
}
}
}
}