Deleted shared/utils folder - openaire-library submodule is added instead
This commit is contained in:
parent
e8db9428bf
commit
a8937de064
|
@ -1 +1 @@
|
|||
Subproject commit 27f644aad1f4568a03bafbbd3d1640568a725957
|
||||
Subproject commit 6ecde003afe2cc7f4917b1d0f616d8c4b6355346
|
|
@ -1,24 +0,0 @@
|
|||
import {Component, Input} from "@angular/core";
|
||||
|
||||
export interface Breadcrumb {
|
||||
name: string;
|
||||
route?: string;
|
||||
keepFormat?: boolean
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'breadcrumbs',
|
||||
template: `
|
||||
<ul class="uk-breadcrumb uk-margin-remove-bottom" [ngClass]="addClass" [class.uk-light]="light">
|
||||
<li *ngFor="let breadcrumb of breadcrumbs">
|
||||
<a [class.uk-text-capitalize]="!breadcrumb.keepFormat" *ngIf="breadcrumb.route" [routerLink]="breadcrumb.route">{{breadcrumb.name}}</a>
|
||||
<span [class.uk-text-capitalize]="!breadcrumb.keepFormat" *ngIf="!breadcrumb.route">{{breadcrumb.name}}</span>
|
||||
</li>
|
||||
</ul>`
|
||||
})
|
||||
export class BreadcrumbsComponent {
|
||||
|
||||
@Input() public light: boolean = false;
|
||||
@Input() public breadcrumbs: Breadcrumb[] = [];
|
||||
@Input() public addClass = "";
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {BreadcrumbsComponent} from "./breadcrumbs.component";
|
||||
import {RouterModule} from "@angular/router";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, RouterModule],
|
||||
declarations: [BreadcrumbsComponent],
|
||||
exports: [BreadcrumbsComponent]
|
||||
})
|
||||
export class BreadcrumbsModule {}
|
|
@ -1,33 +0,0 @@
|
|||
import {Directive, ElementRef, EventEmitter, HostListener, Output} from '@angular/core';
|
||||
|
||||
export interface ClickEvent {
|
||||
event: any,
|
||||
clicked: boolean;
|
||||
}
|
||||
|
||||
@Directive({
|
||||
selector: '[click-outside-or-esc]'
|
||||
})
|
||||
export class ClickOutsideOrEsc {
|
||||
@Output('clickOutside') clickOutside: EventEmitter<ClickEvent> = new EventEmitter<ClickEvent>();
|
||||
|
||||
constructor(private elementRef: ElementRef) {}
|
||||
|
||||
@HostListener('document:click', ['$event'])
|
||||
click(event) {
|
||||
if(event.isTrusted) {
|
||||
this.clickOutside.emit({
|
||||
event: event,
|
||||
clicked: !(this.elementRef && this.elementRef.nativeElement.contains(event.target))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.escape', ['$event'])
|
||||
esc(event: KeyboardEvent) {
|
||||
this.clickOutside.emit({
|
||||
event: event,
|
||||
clicked: true
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {ClickOutsideOrEsc} from "./click-outside-or-esc.directive";
|
||||
import {LongClick} from "./long-click.directive";
|
||||
|
||||
@NgModule({
|
||||
imports: [],
|
||||
declarations: [
|
||||
ClickOutsideOrEsc, LongClick
|
||||
],
|
||||
exports: [
|
||||
ClickOutsideOrEsc, LongClick
|
||||
]
|
||||
})
|
||||
export class ClickModule {}
|
|
@ -1,72 +0,0 @@
|
|||
import {Directive, EventEmitter, HostListener, Input, Output} from '@angular/core';
|
||||
|
||||
@Directive({
|
||||
selector: '[long-click]'
|
||||
})
|
||||
|
||||
export class LongClick {
|
||||
|
||||
@Input() duration: number = 500;
|
||||
|
||||
@Output() onLongPress: EventEmitter<any> = new EventEmitter();
|
||||
@Output() onLongPressing: EventEmitter<any> = new EventEmitter();
|
||||
@Output() onLongPressEnd: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
private pressing: boolean;
|
||||
private longPressing: boolean;
|
||||
private timeout: any;
|
||||
private mouseX: number = 0;
|
||||
private mouseY: number = 0;
|
||||
|
||||
@HostListener('mousedown', ['$event'])
|
||||
onMouseDown(event) {
|
||||
// don't do right/middle clicks
|
||||
if (event.which !== 1) return;
|
||||
|
||||
this.mouseX = event.clientX;
|
||||
this.mouseY = event.clientY;
|
||||
|
||||
this.pressing = true;
|
||||
this.longPressing = false;
|
||||
|
||||
this.timeout = setTimeout(() => {
|
||||
this.longPressing = true;
|
||||
this.onLongPress.emit(event);
|
||||
this.loop(event);
|
||||
}, this.duration);
|
||||
|
||||
this.loop(event);
|
||||
}
|
||||
|
||||
@HostListener('mousemove', ['$event'])
|
||||
onMouseMove(event) {
|
||||
if (this.pressing && !this.longPressing) {
|
||||
const xThres = (event.clientX - this.mouseX) > 10;
|
||||
const yThres = (event.clientY - this.mouseY) > 10;
|
||||
if (xThres || yThres) {
|
||||
this.endPress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loop(event) {
|
||||
if (this.longPressing) {
|
||||
this.timeout = setTimeout(() => {
|
||||
this.onLongPressing.emit(event);
|
||||
this.loop(event);
|
||||
}, 50);
|
||||
}
|
||||
}
|
||||
|
||||
endPress() {
|
||||
clearTimeout(this.timeout);
|
||||
this.longPressing = false;
|
||||
this.pressing = false;
|
||||
this.onLongPressEnd.emit(true);
|
||||
}
|
||||
|
||||
@HostListener('mouseup')
|
||||
onMouseUp() {
|
||||
this.endPress();
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
import {Component} from "@angular/core";
|
||||
|
||||
@Component({
|
||||
selector: 'icons-preview',
|
||||
template: `
|
||||
<div class="uk-section uk-container uk-container-large" style="font-size: 14px;">
|
||||
<h4 class="uk-text-bold">Icons</h4>
|
||||
<div class="uk-grid uk-grid-small uk-child-width-1-6" uk-grid>
|
||||
<div class="uk-text-center">
|
||||
<icon name="book"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">book</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="database"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">database</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="cog"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">cog</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="earth"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">earth</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="incognito"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">incognito</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="restricted"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">restricted</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="graph"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">graph</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="orcid_add"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">orcid_add</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="orcid_bin"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">orcid_bin</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="link"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">link</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="quotes"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">quotes</div>
|
||||
</div>
|
||||
<div class="uk-text-center">
|
||||
<icon name="mining"></icon>
|
||||
<div class="uk-text-bold uk-margin-small-top">mining</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="uk-margin-medium-top">
|
||||
<h4 class="uk-text-bold">Usage</h4>
|
||||
<ul class="uk-list">
|
||||
<li>1. Import IconsModule</li>
|
||||
<li>2. Add this to your module with these icons you will need<br>
|
||||
<div class="uk-margin-top">
|
||||
<pre><code>constructor(private iconsService: IconsService) {{ "{" }}
|
||||
this.iconsService.registerIcons([edit]);
|
||||
{{ "}" }}</code></pre>
|
||||
</div>
|
||||
</li>
|
||||
<li>3. Use an icon with icon tag. Add parameter ratio to scale this icon. Default size 20x20 (ratio: 1)<br>
|
||||
<div class="uk-margin-top">
|
||||
<pre><code>{{'<'}}icon name="edit"{{'><'}}/icon{{'>'}}</code></pre>
|
||||
</div>
|
||||
</li>
|
||||
<li>4. Add a color class in parent of icon to give your icon a color.<br>
|
||||
<div class="uk-margin-top">
|
||||
<pre><code>{{'<'}}div class="uk-text-secondary"{{'>'}}
|
||||
{{'<'}}icon name="edit"{{'><'}}/icon{{'>'}}
|
||||
{{'<'}}/div{{'>'}}</code></pre>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="uk-margin-medium-top">
|
||||
<h4 class="uk-text-bold">Add a new icon</h4>
|
||||
<ul class="uk-list">
|
||||
<li>1. Go to <a href="https://material.io/resources/icons/?style=baseline">Material Icons</a></li>
|
||||
<li>2. Find your icon and download it as svg.</li>
|
||||
<li>3. Open svg file with an editor and change width and height to 20</li>
|
||||
<li>4. Create an entry on icons file with your new icon.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class IconsPreviewComponent {
|
||||
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {RouterModule} from "@angular/router";
|
||||
import {IconsPreviewComponent} from "./icons-preview.component";
|
||||
import {IconsService} from "../icons.service";
|
||||
import {IconsModule} from "../icons.module";
|
||||
import {
|
||||
book,
|
||||
cog,
|
||||
database,
|
||||
earth,
|
||||
filters,
|
||||
graph,
|
||||
incognito, link, mining,
|
||||
orcid_add,
|
||||
orcid_bin,
|
||||
quotes,
|
||||
restricted
|
||||
} from "../icons";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, RouterModule.forChild([
|
||||
{path: '', component: IconsPreviewComponent}
|
||||
]), IconsModule],
|
||||
declarations: [IconsPreviewComponent],
|
||||
exports: [IconsPreviewComponent]
|
||||
})
|
||||
export class IconsPreviewModule {
|
||||
constructor(private iconsService: IconsService) {
|
||||
this.iconsService.registerIcons([book, database, cog, earth, incognito, restricted, graph, filters, orcid_add, orcid_bin, link, quotes, mining])
|
||||
}
|
||||
}
|
|
@ -1,192 +0,0 @@
|
|||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
Input,
|
||||
OnChanges,
|
||||
SimpleChanges,
|
||||
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:
|
||||
*
|
||||
* - Add your icon in icons.ts and register it to Icon registry, by adding this to your component Module.
|
||||
*
|
||||
* e.g export class ExampleModule {
|
||||
* constructor(private iconsService: IconsService) {
|
||||
* this.iconsService.registerIcons([arrow_right])
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* If the name of your icon is the same with a Material Icon name, yours will be used instead of the default.
|
||||
*
|
||||
* - Custom SVG Icon. Define a variable in your component with an SVG and give it as Input @svg.
|
||||
*
|
||||
* In case of SVGs, there is an opportunity to add gradient color by define at least a start and end stop-color rules
|
||||
* and an id to support them. This option is enabled by giving id as input in @gradient (Optional @degrees for gradient direction)
|
||||
*
|
||||
* e.g #gradient .start {
|
||||
* stop-color: red;
|
||||
* }
|
||||
*
|
||||
* e.g #gradient .end {
|
||||
* stop-color: orange;
|
||||
* }
|
||||
*
|
||||
* */
|
||||
@Component({
|
||||
selector: 'icon',
|
||||
template: `
|
||||
<span #icon *ngIf="svg" class="uk-icon" [class.uk-preserve]="gradient" [class.uk-flex]="flex" [ngClass]="customClass" [ngStyle]="style" [innerHTML]="svg | safeHtml"></span>
|
||||
<span *ngIf="!svg && iconName" [class.uk-flex]="flex" [ngClass]="customClass" [class.uk-display-inline-block]="!flex">
|
||||
<span class="material-icons" [ngClass]="type" [ngStyle]="style">{{iconName}}</span>
|
||||
</span>
|
||||
<span *ngIf="visuallyHidden" class="visually-hidden">{{visuallyHidden}}</span>
|
||||
`
|
||||
})
|
||||
export class IconsComponent implements AfterViewInit, OnChanges {
|
||||
private static DEFAULT_ICON_SIZE = 20;
|
||||
public iconName: string;
|
||||
public style;
|
||||
/**
|
||||
* Custom icon as SVG
|
||||
*/
|
||||
@Input()
|
||||
public svg;
|
||||
@Input()
|
||||
public defaultSize = false;
|
||||
/**
|
||||
* True if this icon should have display flex (Optional, Default: false)
|
||||
*
|
||||
* */
|
||||
@Input()
|
||||
public flex = false;
|
||||
/**
|
||||
*
|
||||
* Add custom class(es)(Optional)
|
||||
* */
|
||||
@Input()
|
||||
public customClass = '';
|
||||
/**
|
||||
* Color of svg (Optional)
|
||||
* */
|
||||
@Input()
|
||||
public fill;
|
||||
/**
|
||||
* Color of svg stroke (Optional)
|
||||
* */
|
||||
@Input()
|
||||
public stroke;
|
||||
/**
|
||||
* Size of icon (Default: 1)
|
||||
*
|
||||
* Disabled if defaultSize = true
|
||||
* */
|
||||
@Input()
|
||||
public ratio = 1;
|
||||
/**
|
||||
* In case of Material icon only. Type of icon (Optional)
|
||||
* */
|
||||
@Input()
|
||||
public type: "outlined" | "round" | "sharp" | "two-tone" | null = null;
|
||||
/**
|
||||
* Name of icon in registry (Required)
|
||||
* */
|
||||
@Input()
|
||||
set name(iconName: string) {
|
||||
this.iconName = iconName;
|
||||
this.svg = this.iconsService.getIcon(iconName);
|
||||
}
|
||||
/**
|
||||
* Set visually hidden name for accessibility
|
||||
* */
|
||||
@Input()
|
||||
public visuallyHidden: string = null;
|
||||
/**
|
||||
* Gradient rules
|
||||
* Available only for SVG!
|
||||
*
|
||||
* Define 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;
|
||||
|
||||
constructor(private iconsService: IconsService,
|
||||
private cdr: ChangeDetectorRef) {}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.initIcon();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
this.initIcon();
|
||||
}
|
||||
|
||||
initIcon() {
|
||||
if(this.svg && this.icon) {
|
||||
this.cdr.detectChanges();
|
||||
let svg: Element = this.icon.nativeElement.getElementsByTagName('svg').item(0);
|
||||
if(!this.defaultSize && svg) {
|
||||
svg.setAttribute("width", (this.ratio * IconsComponent.DEFAULT_ICON_SIZE).toString());
|
||||
svg.setAttribute("height", (this.ratio * IconsComponent.DEFAULT_ICON_SIZE).toString());
|
||||
}
|
||||
if(this.gradient && svg) {
|
||||
this.addGradient(svg);
|
||||
} else {
|
||||
this.style = {
|
||||
fill: this.fill,
|
||||
stroke: this.stroke
|
||||
};
|
||||
}
|
||||
} else {
|
||||
this.style = {
|
||||
"font-size.px": this.ratio*IconsComponent.DEFAULT_ICON_SIZE
|
||||
};
|
||||
}
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
||||
addGradient(svg: Element) {
|
||||
if(svg.children.length > 0 && typeof document !== "undefined") {
|
||||
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 + Math.PI) * 50) + '%');
|
||||
gradientDefinition.setAttribute('y1', Math.round(50 + Math.cos(angle + Math.PI) * 50) + '%');
|
||||
gradientDefinition.setAttribute('x2', Math.round(50 + Math.sin(angle) * 50) + '%');
|
||||
gradientDefinition.setAttribute('y2', Math.round(50 + Math.cos(angle) * 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]);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {IconsComponent} from "./icons.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule],
|
||||
declarations: [IconsComponent],
|
||||
exports: [IconsComponent]
|
||||
})
|
||||
export class IconsModule {}
|
|
@ -1,18 +0,0 @@
|
|||
import {Injectable} from "@angular/core";
|
||||
import {Icon} from "./icons";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class IconsService {
|
||||
|
||||
private registry = new Map<string, string>();
|
||||
|
||||
public registerIcons(icons: any[]): void {
|
||||
icons.forEach((icon: Icon) => this.registry.set(icon.name, icon.data));
|
||||
}
|
||||
|
||||
public getIcon(iconName: string): string | undefined {
|
||||
return this.registry.get(iconName);
|
||||
}
|
||||
}
|
|
@ -1,226 +0,0 @@
|
|||
export interface Icon {
|
||||
name: string,
|
||||
data: string
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const arrow_left: Icon = {
|
||||
name: 'arrow_left',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M20 11H6.83l2.88-2.88c.39-.39.39-1.02 0-1.41-.39-.39-1.02-.39-1.41 0L3.71 11.3c-.39.39-.39 1.02 0 1.41L8.3 17.3c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L6.83 13H20c.55 0 1-.45 1-1s-.45-1-1-1z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const arrow_right: Icon = {
|
||||
name: 'arrow_right',
|
||||
data: '<svg height="20" viewBox="0 0 16 16" width="20" xmlns="http://www.w3.org/2000/svg"><path d="M12.578,4.244,5.667,11.155V8.167A.833.833,0,1,0,4,8.167v5A.832.832,0,0,0,4.833,14h5a.833.833,0,0,0,0-1.667H6.845l6.911-6.911a.833.833,0,1,0-1.178-1.178h0Z" transform="translate(7.071 19.799) rotate(-135)"></path></svg>'
|
||||
};
|
||||
|
||||
/** @deprecated */
|
||||
export const arrow_up: Icon = {
|
||||
name: 'arrow_up',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 17.155 17.155"><g transform="translate(0)"><path d="M10.405,11.834,2.022,3.451V7.076A1.011,1.011,0,0,1,0,7.076V1.011A1.009,1.009,0,0,1,1.011,0H7.076a1.011,1.011,0,1,1,0,2.022H3.451l8.383,8.383a1.011,1.011,0,1,1-1.429,1.429h0Z" transform="translate(8.578 0) rotate(45)"/></g></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const arrow_down: Icon = {
|
||||
name: 'arrow_down',
|
||||
data: '<svg height="20" viewBox="0 0 17.155 17.155" width="20" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-1221 -675)"><path d="M14.405,4.3,6.022,12.68V9.055A1.011,1.011,0,0,0,4,9.055V15.12a1.009,1.009,0,0,0,1.011,1.01h6.065a1.011,1.011,0,1,0,0-2.022H7.451l8.383-8.383A1.011,1.011,0,0,0,14.405,4.3h0Z" transform="translate(1215.343 683.578) rotate(-45)"></path></g></svg>'
|
||||
}
|
||||
|
||||
export const book: Icon = {
|
||||
name: 'book',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 22.106 30"><path id="book" d="M26.9,9.405V25.749c0,.824-.713,1.218-1.579,1.832a1.034,1.034,0,0,1-1.579-.927V10.685a.877.877,0,0,0-.5-.845c-.379-.194-12.218-6.418-12.218-6.418A2.239,2.239,0,0,0,8.9,3.4,4.487,4.487,0,0,0,7.119,4.808l12.916,7.077a.917.917,0,0,1,.555.815V29.755a1.057,1.057,0,0,1-.582.924,1.209,1.209,0,0,1-1.136-.042c-.339-.207-12.274-7.526-13.063-8-.379-.227-.823-.693-.832-1.039L4.8,5.355a2.612,2.612,0,0,1,.456-1.629c1.1-1.711,4.94-3.658,6.884-2.65L26.348,8.268A1.151,1.151,0,0,1,26.9,9.405Z" transform="translate(-4.799 -0.8)"/></svg>'
|
||||
};
|
||||
|
||||
export const database: Icon = {
|
||||
name: 'database',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 23.864 30"><path id="database" d="M28.2,21.443c-1.437,2.324-6.026,4.025-11.465,4.025S6.7,23.767,5.266,21.443c-.3-.494-.466-.23-.466.012v3.412c0,3.307,5.342,6.733,11.932,6.733s11.932-3.426,11.932-6.731V21.457C28.664,21.213,28.5,20.949,28.2,21.443Zm.018-8.721c-1.415,2.054-6.02,3.562-11.483,3.562S6.661,14.776,5.246,12.722c-.292-.423-.446-.193-.446,0v4.017c0,3,5.342,5.435,11.932,5.435s11.932-2.434,11.932-5.435V12.719c0-.19-.157-.42-.449,0ZM16.732,1.6C10.142,1.6,4.8,3.611,4.8,6.088V8.236c0,2.627,5.342,4.758,11.932,4.758s11.932-2.131,11.932-4.758V6.088C28.664,3.611,23.322,1.6,16.732,1.6Z" transform="translate(-4.8 -1.6)"/></svg>'
|
||||
};
|
||||
|
||||
export const cog: Icon = {
|
||||
name: 'cog',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 30.001 30"><path id="cog" d="M29.67,17.558A5.108,5.108,0,0,1,32.557,13.2a15.981,15.981,0,0,0-1.235-2.985A4.827,4.827,0,0,1,26.48,8.634a4.665,4.665,0,0,1-1.22-4.841,15.611,15.611,0,0,0-2.985-1.234,5.655,5.655,0,0,1-4.717,2.884,5.658,5.658,0,0,1-4.719-2.884A15.571,15.571,0,0,0,9.855,3.793,4.661,4.661,0,0,1,8.634,8.634a4.824,4.824,0,0,1-4.841,1.577A15.756,15.756,0,0,0,2.559,13.2a5.106,5.106,0,0,1,2.884,4.362,5.661,5.661,0,0,1-2.884,4.719,15.89,15.89,0,0,0,1.234,2.985A4.667,4.667,0,0,1,8.634,26.48a4.669,4.669,0,0,1,1.221,4.841,15.779,15.779,0,0,0,2.985,1.238,5.647,5.647,0,0,1,4.719-2.887,5.658,5.658,0,0,1,4.719,2.887,16.052,16.052,0,0,0,2.985-1.238,4.667,4.667,0,0,1,1.22-4.841A4.84,4.84,0,0,1,31.325,24.9a15.741,15.741,0,0,0,1.235-2.985A5.106,5.106,0,0,1,29.67,17.558Zm-12.111,6.52a6.522,6.522,0,1,1,6.52-6.52A6.521,6.521,0,0,1,17.558,24.079Z" transform="translate(-2.559 -2.559)"/></svg>'
|
||||
};
|
||||
|
||||
export const earth: Icon = {
|
||||
name: 'earth',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 30 30"><path id="earth" d="M15,0A15,15,0,1,0,30,15,15,15,0,0,0,15,0Zm0,28.125a13.086,13.086,0,0,1-5.192-1.068l6.831-7.685a.935.935,0,0,0,.237-.622V15.938A.938.938,0,0,0,15.938,15c-3.31,0-6.8-3.442-6.837-3.475a.937.937,0,0,0-.663-.275H4.688a.938.938,0,0,0-.937.937v5.625a.936.936,0,0,0,.518.838L7.5,20.267v5.5A13.132,13.132,0,0,1,3.14,9.375H6.563A.935.935,0,0,0,7.226,9.1l3.75-3.75a.937.937,0,0,0,.275-.663V2.42a13.164,13.164,0,0,1,9.5.779c-.122.1-.24.21-.353.323a5.626,5.626,0,0,0,3.974,9.6c.093,0,.186,0,.278-.007A22.007,22.007,0,0,1,24.4,24.027a.878.878,0,0,0-.024.153A13.084,13.084,0,0,1,15,28.125Z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const edit: Icon = {
|
||||
name: 'edit',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M3 17.46v3.04c0 .28.22.5.5.5h3.04c.13 0 .26-.05.35-.15L17.81 9.94l-3.75-3.75L3.15 17.1c-.1.1-.15.22-.15.36zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated
|
||||
*
|
||||
* Use delete
|
||||
* */
|
||||
export const remove: Icon = {
|
||||
name: 'remove',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 9.91 11.01"><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M8.83,1.85V9.41A1.58,1.58,0,0,1,7.26,11H2.62a1.6,1.6,0,0,1-1.57-1.6V1.85H.28A.26.26,0,0,1,0,1.57.27.27,0,0,1,.28,1.3H2.59v-1A.26.26,0,0,1,2.87,0H7a.28.28,0,0,1,.27.28v1H9.63a.28.28,0,0,1,.28.27.3.3,0,0,1-.28.28Zm-7.23,0V9.41a1,1,0,0,0,1,1.05H7.26a1,1,0,0,0,1-1.05V1.85ZM6.76,1.3V.55H3.15V1.3Z"/><path class="cls-1" d="M3.06,3.73a.28.28,0,0,1,.28-.28.29.29,0,0,1,.27.28V8.58a.29.29,0,0,1-.27.28.28.28,0,0,1-.28-.28Z"/><path class="cls-1" d="M6.29,3.73a.28.28,0,0,1,.28-.28.29.29,0,0,1,.27.28V8.58a.29.29,0,0,1-.27.28.28.28,0,0,1-.28-.28Z"/><path class="cls-1" d="M4.66,3.73a.3.3,0,0,1,.28-.28.29.29,0,0,1,.28.28V8.58a.29.29,0,0,1-.28.28.3.3,0,0,1-.28-.28Z"/></g></g></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated
|
||||
* Use visibility
|
||||
* */
|
||||
export const preview: Icon = {
|
||||
name: 'preview',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const bullet: Icon = {
|
||||
name: 'bullet',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><circle cx="12" cy="12" r="10"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const remove_circle = {
|
||||
name: 'remove_circle',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="20" viewBox="0 0 24 24" width="20"><g><path d="M0,0h24v24H0V0z" fill="none"/></g><g><path d="M12,2C6.47,2,2,6.47,2,12c0,5.53,4.47,10,10,10s10-4.47,10-10C22,6.47,17.53,2,12,2z M16.29,14.89 c0.39,0.39,0.39,1.02,0,1.41c-0.39,0.39-1.02,0.39-1.41,0L12,13.41l-2.89,2.89c-0.39,0.39-1.02,0.39-1.41,0 c-0.39-0.39-0.39-1.02,0-1.41L10.59,12L7.71,9.11c-0.39-0.39-0.39-1.02,0-1.41c0.39-0.39,1.02-0.39,1.41,0L12,10.59l2.89-2.89 c0.39-0.39,1.02-0.39,1.41,0c0.39,0.39,0.39,1.02,0,1.41L13.41,12L16.29,14.89z"/></g></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const remove_circle_outline = {
|
||||
name: 'remove_circle_outline',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0z" fill="none" opacity=".87"/><path d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm3.59-13L12 10.59 8.41 7 7 8.41 10.59 12 7 15.59 8.41 17 12 13.41 15.59 17 17 15.59 13.41 12 17 8.41z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const person_add = {
|
||||
name: 'person_add',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><path d="M15 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-9-2V7H4v3H1v2h3v3h2v-3h3v-2H6zm9 4c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const cloud_upload = {
|
||||
name: 'cloud_upload',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM14 13v4h-4v-4H7l4.65-4.65c.2-.2.51-.2.71 0L17 13h-3z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const add = {
|
||||
name: 'add',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M18 13h-5v5c0 .55-.45 1-1 1s-1-.45-1-1v-5H6c-.55 0-1-.45-1-1s.45-1 1-1h5V6c0-.55.45-1 1-1s1 .45 1 1v5h5c.55 0 1 .45 1 1s-.45 1-1 1z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const group = {
|
||||
name: 'group',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5s-3 1.34-3 3 1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V18c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-1.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05.02.01.03.03.04.04 1.14.83 1.93 1.94 1.93 3.41V18c0 .35-.07.69-.18 1H22c.55 0 1-.45 1-1v-1.5c0-2.33-4.67-3.5-7-3.5z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const lock = {
|
||||
name: 'lock',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><g fill="none"><path d="M0 0h24v24H0V0z"/><path d="M0 0h24v24H0V0z" opacity=".87"/></g><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM9 8V6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const search = {
|
||||
name: 'search',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M15.5 14h-.79l-.28-.27c1.2-1.4 1.82-3.31 1.48-5.34-.47-2.78-2.79-5-5.59-5.34-4.23-.52-7.79 3.04-7.27 7.27.34 2.8 2.56 5.12 5.34 5.59 2.03.34 3.94-.28 5.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const refresh = {
|
||||
name: 'refresh',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const close = {
|
||||
name: 'close',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M18.3 5.71c-.39-.39-1.02-.39-1.41 0L12 10.59 7.11 5.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L10.59 12 5.7 16.89c-.39.39-.39 1.02 0 1.41.39.39 1.02.39 1.41 0L12 13.41l4.89 4.89c.39.39 1.02.39 1.41 0 .39-.39.39-1.02 0-1.41L13.41 12l4.89-4.89c.38-.38.38-1.02 0-1.4z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const done = {
|
||||
name: 'done',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const mail = {
|
||||
name: 'mail',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const photo = {
|
||||
name: 'photo',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0z" fill="none"/><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const check_circle_outlined = {
|
||||
name: 'check_circle_outlined',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20"><path d="M0 0h24v24H0V0zm0 0h24v24H0V0z" fill="none"/><path d="M16.59 7.58L10 14.17l-3.59-3.58L5 12l5 5 8-8zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const reset = {
|
||||
name: 'reset',
|
||||
data: '<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><polyline fill="#000" points="1 2 2 2 2 6 6 6 6 7 1 7 1 2"></polyline><path fill="none" stroke="#000" stroke-width="1.1" d="M2.1,6.548 C3.391,3.29 6.746,1 10.5,1 C15.5,1 19.5,5 19.5,10 C19.5,15 15.5,19 10.5,19 C5.5,19 1.5,15 1.5,10"></path></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const send = {
|
||||
name: 'send',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="20" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/></svg>'
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
export const print = {
|
||||
name: 'print',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" height="20" viewBox="0 0 24 24" width="240" fill="#000000"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 8H5c-1.66 0-3 1.34-3 3v6h4v4h12v-4h4v-6c0-1.66-1.34-3-3-3zm-3 11H8v-5h8v5zm3-7c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm-1-9H6v4h12V3z"/></svg>'
|
||||
}
|
||||
|
||||
export const incognito = {
|
||||
name: 'incognito',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24.51 19.525"><g id="Group_13376" data-name="Group 13376" transform="translate(-428.81 -3863.018)"><path id="Path_104500" data-name="Path 104500" d="M44.68,105.185H43.024a23.507,23.507,0,0,0-9.194-.158V106a3.909,3.909,0,0,1,1.264,1.668c.455,1.119.2,3.05,4.148,3.289s4-4.041,4.034-4.438.577-.372.577-.372.541-.021.579.372.09,4.673,4.034,4.438,3.693-2.17,4.146-3.289A3.9,3.9,0,0,1,53.879,106v-.969A23.686,23.686,0,0,0,44.68,105.185Z" transform="translate(397.218 3771.582)" fill="#2c2c2c"/><path id="Path_104501" data-name="Path 104501" d="M41.867,35.784H40.326s-1.95-6.217-2.207-6.735a2.8,2.8,0,0,0-2.591-2.061c-1.92-.266-2.138,1.225-3.544,1.268-1.406-.049-1.617-1.546-3.542-1.268a2.817,2.817,0,0,0-2.592,2.061c-.246.518-2.205,6.735-2.205,6.735H22.1a2.31,2.31,0,0,0-2.371,2.245H44.24A2.311,2.311,0,0,0,41.867,35.784Z" transform="translate(409.08 3836.064)" fill="#2c2c2c"/></g></svg>'
|
||||
}
|
||||
|
||||
export const restricted = {
|
||||
name: 'restricted',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><g id="noun-remove-file-3557544" transform="translate(-176.397 -106.4)"><path id="Path_104600" data-name="Path 104600" d="M181.881,274.166A5.485,5.485,0,1,0,178,272.559,5.484,5.484,0,0,0,181.881,274.166Zm-3.548-5.484a3.531,3.531,0,0,1,.452-1.729l4.839,4.839a3.548,3.548,0,0,1-5.29-3.11Zm7.1,0a3.527,3.527,0,0,1-.452,1.729l-4.839-4.839a3.548,3.548,0,0,1,5.29,3.11Z" transform="translate(0 -147.766)"/><path id="Path_104601" data-name="Path 104601" d="M245.859,106.4a2.258,2.258,0,0,0-2.258,2.258v4.516h1.936v-4.516a.323.323,0,0,1,.323-.323h8.064v3.871h3.871v11.935a.323.323,0,0,1-.323.323h-5.484V126.4h5.484a2.259,2.259,0,0,0,2.258-2.258v-13.3l-4.439-4.439Z" transform="translate(-63.333)"/></g></svg>'
|
||||
}
|
||||
|
||||
export const graph = {
|
||||
name: 'graph',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 21.744"><g transform="translate(0)"><g transform="translate(0 0)"><path d="M18.772,15.578a2.718,2.718,0,0,0-.427-.368,3.629,3.629,0,0,0-3.291-.5,3.445,3.445,0,0,0-.962.5c-.07.051-.139.1-.2.161a2.335,2.335,0,0,0-.23.207.3.3,0,0,0-.047.051c-.011.013-.027.028-.036.042a1.611,1.611,0,0,0-.163.19L7.039,12.133a8.04,8.04,0,0,1,8.352-5.007h0a3.681,3.681,0,0,0,.93.133h.046a3.633,3.633,0,0,0,2.008-.605,3.57,3.57,0,0,0,.926-.9A3.63,3.63,0,1,0,13.368,1.57a3.491,3.491,0,0,0-.38.71,3.589,3.589,0,0,0-.26,1.35c0,.065,0,.125,0,.19a4.146,4.146,0,0,0,.051.459,3.721,3.721,0,0,0,.125.486L6.369,8.542a3.546,3.546,0,0,0-.649-.59,3.629,3.629,0,0,0-4.2,0,3.675,3.675,0,0,0-.894.9,3.483,3.483,0,0,0-.38.71,3.35,3.35,0,0,0-.137.41,3.563,3.563,0,0,0-.123.949v.19a3.57,3.57,0,0,0,.038.38.635.635,0,0,0,.013.08,3.641,3.641,0,0,0,.634,1.469h0a3.7,3.7,0,0,0,.934.894,3.606,3.606,0,0,0,2.008.607,3.732,3.732,0,0,0,.55-.038l-.044.036a8.037,8.037,0,0,1,8.6,4.556v-.021a3.606,3.606,0,0,0,2.836,2.61,3.472,3.472,0,0,0,1.26,0,3.629,3.629,0,0,0,2.879-2.58.228.228,0,0,0,0-.038,3.606,3.606,0,0,0-.6-3.111,2.769,2.769,0,0,0-.344-.393M14.129,3.515a2.19,2.19,0,0,1,.254-.928,2.323,2.323,0,0,1,.885-.907A2.24,2.24,0,0,1,16.359,1.4a2.206,2.206,0,0,1,1.1.285,2.234,2.234,0,0,1,.886.909,2.179,2.179,0,0,1,.252,1.038,2.213,2.213,0,0,1-.306,1.116,2.181,2.181,0,0,1-.949.888,2.255,2.255,0,0,1-.983.23h-.04a2.158,2.158,0,0,1-.949-.228,2.278,2.278,0,0,1-.569-.406,1.912,1.912,0,0,1-.156-.171,2.314,2.314,0,0,1-.224-.313.078.078,0,0,1-.015-.027,2.226,2.226,0,0,1-.287-1.091.76.76,0,0,1,0-.114M2.638,12.921a2.24,2.24,0,0,1-.731-.569,2.327,2.327,0,0,1-.22-.307,2.24,2.24,0,0,1-.3-1.118,1.122,1.122,0,0,1,0-.114,2.183,2.183,0,0,1,.258-.941,2.316,2.316,0,0,1,.885-.909,2.278,2.278,0,0,1,1.09-.283,2.232,2.232,0,0,1,1.5.59,2.19,2.19,0,0,1,.437.55.313.313,0,0,1,.038.059,2.1,2.1,0,0,1,.207.562,2.149,2.149,0,0,1,.053.484,2.056,2.056,0,0,1-.057.488,2.105,2.105,0,0,1-.226.6.277.277,0,0,1-.017.028,2.183,2.183,0,0,1-.435.535,2.158,2.158,0,0,1-.514.349,2.265,2.265,0,0,1-.985.23,2.23,2.23,0,0,1-.983-.23m15.8,5.44a2.219,2.219,0,0,1-.642,1.346,2.169,2.169,0,0,1-.22.19,2.261,2.261,0,0,1-.746.38,2.175,2.175,0,0,1-1.26-.019,2.12,2.12,0,0,1-.917-.549A2.185,2.185,0,0,1,14,18.1h0a.9.9,0,0,1,.015-.2c.015-.066,0-.076.015-.116a1.575,1.575,0,0,1,.055-.241,1.993,1.993,0,0,1,.2-.48c.011-.025.027-.049.04-.074a2.291,2.291,0,0,1,.321-.4h0c.034-.034.066-.063.1-.093a1.627,1.627,0,0,1,.142-.114,1.693,1.693,0,0,1,.2-.139,2.253,2.253,0,0,1,2.245,0,2.446,2.446,0,0,1,.45.345,2.371,2.371,0,0,1,.323.412,2.266,2.266,0,0,1,.319,1.388" transform="translate(0.01 0)"/><path d="M78.35,12.262a.338.338,0,0,0,.319.222h.8v.845a.2.2,0,0,0,.013.085.325.325,0,0,0,.173.216.268.268,0,0,0,.156.046.294.294,0,0,0,.1-.019.34.34,0,0,0,.245-.328v-.845h.9a.345.345,0,0,0,.347-.344.355.355,0,0,0-.156-.287.349.349,0,0,0-.19-.057h-.9v-.848a.325.325,0,0,0-.082-.216.305.305,0,0,0-.044-.042l-.038-.023-.068-.036a.237.237,0,0,0-.112-.023.3.3,0,0,0-.156.038.19.19,0,0,0-.055.036.323.323,0,0,0-.129.268V11.8h-.8a.363.363,0,0,0-.19.057.38.38,0,0,0-.123.167.247.247,0,0,0-.027.12.3.3,0,0,0,.011.084.315.315,0,0,0,.015.038" transform="translate(-63.459 -8.595)"/></g></g></svg>'
|
||||
}
|
||||
|
||||
export const filters = {
|
||||
name: 'filters',
|
||||
data: '<svg id="Group_13364" data-name="Group 13364" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="20" viewBox="0 0 24.648 21.128"><defs><linearGradient id="linear-gradient" x2="1" y2="0.961" gradientUnits="objectBoundingBox"><stop offset="0" /><stop offset="1" /></linearGradient><linearGradient id="linear-gradient-2" x1="-0.029" y1="0.037" x2="1" y2="0.928" xlink:href="#linear-gradient"/></defs><g id="Group_13361" data-name="Group 13361" transform="translate(0 10.564)"><line id="Line_420" data-name="Line 420" x2="24.648" transform="translate(0 5.774)" fill="none" stroke="#707070" stroke-width="1"/><g id="Ellipse_515" data-name="Ellipse 515" transform="translate(2.078)" stroke="#fafafa" stroke-width="0.6"><ellipse cx="5.282" cy="5.282" rx="5.282" ry="5.282" stroke="none"/><ellipse cx="5.282" cy="5.282" rx="4.982" ry="4.982" fill="none"/></g></g><g id="Group_13362" data-name="Group 13362"><line id="Line_418" data-name="Line 418" x2="24.648" transform="translate(0 5.388)" fill="none" stroke="#707070" stroke-width="1"/><g id="Path_104494" data-name="Path 104494" transform="translate(11.444)"><path d="M 5.281623840332031 10.26361751556396 C 2.534753799438477 10.26361751556396 0.3000038266181946 8.028787612915039 0.3000038266181946 5.281807899475098 C 0.3000038266181946 2.534827947616577 2.534753799438477 0.2999978959560394 5.281623840332031 0.2999978959560394 C 8.028493881225586 0.2999978959560394 10.26324367523193 2.534827947616577 10.26324367523193 5.281807899475098 C 10.26324367523193 8.028787612915039 8.028493881225586 10.26361751556396 5.281623840332031 10.26361751556396 Z" stroke="none"/><path d="M 5.281623840332031 0.5999975204467773 C 2.700173854827881 0.5999975204467773 0.6000041961669922 2.700247764587402 0.6000041961669922 5.281807899475098 C 0.6000041961669922 7.863368034362793 2.700173854827881 9.963618278503418 5.281623840332031 9.963618278503418 C 7.863073825836182 9.963618278503418 9.96324348449707 7.863368034362793 9.96324348449707 5.281807899475098 C 9.96324348449707 2.700247764587402 7.863073825836182 0.5999975204467773 5.281623840332031 0.5999975204467773 M 5.281623840332031 -1.9073486328125e-06 C 8.198583602905273 -1.9073486328125e-06 10.5632438659668 2.364748001098633 10.5632438659668 5.281807899475098 C 10.5632438659668 8.198867797851562 8.198583602905273 10.56361770629883 5.281623840332031 10.56361770629883 C 2.364664077758789 10.56361770629883 3.814697265625e-06 8.198867797851562 3.814697265625e-06 5.281807899475098 C 3.814697265625e-06 2.364748001098633 2.364664077758789 -1.9073486328125e-06 5.281623840332031 -1.9073486328125e-06 Z" stroke="none" fill="#fafafa"/></g></g></svg>'
|
||||
}
|
||||
|
||||
export const orcid_add = {
|
||||
name: 'orcid_add',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 42.13 40.77"><defs><style>.cls-2{fill:#fff;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><circle cx="18.09" cy="18.09" r="18.09"/><rect class="cls-2" x="9.86" y="11.03" width="2.49" height="15.27"/><ellipse class="cls-2" cx="11.07" cy="8.16" rx="1.63" ry="1.6"/><path class="cls-2" d="M23.07,11.17A6.57,6.57,0,0,0,21.81,11H15.28V13.2h0V24.09h0v2.15h6.34a7.75,7.75,0,0,0,1.45-.14,7.61,7.61,0,0,0,0-14.93ZM25,23l-.26.19a4.3,4.3,0,0,1-.45.29,4.41,4.41,0,0,1-1.64.62H17.63V13.2h4.42a5.63,5.63,0,0,1,2.62.81,4.12,4.12,0,0,1,.47.38A5.74,5.74,0,0,1,25,23Z"/><path d="M41.33,34.62H37.57V30.86a.79.79,0,0,0-.79-.79h0a.79.79,0,0,0-.8.78h0v3.76H32.22a.79.79,0,0,0-.79.79h0a.79.79,0,0,0,.79.79H36V40a.8.8,0,1,0,1.59,0h0V36.21h3.76a.79.79,0,0,0,.8-.78h0A.8.8,0,0,0,41.33,34.62Z"/></g></g></svg>'
|
||||
}
|
||||
|
||||
export const orcid_bin = {
|
||||
name: 'orcid_bin',
|
||||
data: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 41.58 41.07"><defs><style>.cls-3{fill:#fff;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><g id="Layer_2-2" data-name="Layer 2"><g id="Layer_1-2-2" data-name="Layer 1-2"><path d="M40.55,31.91v7.56A1.58,1.58,0,0,1,39,41.07H34.3a1.59,1.59,0,0,1-1.57-1.6V31.91H32a.25.25,0,0,1-.27-.23v0h0a.28.28,0,0,1,.27-.23h2.32v-1a.25.25,0,0,1,.22-.28h4.22a.3.3,0,0,1,.28.28v1h2.32c.15,0,.22.13.22.28h0c0,.14-.08.18-.22.19Zm-7.23,0v7.56a1,1,0,0,0,1,1H39a1,1,0,0,0,1-1V31.91Zm5.12-.5v-.74H34.82v.74Z"/><path d="M34.74,33.79a.29.29,0,0,1,.28-.28.29.29,0,0,1,.27.28v4.85a.29.29,0,0,1-.27.28.29.29,0,0,1-.28-.28Z"/><path d="M38,33.79a.29.29,0,0,1,.28-.28.29.29,0,0,1,.27.28v4.85a.29.29,0,0,1-.27.28.29.29,0,0,1-.28-.28Z"/><path d="M36.34,33.79a.3.3,0,0,1,.28-.28.28.28,0,0,1,.27.28v4.85a.28.28,0,0,1-.27.28.3.3,0,0,1-.28-.28Z"/><circle cx="18.09" cy="18.09" r="18.09"/><rect class="cls-3" x="9.86" y="11.03" width="2.49" height="15.27"/><ellipse class="cls-3" cx="11.07" cy="8.16" rx="1.63" ry="1.6"/><path class="cls-3" d="M23.07,11.17A6.7,6.7,0,0,0,21.81,11H15.28v2.2h0V24.09h0v2.15h6.34a7.83,7.83,0,0,0,1.45-.14,7.61,7.61,0,0,0,0-14.93ZM25,23l-.26.19a3.46,3.46,0,0,1-.45.29,4.42,4.42,0,0,1-1.64.62h-5V13.2h4.42a5.63,5.63,0,0,1,2.62.81,3.4,3.4,0,0,1,.47.38,5.75,5.75,0,0,1,.38,8.11A6.14,6.14,0,0,1,25,23Z"/></g></g></g></g></svg>'
|
||||
}
|
||||
|
||||
export const link = {
|
||||
name: 'link',
|
||||
data: '<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" data-svg="link"><path fill="none" stroke="#000" stroke-width="1.1" d="M10.625,12.375 L7.525,15.475 C6.825,16.175 5.925,16.175 5.225,15.475 L4.525,14.775 C3.825,14.074 3.825,13.175 4.525,12.475 L7.625,9.375"></path><path fill="none" stroke="#000" stroke-width="1.1" d="M9.325,7.375 L12.425,4.275 C13.125,3.575 14.025,3.575 14.724,4.275 L15.425,4.975 C16.125,5.675 16.125,6.575 15.425,7.275 L12.325,10.375"></path><path fill="none" stroke="#000" stroke-width="1.1" d="M7.925,11.875 L11.925,7.975"></path></svg>'
|
||||
}
|
||||
|
||||
export const quotes = {
|
||||
name: 'quotes',
|
||||
data: '<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg" data-svg="quote-right"><path d="M17.27,7.79 C17.27,9.45 16.97,10.43 15.99,12.02 C14.98,13.64 13,15.23 11.56,15.97 L11.1,15.08 C12.34,14.2 13.14,13.51 14.02,11.82 C14.27,11.34 14.41,10.92 14.49,10.54 C14.3,10.58 14.09,10.6 13.88,10.6 C12.06,10.6 10.59,9.12 10.59,7.3 C10.59,5.48 12.06,4 13.88,4 C15.39,4 16.67,5.02 17.05,6.42 C17.19,6.82 17.27,7.27 17.27,7.79 L17.27,7.79 Z"></path><path d="M8.68,7.79 C8.68,9.45 8.38,10.43 7.4,12.02 C6.39,13.64 4.41,15.23 2.97,15.97 L2.51,15.08 C3.75,14.2 4.55,13.51 5.43,11.82 C5.68,11.34 5.82,10.92 5.9,10.54 C5.71,10.58 5.5,10.6 5.29,10.6 C3.47,10.6 2,9.12 2,7.3 C2,5.48 3.47,4 5.29,4 C6.8,4 8.08,5.02 8.46,6.42 C8.6,6.82 8.68,7.27 8.68,7.79 L8.68,7.79 Z"></path></svg>'
|
||||
}
|
||||
|
||||
export const mining = {
|
||||
name: 'mining',
|
||||
data: '<svg width="20" height="20" viewBox="0 0 600 500" xmlns="http://www.w3.org/2000/svg"><g><path d="m449.68 334.84-90.93-52.5c-5.4258-3.1133-12.074-3.1133-17.5 0l-90.93 52.5c-5.4258 3.1328-8.75 8.9062-8.75 15.156v105c0 6.2461 3.3242 12.039 8.75 15.156l90.93 52.5c2.7109 1.5547 5.7227 2.3438 8.75 2.3438s6.0391-0.78906 8.75-2.3438l90.93-52.5c5.4258-3.1328 8.75-8.9062 8.75-15.156v-105c0-6.2461-3.3242-12.023-8.75-15.156zm-99.68 120.16c-28.945 0-52.5-23.555-52.5-52.5s23.555-52.5 52.5-52.5 52.5 23.555 52.5 52.5-23.555 52.5-52.5 52.5z"/><path d="m545.93 35h-391.86c-27.055 0-49.07 22.016-49.07 49.07v20.93h490v-20.93c0-27.055-22.016-49.07-49.07-49.07z"/><path d="m105 370.93c0 27.055 22.016 49.07 49.07 49.07h70v-70c0-12.477 6.7031-24.078 17.5-30.309l90.93-52.5c5.3359-3.0625 11.375-4.6914 17.5-4.6914s12.164 1.6289 17.465 4.6719l90.965 52.516c10.797 6.2305 17.5 17.852 17.5 30.309v70h70c27.055 0.003906 49.07-22.012 49.07-49.066v-230.93h-490zm57.629-138.3 52.5-52.5c6.8438-6.8438 17.902-6.8438 24.746 0l42.84 42.84 75.793-45.484c6.8945-4.1289 15.715-3.0469 21.387 2.625l58.922 58.922 75.266-60.219c7.543-6.0391 18.551-4.8125 24.586 2.7305 6.0391 7.543 4.8125 18.566-2.7305 24.605l-87.5 70c-3.2188 2.5898-7.0859 3.8516-10.938 3.8516-4.4961 0-8.9961-1.7344-12.391-5.1289l-60.34-60.34-75.793 45.484c-6.8789 4.1289-15.68 3.0625-21.387-2.625l-40.09-40.145-40.129 40.129c-6.8438 6.8438-17.902 6.8438-24.746 0-6.8398-6.8438-6.8398-17.906 0.003906-24.746z"/></g></svg>'
|
||||
}
|
||||
|
||||
/** Add new icon under this line to be sure that it will be added on preview */
|
|
@ -1,626 +0,0 @@
|
|||
import {
|
||||
AfterViewInit,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter,
|
||||
HostListener,
|
||||
Input,
|
||||
OnChanges,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
SimpleChanges,
|
||||
ViewChild
|
||||
} from "@angular/core";
|
||||
import {AbstractControl, UntypedFormArray, UntypedFormControl, ValidatorFn} from "@angular/forms";
|
||||
// import {HelperFunctions} from "../../utils/HelperFunctions.class";
|
||||
import {Subscription} from "rxjs";
|
||||
import {ClickEvent} from "../click/click-outside-or-esc.directive";
|
||||
// import {EnvProperties} from "../../utils/properties/env-properties";
|
||||
// import {properties} from "../../../../environments/environment";
|
||||
|
||||
export type InputType = 'text' | 'URL' | 'logoURL' | 'autocomplete' | 'autocomplete_soft' | 'textarea' | 'select' | 'chips';
|
||||
|
||||
export interface Option {
|
||||
icon?: string,
|
||||
iconClass?: string,
|
||||
value: any,
|
||||
label: string,
|
||||
tooltip?: string,
|
||||
disabled?: boolean,
|
||||
hidden?: boolean
|
||||
}
|
||||
|
||||
export interface Placeholder {
|
||||
label: string,
|
||||
static?: boolean
|
||||
}
|
||||
|
||||
declare var UIkit;
|
||||
|
||||
/**
|
||||
* WARNING! dashboard-input selector is @deprecated, use input instead
|
||||
*
|
||||
* Autocomplete soft allows values that are not listed in options list. In order to work as expected
|
||||
* avoid providing options with different label and value.
|
||||
*
|
||||
* */
|
||||
@Component({
|
||||
selector: '[dashboard-input], [input]',
|
||||
template: `
|
||||
<div *ngIf="formControl" [id]="id">
|
||||
<div class="input-wrapper" [class.disabled]="formControl.disabled" [class.opened]="opened"
|
||||
[class.focused]="focused" [ngClass]="inputClass" [class.hint]="hint"
|
||||
[class.active]="(formAsControl?.value || selectable || formAsArray?.length > 0 || getLabel(formAsControl?.value)) && !focused"
|
||||
[class.danger]="(formControl.invalid && (formControl.touched || !!searchControl?.touched)) || (!!searchControl?.invalid && !!searchControl?.touched)">
|
||||
<div #inputBox class="input-box" [class.select]="selectable" click-outside-or-esc
|
||||
[class.static]="placeholderInfo?.static" (clickOutside)="click($event)">
|
||||
<div *ngIf="!placeholderInfo?.static && placeholderInfo.label" class="placeholder">
|
||||
<label>{{placeholderInfo.label}} <sup *ngIf="required">*</sup></label>
|
||||
</div>
|
||||
<div class="uk-flex" [class.uk-flex-middle]="type !== 'textarea'"
|
||||
[attr.uk-tooltip]="(tooltip && formControl.value && !focused && type !== 'chips' && type !== 'textarea')?('title: ' + getTooltip(formControl.value) + '; delay: 500; pos: bottom-left'):null">
|
||||
<ng-template [ngIf]="type === 'text' || type === 'URL' || type === 'logoURL'">
|
||||
<input #input class="input" [attr.placeholder]="placeholderInfo?.static?placeholderInfo.label:hint"
|
||||
[formControl]="formAsControl" [class.uk-text-truncate]="!focused">
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="type === 'textarea'">
|
||||
<textarea #textArea class="input" [attr.placeholder]="placeholderInfo?.static?placeholderInfo.label:hint"
|
||||
[rows]="rows" [formControl]="formAsControl"></textarea>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="type === 'select'">
|
||||
<ng-container *ngIf="placeholderInfo?.static">
|
||||
<div *ngIf="!getLabel(formControl.value)"
|
||||
class="input placeholder uk-width-expand uk-text-truncate">{{placeholderInfo.label}}</div>
|
||||
<div *ngIf="getLabel(formControl.value)"
|
||||
class="input uk-width-expand uk-text-truncate">{{getLabel(formControl.value)}}</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!placeholderInfo?.static">
|
||||
<div *ngIf="!getLabel(formControl.value)" class="input uk-width-expand uk-text-truncate">{{noValueSelected}}</div>
|
||||
<div *ngIf="getLabel(formControl.value)"
|
||||
class="input uk-width-expand uk-text-truncate">{{getLabel(formControl.value)}}</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="type === 'autocomplete'">
|
||||
<input *ngIf="focused" [attr.placeholder]="placeholderInfo?.static?placeholderInfo.label:hint"
|
||||
#searchInput class="input" [formControl]="searchControl" [class.uk-text-truncate]="!focused">
|
||||
<div *ngIf="!focused && !selectable" class="input uk-text-truncate">{{getLabel(formAsControl.value)}}</div>
|
||||
<ng-container *ngIf="!focused && selectable" >
|
||||
<div *ngIf="!getLabel(formControl.value)" class="input uk-text-truncate">{{noValueSelected}}</div>
|
||||
<div *ngIf="getLabel(formControl.value)" class="input uk-text-truncate">{{getLabel(formControl.value)}}</div>
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="type === 'autocomplete_soft'">
|
||||
<input #input class="input" [attr.placeholder]="placeholderInfo?.static?placeholderInfo.label:hint"
|
||||
[formControl]="formAsControl" [class.uk-text-truncate]="!focused">
|
||||
</ng-template>
|
||||
<ng-template [ngIf]="type === 'chips'">
|
||||
<div class="uk-grid uk-grid-small uk-grid-row-collapse uk-width-expand" uk-grid>
|
||||
<div *ngFor="let chip of formAsArray.controls; let i=index" [class.uk-hidden]="!focused && i > 0"
|
||||
class="chip">
|
||||
<div class="uk-label uk-label-small uk-flex uk-flex-middle"
|
||||
[attr.uk-tooltip]="(tooltip)?('title: ' + getLabel(chip.value) + '; delay: 500; pos: bottom-left'):null">
|
||||
<span class="uk-text-truncate uk-width-expand">{{getLabel(chip.value)}}</span>
|
||||
<icon *ngIf="focused" (click)="remove(i, $event)" class="uk-link-text uk-margin-small-left clickable" [flex]="true"
|
||||
name="close" ratio="0.7"></icon>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="searchControl && (focused || formAsArray.length === 0)"
|
||||
class="uk-width-small uk-flex uk-flex-column uk-flex-center">
|
||||
<input #searchInput class="input" [class.search]="searchControl.value"
|
||||
[attr.placeholder]="placeholderInfo?.static?placeholderInfo.label:hint"
|
||||
[formControl]="searchControl" [class.uk-text-truncate]="!focused">
|
||||
</div>
|
||||
<div *ngIf="!focused && formAsArray.length > 1"
|
||||
class="uk-width-expand uk-flex uk-flex-column uk-flex-center more">
|
||||
+ {{(formAsArray.length - 1)}} more
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
<div *ngIf="(formControl.disabled && disabledIcon) || icon || (selectable && selectArrow) || type === 'autocomplete' || searchable"
|
||||
class="uk-margin-small-left icon">
|
||||
<icon *ngIf="formControl.disabled && disabledIcon" [name]="disabledIcon" [flex]="true"></icon>
|
||||
<ng-template [ngIf]="formControl.enabled">
|
||||
<icon *ngIf="!searchControl?.value && icon" [name]="icon" [flex]="true"></icon>
|
||||
<icon *ngIf="!icon && selectable && selectArrow" [name]="selectArrow" [flex]="true"></icon>
|
||||
<button *ngIf="!!searchControl?.value && type === 'autocomplete'" class="uk-close uk-icon"
|
||||
(click)="resetSearch($event)">
|
||||
<icon [flex]="true" name="close"></icon>
|
||||
</button>
|
||||
<button *ngIf="!!formControl?.value && searchable" class="uk-close uk-icon" (click)="resetValue($event)">
|
||||
<icon [flex]="true" name="close"></icon>
|
||||
</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tools">
|
||||
<ng-content select="[tools]"></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="options uk-dropdown" *ngIf="filteredOptions && filteredOptions.length > 0 && opened" #optionBox
|
||||
uk-dropdown="pos: bottom-justify; mode: none; offset: 15; boundary-align: true;" [attr.boundary]="'#' + id">
|
||||
<ul class="uk-nav uk-dropdown-nav">
|
||||
<li *ngFor="let option of filteredOptions; let i=index" [class.uk-hidden]="option.hidden" [class.uk-active]="(formControl.value === option.value) || selectedIndex === i">
|
||||
<a (click)="selectOption(option, $event)"
|
||||
[class]="option.disabled ? 'uk-disabled uk-text-muted' : ''">
|
||||
<span [attr.uk-tooltip]="(tooltip)?('title: ' + (option.tooltip ? option.tooltip : option.label) + '; delay: 500; pos:bottom-left'):null">{{option.label}}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<span *ngIf="formControl?.invalid && formControl?.touched" class="uk-text-danger">
|
||||
<span *ngIf="formControl.errors.error">{{formControl.errors.error}}</span>
|
||||
<span *ngIf="type === 'URL' || type === 'logoURL'">Please provide a valid URL (e.g. https://example.com)</span>
|
||||
</span>
|
||||
<span class="uk-text-danger uk-text-small">
|
||||
<ng-content select="[error]"></ng-content>
|
||||
</span>
|
||||
<span *ngIf="formControl?.valid" class="uk-text-warning uk-text-small">
|
||||
<ng-content select="[warning]"></ng-content>
|
||||
<span *ngIf="!secure">
|
||||
<span class="uk-text-bold">Note:</span> Prefer urls like "<span class="uk-text-bold">https://</span>example.com/my-secure-image.png"
|
||||
instead of "<span class="uk-text-bold">http://</span>example.com/my-image.png".
|
||||
<span class="uk-text-bold">Browsers may not load non secure content.</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="uk-text-small">
|
||||
<ng-content select="[note]"></ng-content>
|
||||
</span>
|
||||
`
|
||||
})
|
||||
export class InputComponent implements OnInit, OnDestroy, AfterViewInit, OnChanges {
|
||||
private static INPUT_COUNTER: number = 0;
|
||||
/** Deprecated options*/
|
||||
/** @deprecated */
|
||||
@Input('label') label: string;
|
||||
/** @deprecated */
|
||||
@Input() extraLeft: boolean = true;
|
||||
/** @deprecated */
|
||||
@Input() gridSmall: boolean = false;
|
||||
/** @deprecated */
|
||||
@Input() hideControl: boolean = false;
|
||||
/** @deprecated */
|
||||
@Input() flex: 'middle' | 'top' | 'bottom' = 'middle';
|
||||
/** @deprecated */
|
||||
@Input() iconLeft: boolean = false;
|
||||
/** @deprecated */
|
||||
@Input() removable: boolean = true;
|
||||
/** @deprecated */
|
||||
@Input() smallChip: boolean = false;
|
||||
/** @deprecated */
|
||||
@Input() panelWidth: number = 300;
|
||||
/** @deprecated */
|
||||
@Input() panelClass: string = null;
|
||||
/** Basic information */
|
||||
@Input('formInput') formControl: AbstractControl;
|
||||
@Input('type') type: InputType = 'text';
|
||||
@Input() validators: ValidatorFn[] | ValidatorFn;
|
||||
@Input() disabled: boolean = false;
|
||||
@Input() disabledIcon: string = 'lock';
|
||||
@Input() value: any | any[];
|
||||
@Output() valueChange = new EventEmitter<any | any[]>();
|
||||
@Input() hint: string;
|
||||
@Input() tooltip: boolean = false;
|
||||
@Input() searchable: boolean = false;
|
||||
/** Text */
|
||||
@ViewChild('input') input: ElementRef;
|
||||
/** Textarea options */
|
||||
@ViewChild('textArea') textArea: ElementRef;
|
||||
@Input('rows') rows: number = 3;
|
||||
/** Select | Autocomplete | chips available options */
|
||||
@Input() selectArrow: string = 'arrow_drop_down';
|
||||
@Input() selectedIndex: number = 0;
|
||||
@Input() selectable: boolean = false;
|
||||
@Input() noValueSelected: string = 'No option selected';
|
||||
/** Chips && Autocomplete*/
|
||||
public filteredOptions: Option[] = [];
|
||||
public searchControl: UntypedFormControl;
|
||||
/** Use modifier's class(es) to change view of your Input */
|
||||
@Input() inputClass: string = 'inner';
|
||||
/** Icon on the input */
|
||||
@Input() icon: string = null;
|
||||
/** Chip options */
|
||||
@Input() addExtraChips: boolean = false;
|
||||
@Input() showOptionsOnEmpty: boolean = true;
|
||||
@Output() focusEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
/** LogoUrl information */
|
||||
public secure: boolean = true;
|
||||
/** Internal basic information */
|
||||
public id: string;
|
||||
public placeholderInfo: Placeholder = {label: '', static: true};
|
||||
public required: boolean = false;
|
||||
public focused: boolean = false;
|
||||
public opened: boolean = false;
|
||||
private initValue: any;
|
||||
private optionsArray: Option[] = [];
|
||||
private optionsBreakpoint: number = 6;
|
||||
private subscriptions: any[] = [];
|
||||
@ViewChild('inputBox') inputBox: ElementRef;
|
||||
@ViewChild('optionBox') optionBox: ElementRef;
|
||||
@ViewChild('searchInput') searchInput: ElementRef;
|
||||
|
||||
@Input()
|
||||
set placeholder(placeholder: string | Placeholder) {
|
||||
if (typeof placeholder === 'string') {
|
||||
this.placeholderInfo = {label: placeholder, static: false};
|
||||
} else {
|
||||
if (placeholder.static && (this.type === 'autocomplete' || this.type === 'chips' || this.hint)) {
|
||||
placeholder.static = false;
|
||||
console.debug('Static placeholder is not available in this type of input and if hint is available.');
|
||||
}
|
||||
this.placeholderInfo = placeholder;
|
||||
}
|
||||
}
|
||||
|
||||
@Input()
|
||||
set options(options: (Option | string | number) []) {
|
||||
this.optionsArray = options.map(option => {
|
||||
if (typeof option === 'string' || typeof option === 'number') {
|
||||
return {
|
||||
label: option.toString(),
|
||||
value: option
|
||||
};
|
||||
} else {
|
||||
return option;
|
||||
}
|
||||
});
|
||||
if(!this.tooltip) {
|
||||
this.tooltip = this.optionsArray.length > 0;
|
||||
}
|
||||
if(this.type === "select") {
|
||||
if (this.optionsArray.length > this.optionsBreakpoint) {
|
||||
this.type = 'autocomplete';
|
||||
this.showOptionsOnEmpty = true;
|
||||
this.icon = this.selectArrow;
|
||||
}
|
||||
this.selectable = true;
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private elementRef: ElementRef, private cdr: ChangeDetectorRef) {}
|
||||
|
||||
@HostListener('window:keydown.arrowUp', ['$event'])
|
||||
arrowUp(event: KeyboardEvent) {
|
||||
if (this.opened) {
|
||||
event.preventDefault();
|
||||
if (this.selectedIndex > 0) {
|
||||
this.selectedIndex--;
|
||||
this.optionBox.nativeElement.scrollBy(0, -34);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.arrowDown', ['$event'])
|
||||
arrowDown(event: KeyboardEvent) {
|
||||
if (this.opened) {
|
||||
event.preventDefault();
|
||||
if (this.selectedIndex < (this.filteredOptions.length - 1)) {
|
||||
this.selectedIndex++;
|
||||
this.optionBox.nativeElement.scrollBy(0, 34);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@HostListener('window:keydown.enter', ['$event'])
|
||||
enter(event: KeyboardEvent) {
|
||||
if (this.opened && this.optionBox) {
|
||||
event.preventDefault();
|
||||
if (this.filteredOptions[this.selectedIndex]) {
|
||||
this.selectOption(this.filteredOptions[this.selectedIndex], event);
|
||||
}
|
||||
this.open(false);
|
||||
event.stopPropagation();
|
||||
} else {
|
||||
this.focus(false, event);
|
||||
}
|
||||
}
|
||||
|
||||
click(event: ClickEvent) {
|
||||
this.focus(!event.clicked, event);
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
InputComponent.INPUT_COUNTER++;
|
||||
this.id = 'input-' + InputComponent.INPUT_COUNTER;
|
||||
if (!this.formControl) {
|
||||
if (Array.isArray(this.value)) {
|
||||
this.formControl = new UntypedFormArray([]);
|
||||
this.value.forEach(value => {
|
||||
this.formAsArray.push(new UntypedFormControl(value, this.validators));
|
||||
});
|
||||
} else {
|
||||
this.formControl = new UntypedFormControl(this.value);
|
||||
this.formControl.setValidators(this.validators);
|
||||
}
|
||||
if (this.disabled) {
|
||||
this.formControl.disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (this.formControl) {
|
||||
if (changes.value) {
|
||||
this.formControl.setValue(this.value);
|
||||
}
|
||||
if (changes.formControl || changes.validators || changes.options) {
|
||||
this.reset();
|
||||
}
|
||||
if (changes.disabled) {
|
||||
if (this.disabled) {
|
||||
this.formControl.disable();
|
||||
} else {
|
||||
this.formControl.enable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.unsubscribe();
|
||||
}
|
||||
|
||||
get formAsControl(): UntypedFormControl {
|
||||
if (this.formControl instanceof UntypedFormControl) {
|
||||
return this.formControl;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
get formAsArray(): UntypedFormArray {
|
||||
if (this.formControl instanceof UntypedFormArray) {
|
||||
return this.formControl;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.secure = true;
|
||||
this.unsubscribe();
|
||||
this.initValue = this.copy(this.formControl.value);
|
||||
if (this.type === 'logoURL') {
|
||||
this.secure = (!this.initValue || this.initValue.includes('https://'));
|
||||
}
|
||||
if (this.optionsArray) {
|
||||
this.filteredOptions = this.filter('');
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
if (this.type === 'chips' || this.type === 'autocomplete') {
|
||||
if (!this.searchControl) {
|
||||
this.searchControl = new UntypedFormControl('', this.validators);
|
||||
}
|
||||
this.subscriptions.push(this.searchControl.valueChanges.subscribe(value => {
|
||||
this.filteredOptions = this.filter(value);
|
||||
this.cdr.detectChanges();
|
||||
if (this.focused) {
|
||||
this.open(true);
|
||||
setTimeout(() => {
|
||||
this.searchInput.nativeElement.focus();
|
||||
this.searchInput.nativeElement.value = value;
|
||||
}, 0);
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (this.formControl.validator) {
|
||||
let validator = this.formControl.validator({} as AbstractControl);
|
||||
this.required = (validator && validator.required);
|
||||
}
|
||||
this.subscriptions.push(this.formControl.valueChanges.subscribe(value => {
|
||||
if (this.formControl.enabled) {
|
||||
value = (value === '') ? null : value;
|
||||
if (this.type === 'logoURL') {
|
||||
this.secure = (!value || value.includes('https://'));
|
||||
}
|
||||
if (this.initValue === value || (this.initValue === '' && value === null)) {
|
||||
this.formControl.markAsPristine();
|
||||
} else {
|
||||
this.formControl.markAsDirty();
|
||||
}
|
||||
if (this.type === 'autocomplete_soft') {
|
||||
this.filteredOptions = this.filter(value);
|
||||
this.cdr.detectChanges();
|
||||
if (this.focused) {
|
||||
this.open(true);
|
||||
}
|
||||
}
|
||||
if ((this.value && value && this.value !== value) || (!this.value && value) || this.value && !value) {
|
||||
this.valueChange.emit(this.formControl.value);
|
||||
}
|
||||
}
|
||||
}));
|
||||
if (this.input) {
|
||||
this.input.nativeElement.disabled = this.formControl.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
unsubscribe() {
|
||||
this.subscriptions.forEach(subscription => {
|
||||
if (subscription instanceof Subscription) {
|
||||
subscription.unsubscribe();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
remove(index: number, event) {
|
||||
if (this.focused) {
|
||||
this.formAsArray.removeAt(index);
|
||||
this.formAsArray.markAsDirty();
|
||||
this.focus(true);
|
||||
this.searchControl.setValue('');
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
private filter(value: string): Option[] {
|
||||
let options = this.optionsArray.filter(option => !option.hidden);
|
||||
if (this.type === "chips") {
|
||||
options = options.filter(option => !this.formAsArray.value.find(value => this.equals(option.value, value)));
|
||||
}
|
||||
if ((!value || value.length == 0)) {
|
||||
this.selectedIndex = 0;
|
||||
return (this.showOptionsOnEmpty) ? options : [];
|
||||
}
|
||||
const filterValue = value.toString().toLowerCase();
|
||||
options = options.filter(option => option.label.toLowerCase().indexOf(filterValue) != -1);
|
||||
this.selectedIndex = options.findIndex(option => option.value === this.formControl.value);
|
||||
if (this.selectedIndex === -1) {
|
||||
this.selectedIndex = 0;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
add(event) {
|
||||
if (this.addExtraChips && this.searchControl.value && this.searchControl.valid) {
|
||||
if (event && event.stopPropagation) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
this.formAsArray.push(new UntypedFormControl(this.searchControl.value, this.validators));
|
||||
this.formAsArray.markAsDirty();
|
||||
}
|
||||
this.searchControl.setValue('');
|
||||
}
|
||||
|
||||
getLabel(value: any): string {
|
||||
let option = this.optionsArray.find(option => this.equals(option.value, value));
|
||||
return (option) ? option.label : (value);
|
||||
}
|
||||
|
||||
getTooltip(value: any): string {
|
||||
let option = this.optionsArray.find(option => this.equals(option.value, value));
|
||||
return (option) ? (option.tooltip ? option.tooltip : option.label) : (value);
|
||||
}
|
||||
|
||||
focus(value: boolean, event = null) {
|
||||
if (this.focused) {
|
||||
this.formControl.markAsTouched();
|
||||
}
|
||||
this.focused = value;
|
||||
this.cdr.detectChanges();
|
||||
if (this.focused) {
|
||||
if (this.input) {
|
||||
this.input.nativeElement.focus();
|
||||
} else if (this.textArea) {
|
||||
this.textArea.nativeElement.focus();
|
||||
} else if (this.searchInput) {
|
||||
this.searchInput.nativeElement.focus();
|
||||
}
|
||||
if (this.selectArrow) {
|
||||
this.open(!this.opened);
|
||||
} else if (this.type !== 'autocomplete' || this.showOptionsOnEmpty || !this.formControl.value) {
|
||||
this.open(true);
|
||||
}
|
||||
} else {
|
||||
this.open(false);
|
||||
if (this.input) {
|
||||
this.input.nativeElement.blur();
|
||||
} else if (this.textArea) {
|
||||
this.textArea.nativeElement.blur();
|
||||
} else if (this.searchInput) {
|
||||
this.searchInput.nativeElement.blur();
|
||||
}
|
||||
if (this.searchControl) {
|
||||
this.add(event);
|
||||
}
|
||||
}
|
||||
this.focusEmitter.emit(this.focused);
|
||||
}
|
||||
|
||||
open(value: boolean) {
|
||||
this.opened = value && this.formControl.enabled;
|
||||
this.cdr.detectChanges();
|
||||
if (this.optionBox && this.opened) {
|
||||
this.selectedIndex = this.filteredOptions.findIndex(option => option.value === this.formControl.value);
|
||||
if (this.selectedIndex === -1 && this.type !== 'autocomplete_soft') {
|
||||
this.selectedIndex = 0;
|
||||
}
|
||||
UIkit.dropdown(this.optionBox.nativeElement).show();
|
||||
} else {
|
||||
if (this.optionBox) {
|
||||
UIkit.dropdown(this.optionBox.nativeElement).hide();
|
||||
this.focused = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resetSearch(event: any) {
|
||||
event.stopPropagation();
|
||||
this.searchControl.setValue('');
|
||||
this.focus(true, event);
|
||||
}
|
||||
|
||||
resetValue(event: any) {
|
||||
event.stopPropagation();
|
||||
this.formControl.setValue('');
|
||||
this.focus(true, event);
|
||||
}
|
||||
|
||||
selectOption(option: Option, event) {
|
||||
if (this.formControl.enabled) {
|
||||
if (this.formAsControl) {
|
||||
this.formAsControl.setValue(option.value);
|
||||
} else if (this.formAsArray) {
|
||||
this.formAsArray.push(new UntypedFormControl(option.value));
|
||||
this.formAsArray.markAsDirty();
|
||||
event.stopPropagation();
|
||||
this.focus(true);
|
||||
this.searchControl.setValue('');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// External Helper Methods
|
||||
public equals(object1, object2) {
|
||||
return object1 === object2 || JSON.stringify(object1) === JSON.stringify(object2);
|
||||
}
|
||||
|
||||
public copy(obj: any): any {
|
||||
let copy;
|
||||
|
||||
// Handle the 3 simple types, and null or undefined
|
||||
if (null == obj || "object" != typeof obj) return obj;
|
||||
|
||||
// Handle Date
|
||||
if (obj instanceof Date) {
|
||||
copy = new Date();
|
||||
copy.setTime(obj.getTime());
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Array
|
||||
if (obj instanceof Array) {
|
||||
copy = [];
|
||||
for (let i = 0, len = obj.length; i < len; i++) {
|
||||
copy[i] = this.copy(obj[i]);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
// Handle Map
|
||||
if (obj instanceof Map) {
|
||||
return new Map(obj.entries());
|
||||
}
|
||||
|
||||
// Handle Object
|
||||
if (obj instanceof Object) {
|
||||
copy = {};
|
||||
for (let attr in obj) {
|
||||
if (obj.hasOwnProperty(attr)) {
|
||||
copy[attr] = this.copy(obj[attr]);
|
||||
}
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
throw new Error("Unable to copy obj! Its type isn't supported.");
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
import {NgModule} from '@angular/core';
|
||||
import {InputComponent} from "./input.component";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {RouterModule} from "@angular/router";
|
||||
import {FormsModule, ReactiveFormsModule} from "@angular/forms";
|
||||
import {ClickModule} from "../click/click.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
FormsModule,
|
||||
ReactiveFormsModule,
|
||||
ClickModule
|
||||
],
|
||||
exports: [
|
||||
InputComponent
|
||||
],
|
||||
declarations: [
|
||||
InputComponent
|
||||
]
|
||||
})
|
||||
export class InputModule {
|
||||
}
|
|
@ -1,191 +0,0 @@
|
|||
import {Component, ElementRef, EventEmitter, Input, Output, ViewChild, ViewEncapsulation} from '@angular/core';
|
||||
|
||||
declare var UIkit: any;
|
||||
|
||||
@Component({
|
||||
selector: 'modal-alert',
|
||||
template: `
|
||||
<div #element class="uk-modal" [class.uk-modal-container]="large" [id]="id" uk-modal="container: #modal-container">
|
||||
<div class="uk-modal-dialog">
|
||||
<div class="uk-modal-header uk-flex uk-flex-middle uk-flex-between" [ngClass]="classTitle">
|
||||
<div [class.uk-invisible]="!alertHeader">
|
||||
<h5 class="uk-margin-remove">{{alertTitle}}</h5>
|
||||
</div>
|
||||
<button class="uk-close uk-icon uk-margin-left" (click)="cancel()">
|
||||
<icon name="close" ratio="1.5"></icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="uk-modal-body uk-animation-fast uk-text-left"
|
||||
[ngClass]="classBody" [attr.uk-overflow-auto]="overflowBody?'':null">
|
||||
<div *ngIf="message" [hidden]=!alertMessage [innerHTML]="message"></div>
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
<div *ngIf="(choice || okButton || cancelButton) && alertFooter" class="uk-modal-footer">
|
||||
<div class="uk-grid uk-flex uk-flex-middle" uk-grid>
|
||||
<label *ngIf="choice" class="uk-width-expand">
|
||||
<input type="checkbox" [(ngModel)]="select">
|
||||
<span class="uk-margin-small-left">Don't show this message again</span>
|
||||
</label>
|
||||
<div [ngClass]="(choice)?'uk-width-auto':'uk-width-1-1'">
|
||||
<div class="uk-flex-right uk-grid uk-grid-small" uk-grid>
|
||||
<span *ngIf="okButton" [class.uk-flex-last]="!okButtonLeft">
|
||||
<button class="uk-button uk-button-primary" [disabled]="okDisabled"
|
||||
[class.uk-disabled]="okDisabled" (click)="ok()">{{okButtonText}}</button>
|
||||
</span>
|
||||
<span *ngIf="cancelButton">
|
||||
<button class="uk-button uk-button-default uk-margin-small-left"
|
||||
(click)="cancel()">{{cancelButtonText}}</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
/**
|
||||
* API to an open alert window.
|
||||
*/
|
||||
export class AlertModal {
|
||||
private static MODAL_COUNTER: number = 0;
|
||||
|
||||
id: string = "modal";
|
||||
@Input() classTitle: string = "uk-background-primary-opacity";
|
||||
@Input() classBody: string = "";
|
||||
@Input() large: boolean = false;
|
||||
@Input() overflowBody: boolean = true;
|
||||
/**
|
||||
* Caption for the title.
|
||||
*/
|
||||
public alertTitle: string;
|
||||
/**
|
||||
* Describes if the alert contains Ok Button.
|
||||
* The default Ok button will close the alert and emit the callback.
|
||||
* Defaults to true.
|
||||
*/
|
||||
public okButton: boolean = true;
|
||||
/**
|
||||
* Caption for the OK button.
|
||||
* Default: Ok
|
||||
*/
|
||||
public okButtonText: string = 'OK';
|
||||
/**
|
||||
* Describes if the alert contains cancel Button.
|
||||
* The default Cancelbutton will close the alert.
|
||||
* Defaults to true.
|
||||
*/
|
||||
public cancelButton: boolean = true;
|
||||
/**
|
||||
* Caption for the Cancel button.
|
||||
* Default: Cancel
|
||||
*/
|
||||
public cancelButtonText: string = 'Cancel';
|
||||
/**
|
||||
* if the alertMessage is true it will show the contentString inside alert body.
|
||||
*/
|
||||
public alertMessage: boolean = true;
|
||||
/**
|
||||
* Some message/content can be set in message which will be shown in alert body.
|
||||
*/
|
||||
public message: string;
|
||||
/**
|
||||
* if the value is true alert footer will be visible or else it will be hidden.
|
||||
*/
|
||||
public alertFooter: boolean = true;
|
||||
/**
|
||||
* shows alert header if the value is true.
|
||||
*/
|
||||
public alertHeader: boolean = true;
|
||||
/**
|
||||
* if the value is true ok button align on the left, else on the right
|
||||
*/
|
||||
public okButtonLeft: boolean = true;
|
||||
|
||||
/**
|
||||
* if the value is true ok button is disabled
|
||||
*/
|
||||
@Input()
|
||||
public okDisabled: boolean = false;
|
||||
|
||||
/**
|
||||
* If the value is true, a checkbox option will be appeared on the right side of footer
|
||||
*/
|
||||
@Input()
|
||||
public choice: boolean = false;
|
||||
|
||||
/**
|
||||
* if the value is true then on ok clicked, modal will stay open.
|
||||
*/
|
||||
public stayOpen: boolean = false;
|
||||
|
||||
/**
|
||||
* Value will be emitted if @choice is true
|
||||
*/
|
||||
public select: boolean = true;
|
||||
/**
|
||||
* Emitted when ok button was clicked
|
||||
* or when Ok method is called.
|
||||
*/
|
||||
@Output() public alertOutput: EventEmitter<any> = new EventEmitter();
|
||||
/**
|
||||
* Emitted when cancel button was clicked
|
||||
* or when cancel method is called.
|
||||
*/
|
||||
@Output() public cancelOutput: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
@ViewChild('element') element: ElementRef;
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
AlertModal.MODAL_COUNTER++;
|
||||
this.id = 'modal-' + AlertModal.MODAL_COUNTER;
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if(typeof document !== "undefined") {
|
||||
const element = document.getElementById("modal-container");
|
||||
for (let i = element.childNodes.length - 1; i >= 0; --i) {
|
||||
let child: ChildNode = element.childNodes[i];
|
||||
if (child['id'] == this.id) {
|
||||
child.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens an alert window creating backdrop.
|
||||
*/
|
||||
open() {
|
||||
UIkit.modal(this.element.nativeElement).show();
|
||||
}
|
||||
|
||||
/**
|
||||
* ok method closes the modal and emits modalOutput.
|
||||
*/
|
||||
ok() {
|
||||
if (!this.stayOpen) {
|
||||
UIkit.modal(this.element.nativeElement).hide();
|
||||
}
|
||||
if (!this.choice) {
|
||||
this.alertOutput.emit(true);
|
||||
} else {
|
||||
this.alertOutput.emit({
|
||||
value: true,
|
||||
choice: this.select
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* cancel method closes the modal.
|
||||
*/
|
||||
cancel() {
|
||||
UIkit.modal(this.element.nativeElement).hide();
|
||||
this.cancelOutput.emit(true);
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import {AlertModal} from './alert';
|
||||
import {ModalModule} from './modal.module';
|
||||
import {IconsModule} from "../icons/icons.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, FormsModule, ModalModule, IconsModule],
|
||||
declarations: [
|
||||
AlertModal
|
||||
],
|
||||
exports: [
|
||||
AlertModal
|
||||
]
|
||||
})
|
||||
export class AlertModalModule { }
|
|
@ -1,144 +0,0 @@
|
|||
import {
|
||||
AfterViewInit, ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
EventEmitter, HostListener,
|
||||
Input,
|
||||
OnDestroy,
|
||||
OnInit,
|
||||
Output,
|
||||
ViewChild
|
||||
} from "@angular/core";
|
||||
import {fromEvent, Subscription} from 'rxjs';
|
||||
import {delay} from "rxjs/operators";
|
||||
import {HelperFunctions} from "../../HelperFunctions.class";
|
||||
|
||||
declare var UIkit;
|
||||
declare var ResizeObserver;
|
||||
|
||||
@Component({
|
||||
selector: 'fs-modal',
|
||||
template: `
|
||||
<div #modal class="uk-modal-full" [id]="id" uk-modal="container: #modal-container">
|
||||
<div class="uk-modal-dialog">
|
||||
<div #header class="uk-modal-header uk-flex uk-flex-middle" [ngClass]="classTitle">
|
||||
<div [class.uk-invisible]="!back" class="uk-width-medium@l uk-width-auto uk-flex uk-flex-center">
|
||||
<button class="uk-button uk-button-link" [disabled]="!back" (click)="cancel()">
|
||||
<icon name="west" [flex]="true" ratio="3"></icon>
|
||||
</button>
|
||||
</div>
|
||||
<div [class.uk-invisible]="!title"
|
||||
class="uk-width-expand uk-padding-small uk-padding-remove-vertical uk-flex uk-flex-center">
|
||||
<h2 class="uk-margin-remove">{{title}}</h2>
|
||||
</div>
|
||||
<div class="uk-width-medium@l uk-width-auto uk-flex" [class.uk-flex-center]="okButton" [class.uk-flex-right]="!okButton">
|
||||
<button *ngIf="okButton" class="uk-button uk-button-default" [disabled]="okButtonDisabled"
|
||||
[class.uk-disabled]="okButtonDisabled" (click)="ok()">
|
||||
{{okButtonText}}
|
||||
</button>
|
||||
<button *ngIf="!okButton" class="uk-close uk-icon" (click)="cancel()">
|
||||
<icon name="close" ratio="2"></icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div #body class="uk-modal-body uk-overflow-auto" [ngStyle]="{'height.px': bodyHeight}">
|
||||
<div class="uk-container uk-height-1-1" [ngClass]="classBody">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class FullScreenModalComponent implements AfterViewInit, OnDestroy {
|
||||
private static FS_MODAL_COUNTER: number = 0;
|
||||
|
||||
id: string = "fs-modal";
|
||||
@Input() classTitle: string = "uk-background-primary uk-light";
|
||||
@Input() classBody: string = 'uk-container-large';
|
||||
back: boolean = false;
|
||||
title: string;
|
||||
okButton: boolean = false;
|
||||
okButtonText = 'OK';
|
||||
@Input()
|
||||
okButtonDisabled = false;
|
||||
@Output()
|
||||
okEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
@Output()
|
||||
cancelEmitter: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
@ViewChild('modal') modal: ElementRef;
|
||||
@ViewChild('header') header: ElementRef;
|
||||
@ViewChild('body') body: ElementRef;
|
||||
observer: any;
|
||||
headerHeight: number;
|
||||
bodyHeight: number;
|
||||
|
||||
constructor(private cdr: ChangeDetectorRef) {
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event'])
|
||||
onResize() {
|
||||
this.changeHeight();
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
FullScreenModalComponent.FS_MODAL_COUNTER++;
|
||||
this.id = 'fs-modal-' + FullScreenModalComponent.FS_MODAL_COUNTER;
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
if(typeof window !== "undefined") {
|
||||
this.observer = new ResizeObserver(entries => {
|
||||
for (let entry of entries) {
|
||||
this.changeHeight();
|
||||
}
|
||||
});
|
||||
this.observer.observe(this.header.nativeElement);
|
||||
}
|
||||
}
|
||||
|
||||
/* Height = Viewport - header - (Body padding) */
|
||||
changeHeight() {
|
||||
if(typeof window !== "undefined" && this.header) {
|
||||
this.bodyHeight = window.innerHeight - this.header.nativeElement.clientHeight - 80;
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if(this.observer && this.observer instanceof ResizeObserver) {
|
||||
this.observer.disconnect();
|
||||
}
|
||||
if(typeof document !== "undefined") {
|
||||
const element = document.getElementById("modal-container");
|
||||
for (let i = element.childNodes.length - 1; i >= 0; --i) {
|
||||
let child: ChildNode = element.childNodes[i];
|
||||
if (child['id'] == this.id) {
|
||||
child.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
get isOpen() {
|
||||
return this.modal && UIkit.modal(this.modal.nativeElement).isToggled();
|
||||
}
|
||||
|
||||
open() {
|
||||
UIkit.modal(this.modal.nativeElement).show();
|
||||
HelperFunctions.scroll();
|
||||
}
|
||||
|
||||
cancel() {
|
||||
UIkit.modal(this.modal.nativeElement).hide();
|
||||
HelperFunctions.scroll();
|
||||
this.cancelEmitter.emit();
|
||||
}
|
||||
|
||||
ok() {
|
||||
UIkit.modal(this.modal.nativeElement).hide();
|
||||
HelperFunctions.scroll();
|
||||
this.okEmitter.emit(true);
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
import {NgModule} from "@angular/core";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {FullScreenModalComponent} from "./full-screen-modal.component";
|
||||
import {IconsModule} from "../../icons/icons.module";
|
||||
|
||||
@NgModule({
|
||||
imports: [CommonModule, IconsModule],
|
||||
declarations: [FullScreenModalComponent],
|
||||
exports: [FullScreenModalComponent]
|
||||
})
|
||||
export class FullScreenModalModule {
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
import {Component, ViewEncapsulation, ComponentRef, ElementRef, Input, EventEmitter, Output} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'modal-loading',
|
||||
template: `
|
||||
<!--uk-modal="center:true"-->
|
||||
<div [class]="(!isOpen)?'uk-modal ':'uk-modal uk-open uk-animation-fade'" [open]="!isOpen" tabindex="-1" role="dialog" >
|
||||
<div class="uk-modal-dialog" role="">
|
||||
<!--div class="modal-content"-->
|
||||
|
||||
<div class="uk-modal-body">
|
||||
<div >
|
||||
<h4 class="text-center" >{{message}}</h4>
|
||||
<!-- <div class="uk-spinner"></div>-->
|
||||
<div class="uk-animation-fade uk-margin-top uk-width-1-1" role="alert">
|
||||
<span class="loading-gif uk-align-center" ></span>
|
||||
</div>
|
||||
<ng-content></ng-content>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!--/div-->
|
||||
</div>
|
||||
<!--div class="uk-modal uk-open" aria-hidden="false" style="display: block; overflow-y: scroll;">
|
||||
<div class="uk-modal-dialog" tabindex="">
|
||||
<div class="uk-modal-spinner"></div>
|
||||
</div>
|
||||
</div-->
|
||||
`,
|
||||
encapsulation: ViewEncapsulation.None,
|
||||
})
|
||||
/**
|
||||
* API to an open alert window.
|
||||
*/
|
||||
export class ModalLoading{
|
||||
|
||||
@Input() public message:string ="Loading";
|
||||
|
||||
/**
|
||||
* if the value is true alert will be visible or else it will be hidden.
|
||||
*/
|
||||
public isOpen:boolean=false;
|
||||
/**
|
||||
* Emitted when a ok button was clicked
|
||||
* or when Ok method is called.
|
||||
*/
|
||||
@Output() public alertOutput:EventEmitter<any> = new EventEmitter();
|
||||
constructor( public _elementRef: ElementRef){}
|
||||
/**
|
||||
* Opens a alert window creating backdrop.
|
||||
*/
|
||||
open(){
|
||||
this.isOpen= true;
|
||||
}
|
||||
|
||||
close(){
|
||||
this.isOpen = false;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import {ModalLoading} from './loading.component';
|
||||
import {ModalModule} from './modal.module';
|
||||
|
||||
//helpers
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule, FormsModule,ModalModule ],
|
||||
declarations: [
|
||||
ModalLoading
|
||||
],
|
||||
exports: [
|
||||
ModalLoading
|
||||
]
|
||||
})
|
||||
export class LoadingModalModule { }
|
|
@ -1,15 +0,0 @@
|
|||
/* common components of modal components */
|
||||
import {NgModule} from '@angular/core';
|
||||
import {Open} from './open.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [],
|
||||
declarations: [
|
||||
Open
|
||||
],
|
||||
exports: [
|
||||
Open
|
||||
]
|
||||
})
|
||||
export class ModalModule {
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import {Directive, Input, HostBinding} from '@angular/core';
|
||||
|
||||
// todo: add animate
|
||||
// todo: add init and on change
|
||||
@Directive({selector: '[open]'})
|
||||
export class Open {
|
||||
@HostBinding('style.display')
|
||||
public display:string;
|
||||
@HostBinding('class.in')
|
||||
@HostBinding('attr.aria-expanded')
|
||||
public isExpanded:boolean = true;
|
||||
|
||||
@Input()
|
||||
public set open(value:boolean) {
|
||||
this.isExpanded = value;
|
||||
this.toggle();
|
||||
}
|
||||
|
||||
public get open():boolean {
|
||||
return this.isExpanded;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
}
|
||||
init() {
|
||||
this.isExpanded = false;
|
||||
this.display = 'none';
|
||||
}
|
||||
toggle() {
|
||||
if (this.isExpanded) {
|
||||
this.hide();
|
||||
} else {
|
||||
this.show();
|
||||
}
|
||||
}
|
||||
|
||||
hide() {
|
||||
this.isExpanded = false;
|
||||
this.display = 'none';
|
||||
if (typeof document !== 'undefined') {
|
||||
let backDrop = document.getElementsByClassName("modal-backdrop");
|
||||
if(backDrop.length>0){
|
||||
document.body.removeChild(backDrop[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
show() {
|
||||
if (typeof document !== 'undefined') {
|
||||
// let backDrop = document.createElement('div');
|
||||
// backDrop.className="modal-backdrop fade in";
|
||||
// document.body.appendChild(backDrop);
|
||||
}
|
||||
this.isExpanded = true;
|
||||
this.display = 'block';
|
||||
}
|
||||
}
|
|
@ -1,455 +0,0 @@
|
|||
import {UrlSegment} from '@angular/router';
|
||||
import {AbstractControl, UntypedFormGroup, ValidationErrors, ValidatorFn, Validators} from "@angular/forms";
|
||||
|
||||
export class Dates {
|
||||
public static yearMin = 1800;
|
||||
public static yearMax = (new Date().getFullYear()) + 10;
|
||||
public static currentYear = (new Date().getFullYear());
|
||||
|
||||
public static isValidYear(yearString, yearMin = this.yearMin, yearMax = this.yearMax) {
|
||||
// First check for the pattern
|
||||
if (!/^\d{4}$/.test(yearString))
|
||||
return false;
|
||||
var year = parseInt(yearString, 10);
|
||||
|
||||
// Check the ranges of month and year
|
||||
return !(year < yearMin || year > yearMax);
|
||||
}
|
||||
|
||||
//format YYYY-MM-DD
|
||||
public static isValidDate(dateString: string) {
|
||||
// First check for the pattern
|
||||
if (!/^\d{4}\-\d{1,2}\-\d{1,2}$/.test(dateString))
|
||||
return false;
|
||||
|
||||
// Parse the date parts to integers
|
||||
var parts = dateString.split("-");
|
||||
var day = parseInt(parts[2], 10);
|
||||
var month = parseInt(parts[1], 10);
|
||||
var year = parseInt(parts[0], 10);
|
||||
if (!this.isValidYear(parts[0])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check the ranges of month and year
|
||||
if (month == 0 || month > 12)
|
||||
return false;
|
||||
|
||||
var monthLength = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
||||
|
||||
// Adjust for leap years
|
||||
if (year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))
|
||||
monthLength[1] = 29;
|
||||
|
||||
// Check the range of the day
|
||||
return day > 0 && day <= monthLength[month - 1];
|
||||
|
||||
}
|
||||
|
||||
public static getDateToday(): Date {
|
||||
var myDate = new Date();
|
||||
return myDate;
|
||||
|
||||
}
|
||||
|
||||
public static getDateToString(myDate: Date): string {
|
||||
var date: string = myDate.getFullYear() + "-";
|
||||
date += ((myDate.getMonth() + 1) < 10) ? "0" + (myDate.getMonth() + 1) : (myDate.getMonth() + 1);
|
||||
date += "-";
|
||||
date += (myDate.getDate() < 10) ? "0" + myDate.getDate() : myDate.getDate();
|
||||
return date;
|
||||
|
||||
}
|
||||
|
||||
public static getDateXMonthsAgo(x: number): Date {
|
||||
var myDate = new Date();
|
||||
myDate.setMonth(myDate.getMonth() - x);
|
||||
return myDate;
|
||||
|
||||
}
|
||||
|
||||
public static getDateXYearsAgo(x: number): Date {
|
||||
var myDate = new Date();
|
||||
myDate.setFullYear(myDate.getFullYear() - x);
|
||||
return myDate;
|
||||
|
||||
}
|
||||
|
||||
public static getDateFromString(date: string): Date {
|
||||
|
||||
var myDate = new Date();
|
||||
myDate.setFullYear(+date.substring(0, 4));
|
||||
myDate.setMonth(((date.length > 5) ? (+date.substring(5, 7) - 1) : (0)));
|
||||
myDate.setDate(((date.length > 8) ? (+date.substring(8, 11)) : (1)));
|
||||
return myDate;
|
||||
|
||||
}
|
||||
|
||||
public static getDate(dateString: string): Date {
|
||||
let date = new Date(dateString);
|
||||
if (Object.prototype.toString.call(date) === "[object Date]") {
|
||||
if (isNaN(date.getTime())) {
|
||||
return null;
|
||||
} else {
|
||||
return date;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static timeSince(date: Date) {
|
||||
|
||||
let seconds = Math.floor((new Date().getTime() - new Date(date).getTime()) / 1000);
|
||||
|
||||
let interval = seconds / (365*24*60*60);
|
||||
|
||||
if (interval > 1) {
|
||||
let years = Math.floor(interval);
|
||||
return (years > 1?(years + ' years ago'):'a year ago');
|
||||
}
|
||||
interval = seconds / (7*24*60*60);
|
||||
if (interval > 1) {
|
||||
let weeks = Math.floor(interval);
|
||||
return (weeks > 1?(weeks + ' weeks ago'):'a week ago');
|
||||
}
|
||||
interval = seconds / (24*60*60);
|
||||
if (interval > 1) {
|
||||
let days = Math.floor(interval);
|
||||
return (days > 1?(days + ' days ago'):'a day ago');
|
||||
}
|
||||
interval = seconds / (60*60);
|
||||
if (interval > 1) {
|
||||
let hours = Math.floor(interval);
|
||||
return (hours > 1?(hours + ' hours ago'):'an hour ago');
|
||||
}
|
||||
interval = seconds / 60;
|
||||
if (interval > 1) {
|
||||
let minutes = Math.floor(interval);
|
||||
return (minutes > 1?(minutes + ' minutes ago'):'a minute ago');
|
||||
}
|
||||
seconds = Math.floor(interval);
|
||||
return (seconds > 1?(seconds + ' seconds ago'):' just now');
|
||||
}
|
||||
}
|
||||
|
||||
export class DOI {
|
||||
|
||||
public static getDOIsFromString(str: string): string[] {
|
||||
return Identifier.getDOIsFromString(str);
|
||||
}
|
||||
|
||||
public static isValidDOI(str: string): boolean {
|
||||
return Identifier.isValidDOI(str);
|
||||
}
|
||||
}
|
||||
|
||||
export class Identifier {
|
||||
class: "doi" | "pmc" | "pmid" | "handle" | "ORCID" | "re3data" = null;
|
||||
id: string;
|
||||
|
||||
public static getDOIsFromString(str: string): string[] {
|
||||
var DOIs: string[] = [];
|
||||
var words: string[] = str.split(" ");
|
||||
|
||||
for (var i = 0; i < words.length; i++) {
|
||||
let id = words[i];
|
||||
if (DOI.isValidDOI(id) ) {
|
||||
id = Identifier.getRawDOIValue(id);
|
||||
if( DOIs.indexOf(id) == -1){
|
||||
DOIs.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return DOIs;
|
||||
}
|
||||
public static getRawDOIValue(id: string): string {
|
||||
if(id.indexOf("doi.org")!=-1 && id.split("doi.org/").length > 1){
|
||||
id = id.split("doi.org/")[1];
|
||||
}
|
||||
return id;
|
||||
}
|
||||
public static getIdentifiersFromString(str: string): Identifier[] {
|
||||
let identifiers: Identifier[] = [];
|
||||
let words: string[] = str.split(" ");
|
||||
|
||||
for (let id of words) {
|
||||
if (id.length > 0) {
|
||||
let identifier: Identifier = this.getIdentifierFromString(id);
|
||||
if (identifier) {
|
||||
identifiers.push(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
public static getIdentifierFromString(pid: string,strict:boolean = true): Identifier {
|
||||
if (Identifier.isValidDOI(pid)) {
|
||||
pid = Identifier.getRawDOIValue(pid);
|
||||
return {"class": "doi", "id": pid};
|
||||
} else if (Identifier.isValidORCID(pid)) {
|
||||
return {"class": "ORCID", "id": pid};
|
||||
} else if (Identifier.isValidPMCID(pid)) {
|
||||
return {"class": "pmc", "id": pid};
|
||||
} else if (Identifier.isValidPMID(pid)) {
|
||||
return {"class": "pmid", "id": pid};
|
||||
} else if (Identifier.isValidHANDLE(pid)) {
|
||||
return {"class": "handle", "id": pid};
|
||||
} else if (Identifier.isValidRe3Data(pid)) {
|
||||
return {"class": "re3data", "id": pid};
|
||||
}
|
||||
//set it as a doi, to catch the case that doi has not valid format
|
||||
return (strict?null:{"class": "doi", "id": pid});
|
||||
}
|
||||
|
||||
public static getPIDFromIdentifiers(identifiers: Map<string, string[]>): Identifier {
|
||||
let classes:string [] = ["doi", "handle", "pmc", "pmid", "re3data"];
|
||||
if(identifiers) {
|
||||
for (let cl of classes) {
|
||||
if (identifiers.get(cl)) {
|
||||
for (let pid of identifiers.get(cl)) {
|
||||
let identifier = Identifier.getIdentifierFromString(pid);
|
||||
if (identifier) {
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static isValidDOI(str: string): boolean {
|
||||
//keep only exp3?
|
||||
let exp1 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])\S)+)\b/g;
|
||||
let exp2 = /\b(10[.][0-9]{4,}(?:[.][0-9]+)*\/(?:(?!["&\'<>])[[:graph:]])+)\b/g;
|
||||
let exp3 = /\b(10[.]*)\b/g;
|
||||
return (str.match(exp1) != null || str.match(exp2) != null || str.match(exp3) != null);
|
||||
}
|
||||
|
||||
public static isValidORCID(str: string): boolean {
|
||||
let exp = /\b\d{4}-\d{4}-\d{4}-(\d{3}X|\d{4})\b/g;
|
||||
return str.match(exp) != null;
|
||||
}
|
||||
|
||||
public static isValidPMID(str: string): boolean {
|
||||
let exp = /^\d*$/g;
|
||||
return str.match(exp) != null;
|
||||
|
||||
}
|
||||
|
||||
public static isValidPMCID(str: string): boolean {
|
||||
let exp = /^(PMC\d{7})$/g;
|
||||
return str.match(exp) != null;
|
||||
}
|
||||
|
||||
public static isValidHANDLE(str: string): boolean {
|
||||
let exp = /^[0-9a-zA-Z-]*\/[0-9a-zA-Z-]*$/g;
|
||||
return str.match(exp) != null;
|
||||
}
|
||||
|
||||
public static isValidRe3Data(str: string): boolean {
|
||||
let exp = /(r3d[1-9]\d{0,8})/g;
|
||||
return str.match(exp) != null;
|
||||
}
|
||||
}
|
||||
|
||||
export class StringUtils {
|
||||
|
||||
public static urlRegex = 'https?:\\/\\/(?:www(2?)\\.|(?!www(2?)))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www(2?)\\.' +
|
||||
'[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?:\\/\\/(?:www(2?)\\.|(?!www(2?)))[a-zA-Z0-9]+\\.[^\\s]{2,}|www(2?)\\.' +
|
||||
'[a-zA-Z0-9]+\\.[^\\s]{2,}';
|
||||
|
||||
public static routeRegex = '^[a-zA-Z0-9\/][a-zA-Z0-9\/-]*$';
|
||||
|
||||
public static jsonRegex = /^[\],:{}\s]*$/;
|
||||
|
||||
public static urlPrefix(url: string): string {
|
||||
if (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//")) {
|
||||
return "";
|
||||
} else {
|
||||
return "//";
|
||||
}
|
||||
}
|
||||
|
||||
public static quote(params: string): string {
|
||||
return '"' + params + '"';
|
||||
}
|
||||
|
||||
public static unquote(params: string): string {
|
||||
if (params.length > 2 && (params[0] == '"' && params[params.length - 1] == '"') || (params[0] == "'" && params[params.length - 1] == "'")) {
|
||||
params = params.substring(1, params.length - 1);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
public static URIEncode(params: string): string {
|
||||
return encodeURIComponent(params);
|
||||
}
|
||||
|
||||
public static URIDecode(params: string): string {
|
||||
return decodeURIComponent(params);
|
||||
}
|
||||
|
||||
public static validateEmails(emails: string): boolean {
|
||||
return (emails.split(',')
|
||||
.map(email => Validators.email(<AbstractControl>{value: email.trim()}))
|
||||
.find(_ => _ !== null) === undefined);
|
||||
}
|
||||
|
||||
public static b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(Array.prototype.map.call(atob(str), function (c) {
|
||||
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||
}).join(''));
|
||||
}
|
||||
|
||||
private emailValidator(email: any): boolean {
|
||||
return !!email.match("^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$");
|
||||
}
|
||||
|
||||
public static isValidUrl(url: string): boolean {
|
||||
return new RegExp(this.urlRegex).test(url);
|
||||
}
|
||||
|
||||
public static urlValidator(): ValidatorFn {
|
||||
return Validators.pattern(StringUtils.urlRegex);
|
||||
}
|
||||
|
||||
public static jsonValidator(error: string = ''): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
if(control.value) {
|
||||
let test = control.getRawValue().replace(/\\["\\\/bfnrtu]/g, '@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').replace(/(?:^|:|,)(?:\s*\[)+/g, '');
|
||||
if(!new RegExp(this.jsonRegex).test(test)) {
|
||||
return {error: 'Please provide a valid JSON.' + error}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public static validatorType(options: string[]): ValidatorFn {
|
||||
return (control: AbstractControl): { [key: string]: boolean } | null => {
|
||||
if (options.filter(type => type === control.value).length === 0) {
|
||||
return {'type': false};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static validRoute(pages: any[], field: string, initial: string = null): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
if(control.value) {
|
||||
if(!new RegExp(this.routeRegex).test(control.value)) {
|
||||
return {error: 'Route should contain only letters or numbers, e.g /route or route'}
|
||||
}
|
||||
if(pages && pages.length > 0 && control.value !== initial) {
|
||||
const forbidden = pages.filter(page => page[field].replace('/', '') === control.value.replace('/', '')).length > 0;
|
||||
return forbidden ? {error: 'This route is used by an other page'} : null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
public static sliceString(mystr, size: number): string {
|
||||
const sliced = String(mystr).substr(0, size);
|
||||
return sliced + (String(mystr).length > size ? '...' : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits a text to words base on a list of separators. Returns the words of the text including the separators.
|
||||
* DO NOT TOUCH, IT WORKS
|
||||
*
|
||||
* @param text
|
||||
* @param separators
|
||||
*/
|
||||
public static split(text: string, separators: string[]): string[] {
|
||||
let words: (string | string[])[] = [text];
|
||||
separators.forEach(separator => {
|
||||
words.forEach((word, index) => {
|
||||
if (typeof word === "string" && separators.indexOf(word) === -1) {
|
||||
let tokens: string[] = word.split(separator).filter(value => value !== '');
|
||||
if (tokens.length > 1) {
|
||||
words[index] = [];
|
||||
tokens.forEach((token, i) => {
|
||||
(<string[]>(words[index])).push(token);
|
||||
if (i !== (tokens.length - 1)) {
|
||||
(<string[]>(words[index])).push(separator);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
words = [].concat.apply([], words);
|
||||
});
|
||||
return <string []>words;
|
||||
}
|
||||
|
||||
public static capitalize(value: string): string {
|
||||
return value.charAt(0).toUpperCase() + value.slice(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a text contains a word
|
||||
*/
|
||||
public static containsWord(text: string, word: string): boolean {
|
||||
return (text && text.toLowerCase().includes(word));
|
||||
}
|
||||
|
||||
public static URLSegmentsToPath(segments: UrlSegment[]): string {
|
||||
let path = '';
|
||||
segments.forEach(route => {
|
||||
path += '/' + route.path;
|
||||
})
|
||||
return path;
|
||||
}
|
||||
|
||||
public static isEuropeanCountry(country: string) {
|
||||
let countries = ["Albania", "Andorra", "Armenia", "Austria", "Azerbaijan", "Belarus", "Belgium", "Bosnia and Herzegovina",
|
||||
"Bulgaria", "Croatia", "Cyprus", "Czech Republic", "Denmark", "Estonia", "Finland", "France", "Georgia", "Germany", "Greece", "Hungary", "Iceland", "Ireland",
|
||||
"Italy", "Kosovo", "Latvia", "Liechtenstein", "Lithuania", "Luxembourg", "Macedonia", "Malta", "Moldova", "Monaco", "Montenegro", "The Netherlands", "Norway", "Poland",
|
||||
"Portugal", "Romania", "Russia", "San Marino", "Serbia", "Slovakia", "Slovenia", "Spain", "Sweden", "Switzerland", "Turkey", "Ukraine", "United Kingdom", "Vatican City",
|
||||
];
|
||||
return (country && countries.indexOf(country) != -1);
|
||||
}
|
||||
|
||||
public static isOpenAIREID(id: string) {
|
||||
if (id && id.length == 46) {
|
||||
let exp1 = /^.{12}::([0-9a-z]{32})$/g;
|
||||
return (id.match(exp1) != null);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public static HTMLToString( html:string){
|
||||
try {
|
||||
html = html.replace(/ /g, ' ');
|
||||
html = html.replace(/(\r\n|\n|\r| +(?= ))|\s\s+/gm, " ");
|
||||
html = html.replace(/<[^>]*>/g, '');
|
||||
}catch( e){
|
||||
}
|
||||
return html;
|
||||
}
|
||||
|
||||
public static inValidYearValidator(minYear, maxYear): ValidatorFn {
|
||||
return (control: AbstractControl): {[key: string]: any} | null => {
|
||||
return ((control.value && !Dates.isValidYear(control.value, minYear, maxYear)) ?
|
||||
{error: 'Year must be between ' + minYear + ' and ' + maxYear + '.'} : null);
|
||||
};
|
||||
}
|
||||
|
||||
public static fromYearAfterToYearValidator: ValidatorFn = (control: UntypedFormGroup): ValidationErrors | null => {
|
||||
const yearFrom = control.get('yearFrom');
|
||||
const yearTo = control.get('yearTo');
|
||||
return ((yearFrom && yearTo && (parseInt(yearFrom.value, 10) > parseInt(yearTo.value, 10))) ?
|
||||
{error: 'Starting year must be greater than or equal to ending year.' } : null);
|
||||
}
|
||||
|
||||
public static rangeRequired( enabled:boolean): ValidatorFn {
|
||||
return (control: AbstractControl): ValidationErrors | null => {
|
||||
const yearFrom = control.get('yearFrom');
|
||||
const yearTo = control.get('yearTo');
|
||||
return ((yearFrom && yearTo && enabled && (yearFrom.value == "" || yearTo.value == "")) ? { error: 'Both starting and ending year are required' } : null);
|
||||
};
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue