Add new text-as-svg pipe. Add gradient fucntionallity on icons

This commit is contained in:
Konstantinos Triantafyllou 2022-02-15 16:25:46 +02:00
parent f0086e4797
commit 4e49e7f489
6 changed files with 102 additions and 29 deletions

View File

@ -308,7 +308,7 @@
[results]="results"
[status]="searchUtils.status"
[type]="entityType"
[showType]="false"
[showType]="entityType == 'stakeholder'"
[showLoading]="true" [properties]=properties>
</portal-search-result>
</div>

View File

@ -1,7 +1,10 @@
<ul class="uk-list uk-list-large" [class]="'uk-list uk-margin ' + custom_class" uk-height-match="target: .uk-card-default; row: false">
<ul class="uk-list uk-list-large" [class]="'uk-list uk-margin ' + custom_class"
uk-height-match="target: .uk-card-default; row: false">
<errorMessages [status]="[status]" [type]="'results'"></errorMessages>
<li *ngFor="let result of results" class="uk-animation-fade">
<div class="uk-card uk-card-default uk-card-body uk-card-hover uk-position-relative uk-flex uk-flex-column uk-flex-center" [class.uk-disabled]="!hasPermission(result)">
<div
class="uk-card uk-card-default uk-card-body uk-card-hover uk-position-relative uk-flex uk-flex-column uk-flex-center"
[class.uk-disabled]="!hasPermission(result)">
<div>
<div *ngIf="type === 'community' && result.isSubscribed"
class="uk-alert-primary uk-padding-small uk-position-top-left uk-text-center">
@ -24,7 +27,8 @@
</div>
</div>
<div class="uk-grid uk-flex uk-flex-middle" uk-grid>
<a *ngIf="directLink && hasPermission(result)" [href]="(type === 'community')?getCommunityPageUrl(result):getStakeholderPageUrl(result)"
<a *ngIf="directLink && hasPermission(result)"
[href]="(type === 'community')?getCommunityPageUrl(result):getStakeholderPageUrl(result)"
target="_blank" class="uk-width-1-5@s">
<ng-container *ngTemplateOutlet="resultPreview; context: {result: result}"></ng-container>
</a>
@ -38,21 +42,25 @@
</div>
<div class="uk-width-expand">
<div *ngIf="type === 'community'" [title]="result.shortTitle" class="uk-margin-bottom">
<a *ngIf="directLink && hasPermission(result)" [href]="getCommunityPageUrl(result)" class="uk-h5 uk-link-heading" target="_blank">
<a *ngIf="directLink && hasPermission(result)" [href]="getCommunityPageUrl(result)"
class="uk-h5 uk-link-heading" target="_blank">
{{(result.title) ? result.title : result.shortTitle}}
</a>
<a *ngIf="!directLink && hasPermission(result)" (click)="confirmModalOpen(result)" class="uk-h5 uk-link-heading">
<a *ngIf="!directLink && hasPermission(result)" (click)="confirmModalOpen(result)"
class="uk-h5 uk-link-heading">
{{(result.title) ? result.title : result.shortTitle}}
</a>
<h5 *ngIf="!hasPermission(result)">
<h5 *ngIf="!hasPermission(result)">
{{(result.title) ? result.title : result.shortTitle}}
</h5>
</div>
<div *ngIf="type === 'stakeholder'" [title]="result.index_shortName" class="uk-margin-bottom">
<a *ngIf="directLink && hasPermission(result)" [href]="getStakeholderPageUrl(result)" class="uk-h5 uk-link-heading" target="_blank">
<a *ngIf="directLink && hasPermission(result)" [href]="getStakeholderPageUrl(result)"
class="uk-h5 uk-link-heading" target="_blank">
{{(result.name) ? result.name : result.index_shortName}}
</a>
<a *ngIf="!directLink && hasPermission(result)" (click)="confirmModalOpen(result)" class="uk-h5 uk-link-heading">
<a *ngIf="!directLink && hasPermission(result)" (click)="confirmModalOpen(result)"
class="uk-h5 uk-link-heading">
{{(result.name) ? result.name : result.index_shortName}}
</a>
<h5 *ngIf="!hasPermission(result)">
@ -68,17 +76,12 @@
<div *ngIf="result.date || result.creationDate" class="uk-flex uk-flex-middle uk-margin-small-bottom">
<span class="uk-text-muted">Creation Date: </span>
<span class="uk-margin-small-left" *ngIf="result.date">{{result.date | date:'dd-MM-yyyy'}}</span>
<span class="uk-margin-small-left" *ngIf="result.creationDate">{{result.creationDate | date:'dd-MM-yyyy'}}</span>
<span class="uk-margin-small-left"
*ngIf="result.creationDate">{{result.creationDate | date:'dd-MM-yyyy'}}</span>
</div>
<div class="uk-flex uk-flex-middle">
<span *ngIf="type === 'community' && showType && result.type">
<span class="uk-text-muted">Type:</span>
<span class="uk-margin-small-left uk-text-capitalize">{{mapType(result.type)}}</span>
</span>
<span *ngIf="type === 'stakeholder' && result.type">
<span class="uk-text-muted">Type:</span>
<span class="uk-margin-small-left uk-text-capitalize">{{mapType(result.type)}}</span>
</span>
<div *ngIf="showType && result.type" class="uk-flex uk-flex-middle">
<span class="uk-text-muted">Type:</span>
<span class="uk-margin-small-left uk-text-capitalize">{{mapType(result.type)}}</span>
</div>
</div>
</div>
@ -96,6 +99,7 @@
</modal-alert>
<ng-template #resultPreview let-result="result">
<div class="uk-flex uk-flex-center">
<img *ngIf="result.logoUrl" [src]="result | logoUrl" [alt]="((result.title)?result.title:result.shortTitle) + ' logo'" loading="lazy">
<img *ngIf="result.logoUrl" [src]="result | logoUrl"
[alt]="((result.title)?result.title:result.shortTitle) + ' logo'" loading="lazy">
</div>
</ng-template>

View File

@ -9,7 +9,7 @@ import {ManageModule} from "../../utils/manage/manage.module";
import {IconsModule} from "../../utils/icons/icons.module";
import {UrlPrefixModule} from "../../utils/pipes/url-prefix.module";
import {IconsService} from "../../utils/icons/icons.service";
import {lock} from "../../utils/icons/icons";
import {group, lock} from "../../utils/icons/icons";
import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
@NgModule({
@ -29,6 +29,6 @@ import {LogoUrlPipeModule} from "../../utils/pipes/logoUrlPipe.module";
})
export class PortalSearchResultModule {
constructor(private iconsService: IconsService) {
this.iconsService.registerIcons([lock])
this.iconsService.registerIcons([group, lock])
}
}

View File

@ -1,6 +1,11 @@
import {AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, OnInit, ViewChild} from "@angular/core";
import {IconsService} from "./icons.service";
export interface StopRule {
class: string,
offset: number
}
/**
* By default this component uses Material Icons Library to render an icon with
* a specific @name. For custom icons you should:
@ -21,7 +26,7 @@ import {IconsService} from "./icons.service";
@Component({
selector: 'icon',
template: `
<span #icon *ngIf="svg" class="uk-icon" [class.uk-flex]="flex" [ngClass]="customClass" [ngStyle]="style" [innerHTML]="svg | safeHtml"></span>
<span #icon *ngIf="svg" class="uk-icon" [class.uk-preserve]="gradient" [class.uk-flex]="flex" [ngClass]="customClass" [ngStyle]="style" [innerHTML]="svg | safeHtml"></span>
<span [class.uk-flex]="flex" [ngClass]="customClass" [class.uk-display-inline-block]="!flex">
<span *ngIf="!svg && iconName" class="material-icons" [ngClass]="type" [ngStyle]="style">{{iconName}}</span>
</span>
@ -78,10 +83,22 @@ export class IconsComponent implements AfterViewInit {
this.svg = this.iconsService.getIcon(iconName);
}
/**
*
* Set visually hidden name for accessibility
* */
@Input()
public visuallyHidden: string = null;
/**
* Gradient rules
* Available only for SVG!
*
* Set your css rules for stop-colors
* */
@Input()
public gradient: string = null;
@Input()
public degrees: number = 0;
@Input()
public stopRules: StopRule[]= [{class: 'start', offset: 0}, {class: 'end', offset: 100}];
@ViewChild("icon")
public icon: ElementRef;
@ -90,13 +107,17 @@ export class IconsComponent implements AfterViewInit {
ngAfterViewInit() {
if(this.svg) {
let svg = this.icon.nativeElement.getElementsByTagName('svg').item(0);
let svg: Element = this.icon.nativeElement.getElementsByTagName('svg').item(0);
svg.setAttribute("width", (this.ratio*IconsComponent.DEFAULT_ICON_SIZE).toString());
svg.setAttribute("height", (this.ratio*IconsComponent.DEFAULT_ICON_SIZE).toString());
this.style = {
fill: this.fill,
stroke: this.stroke
};
if(this.gradient) {
this.addGradient(svg);
} else {
this.style = {
fill: this.fill,
stroke: this.stroke
};
}
} else {
this.style = {
"font-size.px": this.ratio*IconsComponent.DEFAULT_ICON_SIZE
@ -104,4 +125,33 @@ export class IconsComponent implements AfterViewInit {
}
this.cdr.detectChanges();
}
addGradient(svg: Element) {
if(svg.children.length > 0) {
let gradientDefinition = document.createElementNS('http://www.w3.org/2000/svg', 'linearGradient');
gradientDefinition.setAttribute('id', this.gradient);
if(this.degrees !== 0) {
let angle = (this.degrees) * (Math.PI / 180);
gradientDefinition.setAttribute('x1', Math.round(50 + Math.sin(angle) * 50) + '%');
gradientDefinition.setAttribute('y1', Math.round(50 + Math.cos(angle) * 50) + '%');
gradientDefinition.setAttribute('x2', Math.round(50 + Math.sin(angle + Math.PI) * 50) + '%');
gradientDefinition.setAttribute('y2', Math.round(50 + Math.cos(angle + Math.PI) * 50) + '%');
}
for(let rule of this.stopRules) {
let item = document.createElementNS('http://www.w3.org/2000/svg','stop');
item.setAttribute('class', rule.class);
item.setAttribute('offset', rule.offset + '%');
gradientDefinition.appendChild(item);
}
let defs = document.createElementNS('http://www.w3.org/2000/svg','defs');
defs.appendChild(gradientDefinition);
for(let i = 0; i < svg.children.length; i++) {
let item = svg.children.item(i);
if(!item.hasAttribute('fill')) {
item.setAttribute('fill', "url('#" + this.gradient + "')");
}
}
svg.insertBefore(defs, svg.childNodes[0]);
}
}
}

View File

@ -0,0 +1,8 @@
import {NgModule} from "@angular/core";
import {TextAsSvgPipe} from "./text-as-svg.pipe";
@NgModule({
declarations: [TextAsSvgPipe],
exports: [TextAsSvgPipe]
})
export class TextAsSvgModule {}

View File

@ -0,0 +1,11 @@
import {Pipe, PipeTransform} from "@angular/core";
import {DomSanitizer, SafeUrl} from "@angular/platform-browser";
import {StringUtils} from "../string-utils.class";
@Pipe({name: 'textAsSvg'})
export class TextAsSvgPipe implements PipeTransform {
transform(value: string): string {
return '<svg height="20" viewBox="0 0 ' + value.length*20 + ' 20" width="80" xmlns="http://www.w3.org/2000/svg"><text x="50%" y="85%" text-anchor="middle" dy=".4m" class="uk-text-bold" font-size="20">' + value + '</text></svg>';
}
}