File

src/app/modules/certificate/components/svg-editor/svg-editor.component.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods

Constructor

constructor(uploadCertificateService: UploadCertificateService, userService: UserService, sanitizer: DomSanitizer, activatedRoute: ActivatedRoute, certRegService: CertRegService, toasterService: ToasterService, resourceService: ResourceService, navigationHelperService: NavigationHelperService, layoutService: LayoutService)
Parameters :
Name Type Optional
uploadCertificateService UploadCertificateService No
userService UserService No
sanitizer DomSanitizer No
activatedRoute ActivatedRoute No
certRegService CertRegService No
toasterService ToasterService No
resourceService ResourceService No
navigationHelperService NavigationHelperService No
layoutService LayoutService No

Methods

assetData
assetData(data)
Parameters :
Name Optional
data No
Returns : void
back
back()
Returns : void
certificateCreation
certificateCreation(ev)
Parameters :
Name Optional
ev No
Returns : void
chooseCertificate
chooseCertificate(certificate)
Parameters :
Name Optional
certificate No
Returns : void
close
close()
Returns : void
closeSaveAndPreview
closeSaveAndPreview()
Returns : void
closeSVGInputModal
closeSVGInputModal()
Returns : void
convertHtml
convertHtml(tag)
Parameters :
Name Optional
tag No
Returns : any
createCertTemplate
createCertTemplate()
Returns : void
editSVG
editSVG(logosArray, stateLogos)
Parameters :
Name Optional
logosArray No
stateLogos No
Returns : any
elementClicked
elementClicked(e: any)
Parameters :
Name Type Optional
e any No
Returns : void
getBase64Data
getBase64Data(ev)
Parameters :
Name Optional
ev No
Returns : string
getDefaultTemplates
getDefaultTemplates()
Returns : void
getImagePath
getImagePath()
Returns : any
getSVGTemplate
getSVGTemplate()
Returns : void
initializeFormFields
initializeFormFields()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
openSateLogos
openSateLogos(type)
Parameters :
Name Optional
type No
Returns : void
openSignLogos
openSignLogos(type)
Parameters :
Name Optional
type No
Returns : void
previewAndSave
previewAndSave()
Returns : void
previewCertificate
previewCertificate()
Returns : void
previewUpdatedSVGCertificate
previewUpdatedSVGCertificate()
Returns : void
redoLayout
redoLayout()
Returns : void
removeImage
removeImage(key)
Parameters :
Name Optional
key No
Returns : void
sanitizeHTML
sanitizeHTML(html)
Parameters :
Name Optional
html No
Returns : any
saveUpdatedCertificate
saveUpdatedCertificate()
Returns : void
svgAssetData
svgAssetData(imageObj)
Parameters :
Name Optional
imageObj No
Returns : void
toDataURL
toDataURL(image)
Parameters :
Name Optional
image No
Returns : any
toggleSVGPreview
toggleSVGPreview()
Returns : void
updateSigns
updateSigns(stateLogos)
Parameters :
Name Optional
stateLogos No
Returns : void
updateStateLogos
updateStateLogos(stateLogos)
Parameters :
Name Optional
stateLogos No
Returns : void
updateSVGInputTag
updateSVGInputTag()
Returns : void
updateTitles
updateTitles()
Returns : void
uploadTemplate
uploadTemplate(base64Url, identifier)
Parameters :
Name Optional
base64Url No
identifier No
Returns : void
urltoFile
urltoFile(url, filename, mimeType)
Parameters :
Name Optional
url No
filename No
mimeType No
Returns : any
validateForm
validateForm()
Returns : void

Properties

Public browseImage
Type : BrowseImagePopupComponent
Decorators :
@ViewChild(BrowseImagePopupComponent)
center
Type : number
Default value : 275
certConfigModalInstance
Default value : new CertConfigModel()
certLogos
Type : any
Default value : []
certSigns
Type : any
Default value : []
classNames
Type : object
Default value : { 'STATE_LOGOS': 'state-logo', 'STATE_TITLE': 'state-title', 'SIGN_LOGO': ['signatureImg1', 'signatureImg2'], 'CERT_TITLE': 'cert-title', 'DESIGNATIONS_NAMES': ['signatureTitle1', 'signatureTitle2'], 'DESIGNATIONS': ['signatureTitle1a', 'signatureTitle2a'] }
createTemplateForm
Type : UntypedFormGroup
defaultCertificates
Type : []
Default value : []
disableCreateTemplate
Default value : true
disableSVGImageModal
Type : boolean
Default value : false
edit
Type : Subject<any>
Default value : new Subject()
finalSVGurl
Type : any
FIRST_PANEL_LAYOUT
getBase64FromUrl
Default value : () => {...}
images
Type : object
Default value : { 'LOGO1': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''}, 'LOGO2': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''}, 'SIGN1': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''}, 'SIGN2': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''} }
layoutConfiguration
Type : any
Public layoutService
Type : LayoutService
logoHtml
logoType
mode
Type : any
Public navigationHelperService
Type : NavigationHelperService
optionSing
Type : string
Default value : 'SIGN2'
previewButton
Type : string
Default value : 'show'
previewSvgData
Type : any
queryParams
Type : any
refreshEditor
Type : Subject<any>
Default value : new Subject()
Public resourceService
Type : ResourceService
save
Type : Subject<any>
Default value : new Subject()
saveAndPreview
Type : boolean
Default value : false
SECOND_PANEL_LAYOUT
selectedCertificate
Type : any
Default value : {}
selectedSVGObject
Type : any
Default value : {}
selectLanguage
Type : any
selectLanguageOption
Type : any
Default value : []
selectState
Type : any
selectStateOption
Type : any
Default value : []
showPreviewButton
Type : boolean
Default value : true
showSelectImageModal
showSVGInputModal
Type : boolean
Default value : false
showUploadUserModal
svgData
Public toasterService
Type : ToasterService
togglePreview
Type : Subject<any>
Default value : new Subject()
Public unsubscribe$
Default value : new Subject<void>()
Public uploadCertificateService
Type : UploadCertificateService
userConsent
Type : boolean
Default value : false
Public userService
Type : UserService
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import * as _ from 'lodash-es';
import { UploadCertificateService } from '../../services/upload-certificate/upload-certificate.service';
import { UntypedFormGroup, UntypedFormControl, Validators } from '@angular/forms';
import { UserService, CertRegService } from '@sunbird/core';
import { ToasterService, ResourceService, NavigationHelperService, LayoutService, COLUMN_TYPE } from '@sunbird/shared';
import { DomSanitizer } from '@angular/platform-browser';
import { CertConfigModel } from '../../models/cert-config-model/cert-config-model';
import { BrowseImagePopupComponent } from '../browse-image-popup/browse-image-popup.component';
import {ActivatedRoute} from '@angular/router';
import dayjs from 'dayjs';
@Component({
  selector: 'app-svg-editor',
  templateUrl: './svg-editor.component.html',
  styleUrls: ['./svg-editor.component.scss']
})
export class SvgEditorComponent implements OnInit, OnDestroy {

  @ViewChild(BrowseImagePopupComponent)
  public browseImage: BrowseImagePopupComponent;

  public unsubscribe$ = new Subject<void>();
  createTemplateForm: UntypedFormGroup;
  selectStateOption: any = [];
  selectLanguageOption: any = [];
  selectState: any;
  selectLanguage: any;
  showSelectImageModal;
  showUploadUserModal;
  certLogos: any = [];
  certSigns: any = [];
  logoType;
  // api call
  defaultCertificates = [];
  selectedCertificate: any = {};
  logoHtml;
  svgData;
  center = 275;
  disableCreateTemplate = true;
  certConfigModalInstance = new CertConfigModel();
  layoutConfiguration: any;
  FIRST_PANEL_LAYOUT;
  SECOND_PANEL_LAYOUT;
  images = {
    'LOGO1': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''},
    'LOGO2': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''},
    'SIGN1': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''},
    'SIGN2': { 'index': null, 'name' : '' , 'key': '', 'type': '', 'url': ''}
  };
  finalSVGurl: any;
  classNames = {
    'STATE_LOGOS': 'state-logo',
    'STATE_TITLE': 'state-title',
    'SIGN_LOGO': ['signatureImg1', 'signatureImg2'],
    'CERT_TITLE': 'cert-title',
    'DESIGNATIONS_NAMES': ['signatureTitle1', 'signatureTitle2'],
    'DESIGNATIONS': ['signatureTitle1a', 'signatureTitle2a']
  };
  optionSing = 'SIGN2';
  queryParams: any;
  mode: any;
  edit: Subject<any> = new Subject();
  refreshEditor: Subject<any> = new Subject();
  togglePreview: Subject<any> = new Subject();
  save: Subject<any> = new Subject();
  showSVGInputModal: boolean = false;
  disableSVGImageModal: boolean = false;
  selectedSVGObject: any = {};
  showPreviewButton: boolean = true;
  previewButton: string = 'show';
  saveAndPreview: boolean = false;
  userConsent: boolean = false;
  previewSvgData: any;

  constructor(public uploadCertificateService: UploadCertificateService,
    public userService: UserService,
    private sanitizer: DomSanitizer,
    private activatedRoute: ActivatedRoute,
    private certRegService: CertRegService,
    public toasterService: ToasterService,
    public resourceService: ResourceService,
    public navigationHelperService: NavigationHelperService,
    public layoutService: LayoutService) {
  }

  ngOnInit() {
    this.activatedRoute.queryParams.subscribe((params) => {
      this.queryParams = params;
      this.mode = _.get(this.queryParams, 'type');
    });
    this.navigationHelperService.setNavigationUrl();
    this.initializeFormFields();
    this.getDefaultTemplates();
    this.layoutConfiguration = this.layoutService.initlayoutConfig();
    this.redoLayout();
  }

  getDefaultTemplates() {
    const request = {
      'request': {
          'filters': {
              'certType': 'cert template layout',
              'channel': this.userService.channel,
              'mediaType': 'image'
          },
          'fields': ['identifier', 'name', 'code', 'certType', 'data', 'issuer', 'signatoryList', 'artifactUrl', 'primaryCategory', 'channel'],
          'limit': 100
      }
    };
    this.uploadCertificateService.getCertificates(request).subscribe(res => {
      this.defaultCertificates = _.get(res, 'result.content');
      this.selectedCertificate = _.clone(this.defaultCertificates[0]);
      this.getSVGTemplate();
    });
  }

  initializeFormFields() {
    this.createTemplateForm = new UntypedFormGroup({
      certificateTitle: new UntypedFormControl('', [Validators.required]),
      stateName: new UntypedFormControl('', [Validators.required]),
      authoritySignature_0: new UntypedFormControl('', [Validators.required]),
      authoritySignature_1: new UntypedFormControl(''),
      allowPermission: new UntypedFormControl('', [Validators.required])
    });
    // TODO: Move to a separate component this browse logic;
    this.createTemplateForm.valueChanges.subscribe(val => {
      this.validateForm();
    });
  }

  validateForm() {
    // TODO: Form validation need to improve
    const logo = _.get(this.images, 'LOGO1.url');
    const sign = _.get(this.images, 'SIGN1.url');
    if (this.createTemplateForm.status === 'VALID' && _.get(this.createTemplateForm, 'value.allowPermission')
      && logo && sign) {
      this.disableCreateTemplate = false;
    } else {
      this.disableCreateTemplate = true;
    }
  }


  getSVGTemplate() {
    this.uploadCertificateService.getSvg(this.selectedCertificate.artifactUrl).then(res => {
      const svgFile = res;
      this.logoHtml = this.sanitizeHTML(svgFile);
      this.refreshEditor.next({});
      this.previewCertificate();
    });
  }

  ngOnDestroy() {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }

  createCertTemplate() {
    this.validateForm();
    // TODO: form validation need to improve
    if (this.disableCreateTemplate) {
      this.createTemplateForm.controls.certificateTitle.markAsTouched();
      this.createTemplateForm.controls.stateName.markAsTouched();
      this.createTemplateForm.controls.authoritySignature_0.markAsTouched();
      this.createTemplateForm.controls.authoritySignature_1.markAsTouched();
      this.createTemplateForm.controls.allowPermission.markAsTouched();
    } else {
      this.previewCertificate();
      setTimeout(() => {
        const channel = this.userService.channel;
        const request = this.certConfigModalInstance.prepareCreateAssetRequest(_.get(this.createTemplateForm, 'value'), channel, this.selectedCertificate, this.images);
        this.disableCreateTemplate = true;
        this.uploadCertificateService.createCertTemplate(request).subscribe(response => {
          const assetId = _.get(response, 'result.identifier');
          this.uploadTemplate(this.finalSVGurl, assetId);
        }, error => {
          this.toasterService.error('Something went wrong, please try again later');
        });
      }, 1000);
    }
  }

  uploadTemplate(base64Url, identifier) {
    this.uploadCertificateService.storeAsset(base64Url, identifier).subscribe(response => {
      this.toasterService.success(_.get(this.resourceService, 'frmelmnts.cert.lbl.certAddSuccess'));
      const templateIdentifier = {'identifier': _.get(response , 'result.identifier')};
      this.uploadCertificateService.certificate.next(templateIdentifier);
      this.navigationHelperService.navigateToLastUrl();
    }, error => {
      this.toasterService.error('Something went wrong, please try again later');
      console.log('error', error);
    });
  }

  assetData(data) {
    if (data.key === this.optionSing) {
      this.createTemplateForm.get('authoritySignature_1').setValidators([Validators.required]);
      this.createTemplateForm.get('authoritySignature_1').updateValueAndValidity();
    }
    this.images[data.key] = data;
    this.validateForm();
  }

  close() {
    this.showSelectImageModal = false;
    this.showUploadUserModal = false;
  }

  removeImage(key) {
    if (key === 'SIGN2') {
      this.createTemplateForm.get('authoritySignature_1').clearValidators();
      this.createTemplateForm.get('authoritySignature_1').updateValueAndValidity();
    }
    this.images[key] = {};
    this.validateForm();
  }

  openSateLogos(type) {
    this.logoType = type;
    this.showSelectImageModal = true;
    this.browseImage.getAssetList();
  }

  openSignLogos(type) {
    this.logoType = type;
    this.showSelectImageModal = false;
    this.showUploadUserModal = true;
    // this.browseImage.getAssetList();
  }

  chooseCertificate(certificate) {
    this.logoHtml = null;
    this.selectedCertificate = _.clone(certificate);
    this.getSVGTemplate();
  }

  convertHtml(tag) {
    if (tag) {
      const html = tag.toString();
      return new DOMParser().parseFromString(html, 'text/html');
    }
  }

  previewCertificate() {
    this.svgData = this.convertHtml(this.logoHtml);
    const stateLogos = this.svgData.getElementsByClassName(this.classNames.STATE_LOGOS);
    const digitalSigns = this.classNames.SIGN_LOGO.map(id => this.svgData.getElementById(id));
    // this.updateTitles();
    this.updateStateLogos(stateLogos);
    this.updateSigns(digitalSigns);
  }

  previewUpdatedSVGCertificate() {
    this.svgData = this.convertHtml(this.sanitizeHTML(document.getElementById('templateSvg').innerHTML));
    this.certificateCreation(this.svgData.getElementsByTagName('svg')[0]);
  }

  updateTitles() {
    const certTitle = this.svgData.getElementsByClassName(this.classNames.CERT_TITLE);
    certTitle[0].innerHTML = this.createTemplateForm.controls.certificateTitle.value;
    const stateTitle = this.svgData.getElementsByClassName(this.classNames.STATE_TITLE);
    stateTitle[0].innerHTML = this.createTemplateForm.controls.stateName.value;
    this.classNames.DESIGNATIONS_NAMES.forEach((id, index) => {
      const designation_html = this.svgData.getElementById(id);
      if (designation_html) {
        const title = this.createTemplateForm.get(`authoritySignature_${index}`).value;
        designation_html.innerHTML = title;
      }
    });
  }

  updateStateLogos(stateLogos) {
    const logosArray = Object.values(this.images).filter(x => !_.isEmpty(x) && x['type'] === 'LOGO');
    this.editSVG(logosArray, stateLogos).then(res => {
      this.certificateCreation(this.svgData.getElementsByTagName('svg')[0]);
    });
  }

  updateSigns(stateLogos) {
    const logosArray = Object.values(this.images).filter(x => !_.isEmpty(x) && x['type'] === 'SIGN');
    this.editSVG(logosArray, stateLogos).then(res => {
      //this.certificateCreation(this.svgData.getElementsByTagName('svg')[0]);
    });
  }

  editSVG(logosArray, stateLogos) {
    return new Promise<void>(async (resolve, reject) => {
      for (let i = 0; i < logosArray.length; i++) {
        const logo = logosArray[i];
        if (logo) {
          const res = await this.toDataURL(logo);

          if (res && !_.isEmpty(stateLogos) && stateLogos[i]) {
            stateLogos[i].setAttribute('xlink:href', res['url']);
          }
          if (i === (logosArray.length - 1)) {
            resolve();
          }
        }
      }
    });
  }

  toDataURL(image) {
    return fetch(image.url, {
      method: 'GET',
      mode: 'cors',
      cache: 'no-cache',
      headers: {
        'Content-Type': 'application/json'
      }
    })
      .then(response => response.blob())
      .then(blob => new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve({ url: reader.result, type: image.type });
        reader.onerror = reject;
        reader.readAsDataURL(blob);
      }));
  }

urltoFile(url, filename, mimeType) {
  return (fetch(url)
      .then((res) => {
        return res.arrayBuffer();
      })
      .then((buf) => {
        return new File([buf], filename, {type: mimeType});
      })
  );
}

  certificateCreation(ev) {
   const dataURL  = this.getBase64Data(ev);
    this.selectedCertificate['artifactUrl'] = this.sanitizer.bypassSecurityTrustResourceUrl(dataURL);
    this.urltoFile(dataURL, `certificate_${dayjs().format('YYYY-MM-DD_HH_mm')}.svg`, 'image/svg+xml')
    .then((file) => {
      this.finalSVGurl = file;
    });
  }


  sanitizeHTML(html) {
    return this.sanitizer.bypassSecurityTrustHtml(html);
  }

  getImagePath() {
    if (this.selectedCertificate) {
      return this.selectedCertificate.artifactUrl;
    }
  }
  getBase64Data(ev) {
    const div = document.createElement('div');
    div.appendChild(ev.cloneNode(true));
    const b64 = 'data:image/svg+xml;base64,' + window.btoa(div.innerHTML);
    return b64;
  }

  back() {
    this.uploadCertificateService.certificate.next(null);
    this.navigationHelperService.navigateToLastUrl();
  }
  redoLayout() {
    if (this.layoutConfiguration != null) {
      this.FIRST_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(0, this.layoutConfiguration, COLUMN_TYPE.threeToNine);
      this.SECOND_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(1, this.layoutConfiguration, COLUMN_TYPE.threeToNine);
    } else {
      this.FIRST_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(0, null, COLUMN_TYPE.fullLayout);
      this.SECOND_PANEL_LAYOUT = this.layoutService.redoLayoutCSS(1, null, COLUMN_TYPE.fullLayout);
    }
  }

  elementClicked(e: any) {
    this.selectedSVGObject = {
      type: _.get(e, 'type'),
      value: _.get(e, 'element.textContent'),
      element: e.element
    };
    if (e.type === 'image') {
      this.logoType = {type: 'LOGO', index: 0,  key:'LOGO1'};
      this.browseImage.getAssetList();
    }
    
    this.showSVGInputModal = true;
  }
  updateSVGInputTag() {
    this.showSVGInputModal = false;
    this.edit.next({
      element: this.selectedSVGObject.element,
      type: 'text',
      value: this.selectedSVGObject.value
    });
    this.selectedSVGObject = {};
  }
  closeSVGInputModal() {
    this.showSVGInputModal = false;
  }

  svgAssetData(imageObj) {
    this.getBase64FromUrl(_.get(imageObj, 'url')).then((base64String: string) => {
      this.showSVGInputModal = false;
      this.edit.next({
        element: this.selectedSVGObject.element,
        type: 'image',
        value: base64String
      });
      this.selectedSVGObject = {};
    });
  }
  getBase64FromUrl = async (url) => {
    const data = await fetch(url);
    const blob = await data.blob();
    return new Promise((resolve) => {
      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = () => {
        const base64data = reader.result;
        resolve(base64data);
      }
    });
  }
  toggleSVGPreview() {
    this.previewButton = this.previewButton == 'show' ? 'hide' : 'show';
    this.togglePreview.next(this.previewButton);
  }

  saveUpdatedCertificate() {
    const certificateCodeName = _.get(this.queryParams, 'courseId') + '_' + _.get(this.queryParams, 'batchId').toString();
    this.svgData = null;
    this.save.next('');
    this.previewUpdatedSVGCertificate();
    setTimeout(() => {
      const channel = this.userService.channel;
      const request = this.certConfigModalInstance.prepareCreateAssetRequest(_.get(this.createTemplateForm, 'value'), channel, this.selectedCertificate, this.images);
      request.request.asset.code = certificateCodeName;
      request.request.asset.name = certificateCodeName;
      this.uploadCertificateService.createCertTemplate(request).subscribe(response => {
        const assetId = _.get(response, 'result.identifier');
        this.uploadTemplate(this.finalSVGurl, assetId);
      }, error => {
        this.toasterService.error('Something went wrong, please try again later');
      });
    }, 1000);
  }

  previewAndSave() {
    this.toggleSVGPreview();
    this.saveAndPreview = true;
    this.previewSvgData = this.sanitizeHTML(document.getElementById('templateSvg').innerHTML);
  }

  closeSaveAndPreview() {
    this.toggleSVGPreview();
    this.saveAndPreview = false;
    this.userConsent = false;
  }
}
<!-- @since - release-4.7.0 -->
<!-- SVG Editor for Certificate Creation -->
<!-- New Certificate layout -->

<div [ngClass]="layoutConfiguration ? 'sbt-inside-page-container py-16' : ''">

  <div class="sb-bg-color-white py-8 relative9 cc-player__content-header cc-player__border-fix">
    <div class="ui container">
      <div class="d-flex flex-ai-center flex-jc-space-between">
        <button (click)="back()" tabindex="0"
          class="sb-btn sb-btn-normal sb-btn-link sb-btn-link-primary sb-left-icon-btn mr-auto" id="goBack"
          type="button">
          <i class="icon-svg icon-svg--xxs icon-back mr-4">
            <svg class="icon icon-svg--primary">
              <use xlink:href="assets/images/sprite.svg#arrow-long-left"></use>
            </svg></i>
          {{resourceService?.frmelmnts?.btn?.back}}
        </button>
      </div>
    </div>
  </div>

  <div class="certificate-container relative9">
    <div class="ui container">
      <div class='sb-g mt-16'>
        <div class="sb-g-col-xs-12 sb-g-col-md-3 sb-g-col-lg-3 sb-g-col-xxxl-12">
          <div class="certificate-content">
            <label class="fmedium my-8">{{resourceService?.frmelmnts?.cert?.lbl?.layout}}</label>
            <div class="mt-16">
              <div *ngFor="let certificate of defaultCertificates" class="cert-img-sb-card"
                [ngClass]="selectedCertificate?.identifier === certificate?.identifier ? 'active' : ''">
                <div class="cert-img-sb-card__content d-flex flex-ai-center flex-jc-center" alt="certificate template">
                  <img (click)="chooseCertificate(certificate)" tabindex="0" [src]="certificate?.artifactUrl"
                    alt="certificate template" />
                </div>
              </div>
            </div>
          </div>
        </div>

        <div class="sb-g-col-xs-12 sb-g-col-md-9 sb-g-col-lg-9 sb-g-col-xxxl-12">
          <div>
            <div class="d-flex flex-ai-center">
              <i class="icon-svg icon-svg--md icon-back mr-16">
                <svg class="icon icon-svg--primary">
                  <use xlink:href="assets/images/sprite.svg#question_on_play"></use>
                </svg></i>
              <label class="preview-title mb-0 mr-auto">{{resourceService?.frmelmnts?.lbl?.editCertificateTitle}}</label>
              <button type="button" (click)="back()" tabindex="0" class="sb-btn sb-btn-normal sb-btn-outline-primary">{{resourceService?.frmelmnts?.btn?.cancel}}</button>
              <!-- <button type="button" (click)="saveUpdatedCertificate()" tabindex="0"
                class="sb-btn sb-btn-normal sb-btn-primary ml-16">{{resourceService?.frmelmnts?.cert?.btn?.saveAsTemplate}}
              </button>
              <button type="button" *ngIf="previewButton == 'show'" (click)="toggleSVGPreview()" tabindex="0"
                class="sb-btn sb-btn-normal sb-btn-primary ml-16">Preview
              </button>
              <button type="button" *ngIf="previewButton == 'hide'" (click)="toggleSVGPreview()" tabindex="0"
                class="sb-btn sb-btn-normal sb-btn-primary ml-16">Edit
              </button> -->
              <button type="button" (click)="previewAndSave()" tabindex="0"
                class="sb-btn sb-btn-normal sb-btn-primary ml-16">{{resourceService?.frmelmnts?.lbl?.saveAndPreview}}</button>
            </div>

            <div class="cert-select-card my-16">
              <div class="d-flex flex-ai-center flex-dc cert-select-card__content">
                <div class="d-flex flex-ai-center flex-jc-center cert-select-card__content__description">
                  <div class="svgContainer">
                    <!-- <svg-editor [svgContent]="logoHtml" [save]="save" [togglePreview]="togglePreview"
                     [edit]="edit" (elementClicked)="elementClicked($event)" [refreshEditor]="refreshEditor"></svg-editor> -->
                  </div>
                </div>
              </div>
            </div>

          </div>
        </div>
      </div>
    </div>
  </div>
</div>

<app-modal-wrapper *ngIf="showSVGInputModal && showPreviewButton && selectedSVGObject?.type === 'text'" [config]="{disableClose: true, size: 'small'}" (dismiss)="closeSVGInputModal()">
  <ng-template sbModalContent>
      <div class="sb-modal sb-error">
          <div class="transition ui dimmer page modals active visible">
              <div class="ui modal transition active visible small">
                  <button aria-label="close dialog" mat-dialog-close class="mat-close-btn">
                      <span>&times;</span>
                  </button>
                  <!--Header-->
                  <div class="sb-modal-header">
                      {{resourceService?.frmelmnts?.lbl?.updateDetails}}
                  </div>
                  <!--/Header-->
                  <!--Content-->
                  <div class="sb-modal-content">
                    <div class="image-tabs px-8">
                
                      <!-- Text update -->
                      <section *ngIf="selectedSVGObject?.type === 'text'" id="content1">
                        <div class="twelve wide column">
                          <div class="sb-search-box m-0">
                            <div class="input-div relative">
                              <input autofocus class="sb-search-input" [(ngModel)]="selectedSVGObject.value" type="text" maxlength="80" />
                            </div>
                          </div>
                          <small _ngcontent-nit-c26="" class="pl-4 fsmall">
                            {{80 - selectedSVGObject.value.length}} / 80 {{resourceService?.frmelmnts?.lbl?.characterleft}}
                          </small>
                        </div>
                      </section>
                    </div>
                  </div>
                  <!--/Content-->
                  <!--Actions-->
                  <div class="sb-modal-actions">
                    <button class="sb-btn sb-btn-normal sb-btn-primary" tabindex="0" (click)="updateSVGInputTag()">{{resourceService?.frmelmnts?.btn?.update}}</button>
                    <button class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0" (click)="closeSVGInputModal()">
                      {{resourceService.frmelmnts?.btn?.cancel}}
                    </button>
                  </div>
                  <!--/Actions-->
              </div>
          </div>
      </div>
  </ng-template>
</app-modal-wrapper>
 <browse-image-popup [enableUploadSignature]="true" (assetData)="svgAssetData($event)" (close)="closeSVGInputModal()" [showUploadUserModal]="disableSVGImageModal" [showSelectImageModal]="showSVGInputModal && showPreviewButton && selectedSVGObject?.type === 'image'" [logoType]="logoType" ></browse-image-popup>
 

 <app-modal-wrapper [config]="{disableClose: true, size: 'large'}" (dismiss)="closeSaveAndPreview()" *ngIf="saveAndPreview">
  <ng-template sbModalContent>
    <div class="sb-modal sb-error">
        <div class="transition ui dimmer page modals active visible">
            <div class="ui modal sb-bg-color-white  transition active visible large">
                <button aria-label="close dialog" mat-dialog-close class="mat-close-btn">
                    <span>&times;</span>
                </button>
                <!--Header-->
                <div class="sb-modal-header sb-bg-color-white ">
                    {{resourceService?.frmelmnts?.lbl?.certPreview}}
                </div>
                <!--/Header-->
                <!--Content-->
                <div class="sb-modal-content sb-bg-color-white ">
                  <div class="image-tabs px-8">
                    <div [innerHTML]="previewSvgData"></div>
                  </div>
                </div>
                <!--/Content-->
                <!--Actions-->
                <div class="sb-modal-actions sb-bg-color-white ">
                  <div class='ui stackable d-flex flex-jc-space-between mt-0'>
                    <!-- <div class="twelve wide column"> -->
                      <div class="">
                        <div class="sb-checkbox sb-checkbox-secondary pt-24">
                          <input [checked]="userConsent" (change)="userConsent = !userConsent" value="true" type="checkbox" id="check2" name="selected">
                          <label for="check2" class="text-left fsmall">{{resourceService?.frmelmnts?.cert?.intxt?.confrmtion}}</label>
                        </div>
                      </div>
                      <div class="">
                        <button [disabled]="!userConsent" [ngClass]="{'sb-btn-disabled': !userConsent }" class="sb-btn sb-btn-normal sb-btn-primary" tabindex="0" (click)="saveUpdatedCertificate()">{{resourceService?.frmelmnts?.cert?.btn?.saveAsTemplate}}</button>
                      </div>
                    <!-- </div> -->
                  </div>
                 
                </div>
                <!--/Actions-->
            </div>
        </div>
    </div>
</ng-template>
 </app-modal-wrapper>

./svg-editor.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;

.certificate-content {
  height: 100%;
}

.cert-img-sb-card {
  width: 100%;
  height: auto;
  background-color: var(--white);
  border: calculateRem(2px) solid var(--gray-200);
  border-radius: .25rem;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  margin-bottom: calculateRem(16px);
  transition: all 0.3s ease-out;

  &:last-child {
    margin-bottom: 0;
  }

  &.active {
    .selected-mark {
      position: absolute;
      right: calculateRem(4px);
      top: 0;
      display: block;
    }
  }

  &.active,
  &:hover {
    border: calculateRem(2px) solid var(--primary-color);
  }

  &__content {
    padding: 0.5rem;
    overflow: hidden;
    position: relative;

    .selected-mark {
      display: none;
    }

    img {
      width: 100%;
      height: 100%;
    }
  }
}

.select-template-content {
  background: var(--white);
  height: 100%;
}

.cert-select-card {
  width: 100%;
  border-radius: 0.5rem;
  cursor: pointer;

  &__content {
    height: 100%;
    background: var(--white);

    &__description {
      width: 100%;
      text-align: center;
      border-style: dashed;
      border-color: var(--gray-100);

      .title {
        font-size: 1.125rem;
        color: var(--gray-100);
      }
    }
  }
}

.cert-select-image {
  width: 100%;
  height: 100%;

  img {
    width: 100%;
    height: 100%;
    border: calculateRem(1px) solid;
    margin-bottom: calculateRem(16px);
  }
}

.cert-view-image {
  width: 100%;
  height: 100%;

  img {
    width: 100%;
    height: 100%;
    border: calculateRem(1px) solid;
  }
}

.asterik {
  color: var(--red-400);
}

.preview-title {
  font-size: calculateRem(20px);
}

.state-labels {
  color: var(--gray-800);
}

.list-border {
  border-bottom: calculateRem(1px) solid var(--gray-200);
}

.sb-browse-btn {
  position: relative;
  overflow: hidden;
  margin-top: calculateRem(3px);
  cursor: pointer;
  border-radius: calculateRem(24px);
  border: calculateRem(2px) solid var(--primary-300);
  color: var(--primary-300);
  font-weight: bold;
  background: var(--primary-100);
}
.svgContainer {
  width: 100%;
  height: 100%;
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""