UNPKG

@js-sugar/angular

Version:

JS-Sugar core package (Angular)

1 lines 122 kB
{"version":3,"file":"js-sugar-angular.mjs","sources":["../../../projects/angular/src/lib/components/collapse/collapse.directive.ts","../../../projects/angular/src/lib/components/collapse/collapse.module.ts","../../../projects/angular/src/lib/components/panels/panel-backdrop.component.ts","../../../projects/angular/src/lib/components/panels/animation.ts","../../../projects/angular/src/lib/components/panels/panel.component.ts","../../../projects/angular/src/lib/components/panels/panel.component.html","../../../projects/angular/src/lib/components/panels/panels.component.ts","../../../projects/angular/src/lib/components/panels/panels.component.html","../../../projects/angular/src/lib/components/panels/panels.module.ts","../../../projects/angular/src/lib/components/menu/divider-menu-item-template.directive.ts","../../../projects/angular/src/lib/components/menu/group-menu-item-template.directive.ts","../../../projects/angular/src/lib/components/menu/text-menu-item-template.directive.ts","../../../projects/angular/src/lib/security/user/user.ts","../../../projects/angular/src/lib/security/user/user-store.ts","../../../projects/angular/src/lib/security/show-permission.directive.ts","../../../projects/angular/src/lib/security/show.directive.ts","../../../projects/angular/src/lib/security/security.module.ts","../../../projects/angular/src/lib/components/menu/menu.component.ts","../../../projects/angular/src/lib/components/menu/menu.component.html","../../../projects/angular/src/lib/components/menu/menu.module.ts","../../../projects/angular/src/lib/components/overlay/overlay.directive.ts","../../../projects/angular/src/lib/components/overlay/cdk-overlay.service.ts","../../../projects/angular/src/lib/components/overlay/overlay.module.ts","../../../projects/angular/src/lib/configuration/types.ts","../../../projects/angular/src/lib/form/validation/error.directive.ts","../../../projects/angular/src/lib/localization/locale.ts","../../../projects/angular/src/lib/localization/locales/en-us.ts","../../../projects/angular/src/lib/localization/locale-provider.ts","../../../projects/angular/src/lib/localization/types.ts","../../../projects/angular/src/lib/localization/translate.pipe.ts","../../../projects/angular/src/lib/localization/localization.module.ts","../../../projects/angular/src/lib/form/validation/first-error.directive.ts","../../../projects/angular/src/lib/form/validation/validators/equal-with/equal-with-validator.ts","../../../projects/angular/src/lib/form/validation/validators/equal-with/equal-with.directive.ts","../../../projects/angular/src/lib/form/validation/validators/max/max-validator.directive.ts","../../../projects/angular/src/lib/form/validation/validators/min/min-validator.directive.ts","../../../projects/angular/src/lib/form/validation/validators/password/password-validator.ts","../../../projects/angular/src/lib/form/validation/validators/password/password-validator.directive.ts","../../../projects/angular/src/lib/form/validation/validation.module.ts","../../../projects/angular/src/lib/http/types.ts","../../../projects/angular/src/lib/http/http.service.ts","../../../projects/angular/src/lib/layout/common/menu-types.ts","../../../projects/angular/src/lib/routing/types.ts","../../../projects/angular/src/lib/routing/router-service.ts","../../../projects/angular/src/lib/routing/router-utils.module.ts"],"sourcesContent":["import { Directive, Input, OnInit, ElementRef, Renderer2, OnDestroy, OnChanges, SimpleChanges } from '@angular/core';\r\nimport { animate, AnimationBuilder, AnimationMetadata, AnimationPlayer, style } from '@angular/animations';\r\n\r\n@Directive({\r\n selector: '[jssCollapse]',\r\n exportAs: 'jssCollapse',\r\n})\r\nexport class CollapseDirective implements OnInit, OnDestroy, OnChanges {\r\n /** Animation timing */\r\n @Input() timing: string | number = '100ms ease-in';\r\n /** Collapse state */\r\n @Input('jssCollapse') collapsed = false;\r\n private _player?: AnimationPlayer;\r\n\r\n constructor(\r\n private _el: ElementRef,\r\n private _builder: AnimationBuilder,\r\n _renderer: Renderer2) {\r\n _renderer.setStyle(_el.nativeElement, 'overflow-y', 'hidden');\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if(changes['collapsed']?.firstChange === false) {\r\n this._collapseElement(this.collapsed)\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n this._collapseElement(this.collapsed, 0)\r\n }\r\n\r\n private _collapseElement(collapse: boolean, timing?: string | number) {\r\n timing = timing != undefined ? timing : this.timing;\r\n const expandMeta: AnimationMetadata[] = [\r\n style({ height: 0 }),\r\n animate(timing, style({ height: '*' })),\r\n ];\r\n\r\n const collapseMeta: AnimationMetadata[] = [\r\n style({ height: '*' }),\r\n animate(timing, style({ height: 0 })),\r\n ];\r\n\r\n if (this._player) {\r\n this._player.destroy();\r\n }\r\n\r\n this._player = this._builder.build(collapse ? collapseMeta : expandMeta).create(this._el.nativeElement);\r\n this._player.play();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._player?.destroy();\r\n }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { CollapseDirective } from './collapse.directive';\r\n\r\n@NgModule({\r\n declarations: [\r\n CollapseDirective,\r\n ],\r\n imports: [\r\n CommonModule\r\n ],\r\n exports: [\r\n CollapseDirective,\r\n ]\r\n})\r\nexport class CollapseModule {\r\n}\r\n","import { Component, ElementRef} from '@angular/core';\r\n\r\n@Component({\r\n selector: 'jss-panel-backdrop',\r\n exportAs: 'jssPanelBackdrop',\r\n styleUrls: ['./panel-backdrop.component.scss'],\r\n template: ''\r\n})\r\nexport class PanelBackdropComponent {\r\n constructor(public elementRef: ElementRef) {\r\n }\r\n}\r\n","import { animate } from \"@angular/animations\";\r\n\r\nexport const SIDENAV_ANIMATE = animate('.15s cubic-bezier(.7,.3,.1,1)');","import {\r\n Input, Component, Output, EventEmitter, Renderer2, ElementRef, ComponentFactoryResolver,\r\n ViewContainerRef, OnDestroy, HostBinding, OnChanges, SimpleChanges\r\n} from '@angular/core';\r\nimport { PanelBackdropComponent } from './panel-backdrop.component';\r\nimport { PanelPlacement, PanelPosition, PanelStretch } from './types';\r\nimport { trigger, state, style, transition } from '@angular/animations';\r\nimport { Directionality } from '@angular/cdk/bidi';\r\nimport { SIDENAV_ANIMATE } from './animation';\r\nimport { PanelsComponent } from './panels.component';\r\n\r\n@Component({\r\n selector: 'jss-panel',\r\n exportAs: 'jssPanel',\r\n styleUrls: ['./panel.component.scss'],\r\n templateUrl: 'panel.component.html',\r\n animations: [\r\n trigger('t', [\r\n state('0', style({\r\n left: '{{left}}',\r\n right: '{{right}}',\r\n top: '{{top}}',\r\n bottom: '{{bottom}}',\r\n transform: '{{transform}}'\r\n }), { params: { left: '', right: '', top: '', bottom: '', transform: '' } }),\r\n state('1', style({\r\n left: '{{left}}',\r\n right: '{{right}}',\r\n top: '{{top}}',\r\n bottom: '{{bottom}}',\r\n transform: '{{transform}}'\r\n }), { params: { left: '', right: '', top: '', bottom: '', transform: '' } }),\r\n transition('0 <=> 1', [\r\n SIDENAV_ANIMATE,\r\n ])\r\n ]),\r\n ]\r\n})\r\nexport class PanelComponent implements OnChanges, OnDestroy {\r\n private _backdrop = false;\r\n private _backdropUnlistenFunc?: () => void;\r\n private _animationState = false;\r\n @Input() position: PanelPosition = 'start';\r\n @Input() placement: PanelPlacement = 'container';\r\n @Input() stretch: PanelStretch = 'both';\r\n @Input() show = true;\r\n @Input() size = 200;\r\n @Input() over = true;\r\n @Input() zOrder = 1;\r\n @Input() set backdrop(value: boolean) {\r\n if (value === this._backdrop) { return; }\r\n if (value) {\r\n const compRef = this._viewRef.createComponent<PanelBackdropComponent>(PanelBackdropComponent);\r\n this._renderer.setStyle(compRef.instance.elementRef.nativeElement, 'z-index', this.zOrder * 2 - 1);\r\n this._backdropUnlistenFunc = this._renderer.listen(compRef.instance.elementRef.nativeElement, 'click', (e) => {\r\n this.backdropClick.emit(this);\r\n });\r\n } else {\r\n this._viewRef.clear();\r\n }\r\n this._backdrop = value;\r\n }\r\n\r\n get backdrop(): boolean {\r\n return this._backdrop;\r\n }\r\n \r\n @Output() backdropClick = new EventEmitter<PanelComponent>();\r\n\r\n constructor(\r\n public elementRef: ElementRef,\r\n private _parent: PanelsComponent,\r\n private _renderer: Renderer2,\r\n private _viewRef: ViewContainerRef,\r\n private _dir: Directionality,\r\n ) {\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n const change = changes['position'] || changes['stretch'] || changes['size'] || changes['show'] || changes['over'];\r\n if (change && !change.isFirstChange()) {\r\n this._parent.refresh();\r\n this._animationState = !this._animationState;\r\n }\r\n }\r\n\r\n @HostBinding('style.z-index') private get _zIndex() {\r\n return this.zOrder * 2;\r\n }\r\n\r\n @HostBinding('style.position') private get _position() {\r\n return this.placement === 'container' ? 'absolute' : 'fixed';\r\n }\r\n\r\n @HostBinding('@t') private get _animationTrigger() {\r\n const ltr = this._dir.value === 'ltr';\r\n const contentPos = this._parent.contentPosition;\r\n const isStretchNoneOrStart = this.stretch === 'none' || this.stretch === 'start';\r\n const isStretchNone = this.stretch === 'none';\r\n const isStretchStart = this.stretch === 'start';\r\n const isStretchEnd = this.stretch === 'end';\r\n const isStretchNoneOrEnd = isStretchNone || isStretchEnd;\r\n const isStretchBoth = this.stretch === 'both';\r\n let params: { top: string, bottom: string, left: string, right: string, hideTransform: string };\r\n\r\n switch (this.position) {\r\n case 'start':\r\n params = {\r\n top: isStretchNoneOrEnd ? `${contentPos?.top}px` : '0',\r\n bottom: isStretchNoneOrStart ? `${contentPos?.bottom}px` : '0',\r\n left: ltr ? '0' : '',\r\n right: ltr ? '' : '0',\r\n hideTransform: `translateX(${ltr ? -100 : 100}%)`,\r\n };\r\n break;\r\n case 'end':\r\n params = {\r\n top: isStretchNoneOrEnd ? `${contentPos?.top}px` : '0',\r\n bottom: isStretchNoneOrStart ? `${contentPos?.bottom}px` : '0',\r\n left: ltr ? '' : '0',\r\n right: ltr ? '0' : '',\r\n hideTransform: `translateX(${ltr ? 100 : -100}%)`,\r\n };\r\n break;\r\n case 'top':\r\n params = {\r\n top: '0',\r\n bottom: '',\r\n left: isStretchBoth || (isStretchStart && ltr) || (isStretchEnd && !ltr) ? '0' : `${contentPos?.left}px`,\r\n right: isStretchBoth || (isStretchEnd && ltr) || (isStretchStart && !ltr) ? '0' : `${contentPos?.right}px`,\r\n hideTransform: 'translateY(-100%)',\r\n };\r\n break;\r\n case 'bottom':\r\n params = {\r\n top: '',\r\n bottom: '0',\r\n left: isStretchBoth || (isStretchStart && ltr) || (isStretchEnd && !ltr) ? '0' : `${contentPos?.left}px`,\r\n right: isStretchBoth || (isStretchEnd && ltr) || (isStretchStart && !ltr) ? '0' : `${contentPos?.right}px`,\r\n hideTransform: 'translateY(100%)',\r\n };\r\n break;\r\n default:\r\n throw Error('Invalid position');\r\n }\r\n\r\n return {\r\n value: this._animationState,\r\n params: {\r\n ...params,\r\n transform: this.show ? 'translate(0,0)' : params.hideTransform,\r\n }\r\n };\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this._backdropUnlistenFunc) {\r\n this._backdropUnlistenFunc();\r\n }\r\n }\r\n}\r\n","<ng-content></ng-content>","import { Directionality } from '@angular/cdk/bidi';\r\nimport { isPlatformBrowser } from '@angular/common';\r\nimport {\r\n AfterContentInit, Component, ContentChildren, EventEmitter, Inject, Input, Output, PLATFORM_ID, QueryList\r\n} from '@angular/core';\r\nimport { PanelPosition, PanelsContentPosition } from './types';\r\nimport { PanelComponent } from './panel.component';\r\nimport { state, style, transition, trigger } from '@angular/animations';\r\nimport { SIDENAV_ANIMATE } from './animation';\r\n\r\n@Component({\r\n selector: 'jss-panels',\r\n exportAs: 'jssPanels',\r\n templateUrl: './panels.component.html',\r\n styleUrls: ['./panels.component.scss'],\r\n animations: [\r\n trigger('t', [\r\n state('0', style({\r\n padding: '{{padding}}',\r\n height: '100%'\r\n }), { params: { padding: '' } }),\r\n state('1', style({\r\n padding: '{{padding}}',\r\n height: '100%'\r\n }), { params: { padding: '' } }),\r\n transition('0 <=> 1', [\r\n SIDENAV_ANIMATE,\r\n ])\r\n ]),\r\n ]\r\n})\r\nexport class PanelsComponent implements AfterContentInit {\r\n @Output() layoutChange = new EventEmitter<PanelsContentPosition>();\r\n @ContentChildren(PanelComponent) private _panels!: QueryList<PanelComponent>;\r\n private _isBrowser: boolean;\r\n private _isRtl: boolean;\r\n private _animationState = false;\r\n private _contentPosition: PanelsContentPosition = { top: 0, bottom: 0, left: 0, right: 0 };\r\n public get contentPosition(): PanelsContentPosition {\r\n return this._contentPosition;\r\n }\r\n\r\n constructor(\r\n private _dir: Directionality,\r\n @Inject(PLATFORM_ID) _platformId: any) {\r\n\r\n this._isBrowser = isPlatformBrowser(_platformId);\r\n this._isRtl = this._dir.value === 'rtl';\r\n }\r\n\r\n ngAfterContentInit(): void {\r\n this.refresh();\r\n }\r\n\r\n public refresh() {\r\n this.computeContentPosition();\r\n this._animationState = !this._animationState;\r\n }\r\n\r\n private computeContentPosition() {\r\n if (this._isBrowser) {\r\n const fixedPanels = this._panels.filter(p => p.show && !p.over);\r\n const max = (items: number[]) => items.length === 0 ? 0 : Math.max(...items);\r\n const getPositionSizes = (position: PanelPosition): number[] => fixedPanels\r\n .filter(p => p.position === position)\r\n .map(p => position === 'start' || position === 'end' ? p.elementRef.nativeElement.clientWidth : p.elementRef.nativeElement.clientHeight);\r\n\r\n const positions: PanelPosition[] = ['start', 'end', 'top', 'bottom'];\r\n var paddings = positions.map(pos => max(getPositionSizes(pos)));\r\n this._contentPosition = {\r\n left: this._isRtl ? paddings[1] : paddings[0],\r\n right: this._isRtl ? paddings[0] : paddings[1],\r\n top: paddings[2],\r\n bottom: paddings[3],\r\n };\r\n } else {\r\n this._contentPosition = { top: 0, right: 0, bottom: 0, left: 0 };\r\n }\r\n }\r\n\r\n get _animationTrigger() {\r\n const { bottom, left, top, right } = this._contentPosition;\r\n return {\r\n value: this._animationState,\r\n params: {\r\n padding: `${top}px ${right}px ${bottom}px ${left}px`,\r\n }\r\n };\r\n }\r\n}\r\n","<ng-content select=\"jss-panel\"></ng-content>\r\n<div class=\"jss-panels-content\" [@t]=\"_animationTrigger\">\r\n <ng-content></ng-content>\r\n</div>","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { PanelsComponent } from './panels.component';\r\nimport { PanelComponent } from './panel.component';\r\nimport { BidiModule } from '@angular/cdk/bidi';\r\nimport { PanelBackdropComponent } from './panel-backdrop.component';\r\n\r\n@NgModule({\r\n declarations: [\r\n PanelComponent,\r\n PanelsComponent\r\n ],\r\n imports: [\r\n CommonModule,\r\n BidiModule\r\n ],\r\n exports: [\r\n PanelComponent,\r\n PanelsComponent,\r\n ],\r\n entryComponents: [\r\n PanelBackdropComponent\r\n ]\r\n})\r\nexport class PanelsModule { }\r\n","import { Directive, TemplateRef } from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[jssDividerMenuItemTemplate]',\r\n exportAs: 'jssDividerMenuItemTemplate',\r\n})\r\nexport class DividerMenuItemTemplateDirective {\r\n constructor(public readonly templateRef: TemplateRef<any>) {\r\n }\r\n}\r\n","import { Directive, TemplateRef } from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[jssGroupMenuItemTemplate]',\r\n exportAs: 'jssGroupMenuItemTemplate',\r\n})\r\nexport class GroupMenuItemTemplateDirective {\r\n constructor(public readonly templateRef: TemplateRef<any>) {\r\n }\r\n}\r\n","import { Directive, TemplateRef } from '@angular/core';\r\n\r\n@Directive({\r\n selector: '[jssTextMenuItemTemplate]',\r\n exportAs: 'jssTextMenuItemTemplate',\r\n})\r\nexport class TextMenuItemTemplateDirective {\r\n constructor(public readonly templateRef: TemplateRef<any>) {\r\n }\r\n}\r\n","import { PermissionCriteria } from '../types';\r\n\r\n/** User Identity (Immutable) */\r\nexport class User {\r\n private readonly _permissions = new Array<string>();\r\n\r\n get permissions(): readonly string[] {\r\n return [...this._permissions];\r\n }\r\n\r\n constructor(permissions?: readonly string[]) {\r\n if (Array.isArray(permissions)) {\r\n this._permissions = [...permissions];\r\n }\r\n }\r\n\r\n /** hasAllPermissions */\r\n public hasAllPermissions(permissions: readonly string[]): boolean {\r\n return permissions.every(x => this._permissions.some(y => x === y));\r\n }\r\n\r\n /** hasAnyPermission */\r\n public hasAnyPermission(permissions: readonly string[]): boolean {\r\n return permissions.length == 0 || permissions.some(x => this._permissions.some(y => x === y));\r\n }\r\n\r\n public hasPermission(criteria: PermissionCriteria): boolean {\r\n if (typeof criteria === 'string') {\r\n return this._permissions.some(x => x === criteria);\r\n }\r\n\r\n if (typeof criteria === 'object' && criteria?.any && criteria?.all) {\r\n throw Error('Setting \"any\" and \"all\" at the same time is not valid.');\r\n }\r\n if (Array.isArray(criteria?.any)) {\r\n return this.hasAnyPermission(criteria.any);\r\n }\r\n if (Array.isArray(criteria?.all)) {\r\n return this.hasAllPermissions(criteria.all);\r\n }\r\n\r\n throw Error('Invalid criteria');\r\n }\r\n\r\n // /** toJson */\r\n // public toJson() {\r\n // return JSON.stringify({ permissions: this._permissions, data: this.data });\r\n // }\r\n\r\n // /** fromJson */\r\n // public static fromJson<DataType = any>(text: string): UserIdentity<DataType> {\r\n // var obj = JSON.parse(text);\r\n // const permissions: string[] = obj['permissions'];\r\n // const data: DataType = obj['data'];\r\n // if (!Array.isArray(permissions)) {\r\n // throw Error('Invalid UserIdentity JSON.');\r\n // }\r\n\r\n // return new UserIdentity<DataType>(permissions, data);\r\n // }\r\n}\r\n\r\n","import { Subject } from 'rxjs';\r\nimport { User } from './user';\r\n\r\nexport class UserStore<U extends User = any> {\r\n private _user?: U;\r\n private _userSubject = new Subject<U | undefined>();\r\n\r\n /** An observable that emmits whenever \"user\" property changes . */\r\n readonly change = this._userSubject.asObservable();\r\n\r\n constructor() {\r\n }\r\n\r\n /** Gets the User. */\r\n public get user(): U | undefined {\r\n return this._user;\r\n }\r\n\r\n /** Sets the User. */\r\n public setUser(user: U | undefined): void {\r\n if (user === undefined || user instanceof User) {\r\n this._user = user;\r\n this._userSubject.next(user!);\r\n return;\r\n }\r\n\r\n throw Error('Invalid User.');\r\n }\r\n}","import { Directive, TemplateRef, ViewContainerRef, Input, Inject, Optional } from '@angular/core';\r\nimport { PermissionCriteria } from './types';\r\nimport { User } from './user/user';\r\nimport { UserStore } from './user/user-store';\r\n\r\n@Directive({\r\n selector: '[jssShowPermission]',\r\n exportAs: 'jssShowPermission',\r\n})\r\nexport class ShowPermissionDirective {\r\n private _viewCreated = false;\r\n\r\n constructor(\r\n private templateRef: TemplateRef<any>,\r\n private viewContainer: ViewContainerRef,\r\n @Optional() private userStore?: UserStore<User>,\r\n ) {\r\n }\r\n\r\n @Input('jssShowPermission') set showPermission(value: PermissionCriteria) {\r\n let granted: boolean;\r\n const user = this.userStore?.user;\r\n\r\n if (value == null) {\r\n granted = true;\r\n } else if (user == undefined) {\r\n granted = false;\r\n } else {\r\n granted = user.hasPermission(value);\r\n }\r\n\r\n this._show(granted);\r\n }\r\n\r\n private _show(show: boolean): void {\r\n if (show && !this._viewCreated) {\r\n this.viewContainer.createEmbeddedView(this.templateRef);\r\n this._viewCreated = true;\r\n } else if (!show && this._viewCreated) {\r\n this.viewContainer.clear();\r\n this._viewCreated = false;\r\n }\r\n }\r\n}\r\n","import { Directive, TemplateRef, ViewContainerRef, Input, OnDestroy, Optional, Inject } from '@angular/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { ShowCondition } from './types';\r\nimport { User } from './user/user';\r\nimport { UserStore } from './user/user-store';\r\n\r\n@Directive({\r\n selector: '[jssShow]',\r\n exportAs: 'jssShow',\r\n})\r\nexport class ShowDirective implements OnDestroy {\r\n private _viewCreated = false;\r\n private _condition!: ShowCondition;\r\n private _subscription?: Subscription;\r\n\r\n constructor(\r\n private templateRef: TemplateRef<any>,\r\n private viewContainer: ViewContainerRef,\r\n @Optional() private userStore?: UserStore<User>,\r\n ) {\r\n this._subscription = userStore?.change.subscribe(x => this._decide());\r\n }\r\n\r\n @Input('jssShow') set show(value: ShowCondition) {\r\n this._condition = value;\r\n this._decide();\r\n }\r\n\r\n private _decide() {\r\n let show: boolean;\r\n const user = this.userStore?.user;\r\n const { user: userCondition, permission } = this._condition;\r\n\r\n if (userCondition === 'any') {\r\n show = true\r\n } else if (userCondition === 'set') {\r\n if (user == undefined) {\r\n show = false;\r\n } else if (permission == undefined) {\r\n show = true;\r\n } else {\r\n show = user.hasPermission(permission);\r\n }\r\n } else {\r\n show = user == undefined;\r\n }\r\n\r\n if (show && !this._viewCreated) {\r\n this.viewContainer.createEmbeddedView(this.templateRef);\r\n this._viewCreated = true;\r\n } else if (!show && this._viewCreated) {\r\n this.viewContainer.clear();\r\n this._viewCreated = false;\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._subscription?.unsubscribe();\r\n }\r\n}\r\n","import { NgModule, Inject } from '@angular/core';\r\nimport { ShowPermissionDirective } from './show-permission.directive';\r\nimport { ShowDirective } from './show.directive';\r\n\r\n@NgModule({\r\n declarations: [\r\n ShowPermissionDirective,\r\n ShowDirective\r\n ],\r\n providers: [\r\n ],\r\n exports: [\r\n ShowPermissionDirective,\r\n ShowDirective\r\n ]\r\n})\r\nexport class SecurityModule {\r\n}\r\n","import { animate, state, style, transition, trigger } from '@angular/animations';\r\nimport { Component, ContentChild, EventEmitter, Input, Optional, Output } from '@angular/core';\r\nimport { GroupMenuItem, MenuItem, TextMenuItem } from '../../layout';\r\nimport { User, UserStore } from '../../security';\r\nimport { DividerMenuItemTemplateDirective } from './divider-menu-item-template.directive';\r\nimport { GroupMenuItemTemplateDirective } from './group-menu-item-template.directive';\r\nimport { TextMenuItemTemplateDirective } from './text-menu-item-template.directive';\r\nimport { MenuItemClickEvent } from './types';\r\n\r\n@Component({\r\n selector: 'jss-menu',\r\n exportAs: 'jssMenu',\r\n templateUrl: 'menu.component.html',\r\n styleUrls: ['./menu.component.scss'],\r\n animations: [\r\n trigger('t', [\r\n state('0', style({\r\n height: '0',\r\n })),\r\n state('1', style({\r\n height: '*',\r\n })),\r\n transition('0 <=> 1', [\r\n animate('.15s cubic-bezier(.7,.3,.1,1)'),\r\n ])\r\n ]),\r\n ]\r\n})\r\nexport class MenuComponent {\r\n @Input() items!: MenuItem[];\r\n @Output() itemClick = new EventEmitter<MenuItemClickEvent>();\r\n @ContentChild(TextMenuItemTemplateDirective) _textTemplate?: TextMenuItemTemplateDirective;\r\n @ContentChild(GroupMenuItemTemplateDirective) _groupTemplate?: GroupMenuItemTemplateDirective;\r\n @ContentChild(DividerMenuItemTemplateDirective) _dividerTemplate?: DividerMenuItemTemplateDirective;\r\n private _expansionStates = new Map<GroupMenuItem, boolean>();\r\n\r\n constructor(@Optional() private _identityManager?: UserStore<User>) { }\r\n\r\n _onTextMenuItemClick(item: TextMenuItem, e: MouseEvent) {\r\n e.stopPropagation();\r\n if (!item.disabled) {\r\n this.itemClick.emit({ item, mouseEvent: e });\r\n }\r\n }\r\n\r\n _onGroupMenuItemClick(item: GroupMenuItem, e: MouseEvent) {\r\n e.stopPropagation();\r\n if (!item.disabled) {\r\n var expanded = this._expansionStates.get(item);\r\n this._expansionStates.set(item, !expanded);\r\n }\r\n }\r\n\r\n _isGroupExpanded(item: GroupMenuItem) {\r\n var state = this._expansionStates.get(item);\r\n return typeof state === 'undefined' ? false : state;\r\n }\r\n\r\n hasPermission(item: GroupMenuItem<any>) {\r\n // if (this._identityManager && item.showPermission) {\r\n // const user = this._identityManager?.get()!;\r\n // return user.hasPermission(item.showPermission);\r\n // }\r\n return true;\r\n }\r\n}\r\n","<ul>\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: {$implicit: items}\"></ng-container>\r\n</ul>\r\n\r\n<ng-template #menuTemplate let-items>\r\n <ng-container *ngFor=\"let item of items\">\r\n <ng-container [ngSwitch]=\"item.constructor.name\">\r\n <li *ngSwitchCase=\"'GroupMenuItem'\" class=\"jss-group-menu-item\" (click)=\"_onGroupMenuItemClick(item, $event)\">\r\n <span *ngIf=\"!_groupTemplate && item.text\" class=\"group-text\">{{item.text}}</span>\r\n <ng-container *ngIf=\"_groupTemplate\">\r\n <ng-container *ngTemplateOutlet=\"_groupTemplate.templateRef; context: {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n <ul *ngIf=\"item.children\" [@t]=\"_isGroupExpanded(item)\">\r\n <ng-container *ngTemplateOutlet=\"menuTemplate; context: {$implicit: item.children}\">\r\n </ng-container>\r\n </ul>\r\n </li> \r\n\r\n <li *ngSwitchCase=\"'TextMenuItem'\" class=\"jss-text-menu-item\" (click)=\"_onTextMenuItemClick(item, $event)\">\r\n <span *ngIf=\"!_textTemplate\">{{item.text}}</span>\r\n <ng-container *ngIf=\"_textTemplate\">\r\n <ng-container *ngTemplateOutlet=\"_textTemplate.templateRef; context: {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n\r\n <li *ngSwitchCase=\"'DividerMenuItem'\" class=\"jss-divider-menu-item\">\r\n <hr *ngIf=\"!_dividerTemplate\">\r\n <ng-container *ngIf=\"_dividerTemplate\">\r\n <ng-container *ngTemplateOutlet=\"_dividerTemplate.templateRef; context: {$implicit: item}\"></ng-container>\r\n </ng-container>\r\n </li>\r\n </ng-container>\r\n </ng-container>\r\n</ng-template>","import { NgModule } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { MenuComponent } from './menu.component';\r\nimport { TextMenuItemTemplateDirective } from './text-menu-item-template.directive';\r\nimport { GroupMenuItemTemplateDirective } from './group-menu-item-template.directive';\r\nimport { DividerMenuItemTemplateDirective } from './divider-menu-item-template.directive';\r\n\r\nconst DECLARES = [\r\n MenuComponent,\r\n TextMenuItemTemplateDirective,\r\n GroupMenuItemTemplateDirective,\r\n DividerMenuItemTemplateDirective\r\n];\r\n\r\n@NgModule({\r\n declarations: DECLARES,\r\n imports: [\r\n CommonModule\r\n ],\r\n exports: DECLARES\r\n})\r\nexport class MenuModule { }\r\n","import {\r\n Directive, TemplateRef, Input, ViewContainerRef, OnDestroy, EventEmitter, Output, OnInit, HostListener, ElementRef\r\n} from '@angular/core';\r\nimport { Overlay, OverlayRef } from '@angular/cdk/overlay';\r\nimport { TemplatePortal } from '@angular/cdk/portal';\r\nimport { OverlayPosition } from './types';\r\nimport { Subscription } from 'rxjs';\r\n\r\n@Directive({\r\n selector: '[jssOverlay]',\r\n exportAs: 'jssOverlay',\r\n})\r\nexport class OverlayDirective implements OnInit, OnDestroy {\r\n @Input() hasBackdrop = false;\r\n @Input('jssOverlay') overlay!: TemplateRef<any>;\r\n @Input() positions: OverlayPosition[] = [{ originX: 'start', originY: 'bottom', overlayX: 'start', overlayY: 'top' }];\r\n @Output() showChange = new EventEmitter<boolean>();\r\n @Output() backdropClick = new EventEmitter<MouseEvent>();\r\n\r\n /** Overlay state */\r\n @Input() set show(value: boolean) {\r\n if ((value && !this._show) || (!value && this._show)) {\r\n if (value) {\r\n this._createOverlay();\r\n } else {\r\n this._dispose();\r\n }\r\n this._show = value;\r\n }\r\n }\r\n\r\n get show(): boolean { return this._show; }\r\n\r\n private _overlayRef?: OverlayRef;\r\n private _show = false;\r\n private _backdropClickSubscription?: Subscription;\r\n\r\n constructor(\r\n private _overlayService: Overlay,\r\n private _viewRef: ViewContainerRef,\r\n private _elementRef: ElementRef,\r\n ) {\r\n }\r\n\r\n ngOnInit(): void {\r\n }\r\n\r\n public toggle(): void {\r\n this.show = !this.show;\r\n this.showChange.emit(this.show);\r\n }\r\n\r\n private _createOverlay(): void {\r\n var portal = new TemplatePortal(this.overlay, this._viewRef);\r\n const scrollStrategy = this._overlayService.scrollStrategies.reposition();\r\n const positionStrategy = this._overlayService.position().flexibleConnectedTo(this._elementRef.nativeElement)\r\n .withPositions(this.positions);\r\n\r\n this._overlayRef = this._overlayService.create({\r\n scrollStrategy,\r\n positionStrategy,\r\n hasBackdrop: this.hasBackdrop,\r\n backdropClass: 'jss-transparent-overlay'\r\n });\r\n\r\n this._overlayRef.attach(portal);\r\n if (this.hasBackdrop) {\r\n this._backdropClickSubscription = this._overlayRef.backdropClick().subscribe(x => {\r\n this.backdropClick.emit(x);\r\n });\r\n }\r\n }\r\n\r\n private _dispose(): void {\r\n this._backdropClickSubscription?.unsubscribe();\r\n this._overlayRef?.dispose();\r\n this._overlayRef = undefined;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._dispose();\r\n }\r\n}\r\n","import { DOCUMENT } from '@angular/common';\r\nimport { Inject, Injectable, Optional } from '@angular/core';\r\n\r\nconst cdkOverlayCss = `.cdk-overlay-container,.cdk-global-overlay-wrapper{pointer-events:none;top:0;left:0;height:100%;width:100%}.cdk-overlay-container{position:fixed;z-index:1000}.cdk-overlay-container:empty{display:none}.cdk-global-overlay-wrapper{display:flex;position:absolute;z-index:1000}.cdk-overlay-pane{position:absolute;pointer-events:auto;box-sizing:border-box;z-index:1000;display:flex;max-width:100%;max-height:100%}.cdk-overlay-backdrop{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1000;pointer-events:auto;-webkit-tap-highlight-color:transparent;transition:opacity 400ms cubic-bezier(0.25, 0.8, 0.25, 1);opacity:0}.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:1}@media screen and (-ms-high-contrast: active){.cdk-overlay-backdrop.cdk-overlay-backdrop-showing{opacity:.6}}.cdk-overlay-dark-backdrop{background:rgba(0,0,0,.32)}.cdk-overlay-transparent-backdrop,.cdk-overlay-transparent-backdrop.cdk-overlay-backdrop-showing{opacity:0}.cdk-overlay-connected-position-bounding-box{position:absolute;z-index:1000;display:flex;flex-direction:column;min-width:1px;min-height:1px}.cdk-global-scrollblock{position:fixed;width:100%;overflow-y:scroll}`;\r\nconst transparentOverlayCss = '.jss-transparent-overlay{background-color:transparent!important}';\r\nconst css = cdkOverlayCss + transparentOverlayCss;\r\n\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class CdkOverlayService {\r\n private _cssInjected = false;\r\n\r\n constructor(@Optional() @Inject(DOCUMENT) private _doc?: Document) {\r\n }\r\n\r\n /** Injects Angular CDK Overlay CSS to the DOM */\r\n public injectCss(): void {\r\n if (this._doc?.head && !this._cssInjected) {\r\n const head = this._doc.getElementsByTagName('head')[0];\r\n const style = this._doc.createElement('style');\r\n style.appendChild(this._doc.createTextNode(css));\r\n head.appendChild(style);\r\n }\r\n }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { OverlayModule as CdkOverlay } from '@angular/cdk/overlay';\r\nimport { CommonModule } from '@angular/common';\r\nimport { OverlayDirective } from './overlay.directive';\r\nimport { CdkOverlayService } from './cdk-overlay.service';\r\n\r\n@NgModule({\r\n declarations: [\r\n OverlayDirective,\r\n ],\r\n imports: [\r\n CommonModule,\r\n CdkOverlay\r\n ],\r\n exports: [\r\n OverlayDirective,\r\n ]\r\n})\r\nexport class OverlayModule {\r\n constructor(cdkOverlayService: CdkOverlayService) {\r\n cdkOverlayService.injectCss();\r\n }\r\n}\r\n","import { InjectionToken } from \"@angular/core\";\r\nimport { AppConfiguration } from \"./app-configuration\";\r\n\r\nexport const APP_CONFIGURATION = new InjectionToken<AppConfiguration>('AppConfiguration');\r\n","import { Directive, TemplateRef, ViewContainerRef, Input, Optional, OnInit, OnDestroy, EmbeddedViewRef } from '@angular/core';\r\nimport { NgForm, ValidationErrors } from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\n\r\n@Directive({\r\n selector: '[jssError]',\r\n exportAs: 'jssError',\r\n})\r\nexport class ErrorDirective implements OnInit, OnDestroy {\r\n private _embededViewRef?: EmbeddedViewRef<any>;\r\n private _fieldName!: string;\r\n private _formStatusChangeSubscription!: Subscription;\r\n private _formSubmitSubscription!: Subscription;\r\n private _errors: ValidationErrors | null = null;\r\n\r\n constructor(\r\n private _templateRef: TemplateRef<any>,\r\n private _viewContainer: ViewContainerRef,\r\n @Optional() private _form: NgForm,\r\n ) {\r\n if (!_form) {\r\n throw Error('ErrorDirective must be used in a form element.');\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n this._formStatusChangeSubscription = this._form.statusChanges!.subscribe(x => {\r\n const control = this._form.controls[this._fieldName];\r\n this._errors = control.errors;\r\n if (control.invalid && (control.dirty || control.touched)) {\r\n this._show(true);\r\n } else {\r\n this._show(false);\r\n }\r\n });\r\n\r\n this._formSubmitSubscription = this._form.ngSubmit.subscribe(s => {\r\n this._show(true);\r\n });\r\n }\r\n\r\n @Input('jssError') set fieldName(value: string) {\r\n this._fieldName = value;\r\n }\r\n\r\n get fieldName() {\r\n return this._fieldName;\r\n }\r\n\r\n get errors() {\r\n return this._errors;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._formStatusChangeSubscription.unsubscribe();\r\n this._formSubmitSubscription.unsubscribe();\r\n }\r\n\r\n private _show(show: boolean): void {\r\n if (show && !this._embededViewRef) {\r\n this._embededViewRef = this._viewContainer.createEmbeddedView(this._templateRef);\r\n } else if (!show && this._embededViewRef) {\r\n this._embededViewRef.destroy();\r\n this._embededViewRef = undefined;\r\n }\r\n }\r\n}\r\n","import { LocaleData, LocaleDictionary, LocaleErrorTranslators } from \"./locale-data\";\r\nimport { LocalizedValidationError } from \"./types\";\r\n\r\n/** Locale (Immutable) */\r\nexport class Locale {\r\n private readonly _data: LocaleData;\r\n\r\n constructor(data: LocaleData) {\r\n this._data = data;\r\n Object.freeze(data);\r\n // Object.freeze(data.dictionary);\r\n // Object.freeze(data.form.validation.error);\r\n // Object.freeze(data.form.validation.error.translators);\r\n }\r\n\r\n get name(): string {\r\n return this._data.name;\r\n }\r\n\r\n get rtl(): boolean {\r\n return this._data.rtl === true;\r\n }\r\n\r\n get data(): LocaleData {\r\n return this._data;\r\n }\r\n\r\n /** Clones this locale */\r\n clone(newProps?: Partial<LocaleData>): Locale {\r\n const configs: LocaleData = {\r\n name: newProps?.name ?? this._data.name,\r\n rtl: newProps?.rtl ?? this._data.rtl,\r\n dictionary: newProps?.dictionary ?? this._data.dictionary,\r\n form: newProps?.form ?? this._data.form,\r\n };\r\n\r\n return new Locale(configs);\r\n }\r\n\r\n /** Extends this object and returns a new Locale */\r\n extend(values: {\r\n dictionary?: LocaleDictionary,\r\n errorTranslators?: LocaleErrorTranslators\r\n }): Locale {\r\n return this.clone({\r\n dictionary: { ...this._data.dictionary, ...values?.dictionary },\r\n form: {\r\n validation: {\r\n error: {\r\n defaultMessage: this._data?.form?.validation?.error?.defaultMessage,\r\n translators: { ...this._data?.form?.validation?.error?.translators, ...values.errorTranslators }\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /** Translates a validation error */\r\n translateError(key: string, value: any): string | undefined {\r\n const e = this._data?.form?.validation?.error;\r\n const translatorFunc = e?.translators ? e.translators[key] : undefined;\r\n return typeof translatorFunc === 'function' ? translatorFunc(value) : e?.defaultMessage\r\n }\r\n\r\n /** Translates validation errors */\r\n translateErrors(errors: any): { [key: string]: LocalizedValidationError } {\r\n const result: { [key: string]: LocalizedValidationError } = {};\r\n for (const key in errors) {\r\n if (Object.prototype.hasOwnProperty.call(errors, key)) {\r\n result[key] = {\r\n key: key,\r\n value: errors[key],\r\n text: this.translateError(key, errors[key])\r\n };\r\n }\r\n }\r\n\r\n return result;\r\n }\r\n\r\n /** Translates first validation error */\r\n translateFirstError(errors: any): LocalizedValidationError | undefined {\r\n const key = Object.keys(errors)[0];\r\n const value = errors[key];\r\n return {\r\n key,\r\n value,\r\n text: this.translateError(key, value)\r\n };\r\n }\r\n\r\n /** Looks up a key in the locale dictionary */\r\n lookup(dictionaryKey: string): string | undefined {\r\n return this._data.dictionary ? this._data.dictionary[dictionaryKey] : undefined;\r\n }\r\n\r\n // formatDate(dateTime: DateTime, format: string): string {\r\n // return 'formated DateTime';\r\n // }\r\n}\r\n","import { Locale } from '../locale';\r\n\r\nexport const EN_US_LOCALE = new Locale({\r\n name: 'enUS',\r\n rtl: false,\r\n dictionary: {\r\n },\r\n form: {\r\n validation: {\r\n error: {\r\n defaultMessage: 'خطا',\r\n translators: {\r\n required: (err) => `Required`,\r\n min: (err) => `Minimum value: ${err.requiredMin}`,\r\n max: (err) => `Maximum value: ${err.requiredMax}`,\r\n minlength: (err) => `Minimum length: ${err.minlength}`,\r\n maxlength: (err) => `Maximum length: ${err.maxlength}`,\r\n email: (err) => `Invalid email`,\r\n }\r\n }\r\n }\r\n }\r\n});\r\n","import { Injectable, InjectionToken, Optional } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\nimport { Locale } from './locale';\r\n\r\nexport interface LocaleChangeEvent {\r\n oldLocale?: Locale;\r\n newLocale: Locale;\r\n}\r\n\r\n\r\n@Injectable()\r\nexport class LocaleProvider {\r\n private _locale?: Locale;\r\n private _locales: Locale[] = [];\r\n private _changeSubject = new Subject<LocaleChangeEvent>();\r\n readonly change = this._changeSubject.asObservable();\r\n\r\n constructor() {\r\n }\r\n\r\n /** Adds a Locale to this LocaleProvider */\r\n add(locale: Locale): void;\r\n /** Adds an array of Locales to this LocaleProvider */\r\n add(locales: Locale[]): void;\r\n add(l: any): void {\r\n if (l instanceof Locale) {\r\n this._locales.push(l);\r\n } else if (Array.isArray(l)) {\r\n l.forEach(x => this.add(x));\r\n } else {\r\n throw Error('Invalid locale');\r\n }\r\n }\r\n\r\n /** Sets the current Locale */\r\n set(localeName: string): void {\r\n const locale = this._locales.find(x => x.name === localeName);\r\n if (locale) {\r\n this._changeSubject.next({ oldLocale: this._locale, newLocale: locale });\r\n this._locale = locale;\r\n return;\r\n }\r\n\r\n throw Error('Locale not found.');\r\n }\r\n\r\n /** Returns the current Locale */\r\n get(): Locale | undefined {\r\n return this._locale;\r\n }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\nimport { LocaleProvider } from './locale-provider';\r\nimport { Locale } from './locale';\r\n\r\nexport const LOCALE = new InjectionToken<Locale | LocaleProvider>('LOCALE');\r\n\r\nexport interface LocalizedValidationError {\r\n /** Error key */\r\n key: string;\r\n \r\n /** Error object */\r\n value: any;\r\n \r\n /** Error localized text */\r\n text?: string;\r\n }\r\n ","import { Inject, Optional, Pipe, PipeTransform } from '@angular/core';\r\nimport { LocaleProvider } from './locale-provider';\r\nimport { Locale } from './locale';\r\nimport { LOCALE } from './types';\r\n\r\n@Pipe({\r\n name: 'jssTranslate',\r\n pure: false\r\n})\r\nexport class TranslatePipe implements PipeTransform {\r\n private _locale?: Locale;\r\n\r\n constructor(\r\n @Optional() @Inject(LOCALE) private l?: Locale | LocaleProvider) {\r\n const err = () => { throw Error('No Locale found.'); };\r\n\r\n if (l instanceof Locale) {\r\n this._locale = l;\r\n } else if (l instanceof LocaleProvider) {\r\n this._locale = l.get();\r\n if (!this._locale) {\r\n err();\r\n }\r\n l.change.subscribe(x => {\r\n this._locale = x.newLocale;\r\n });\r\n } else {\r\n err();\r\n }\r\n }\r\n\r\n transform(dictionaryKey: string, ...args: unknown[]): string {\r\n return this._locale?.lookup(dictionaryKey) ?? '';\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { NgModule } from '@angular/core';\r\nimport { TranslatePipe } from './translate.pipe';\r\n\r\nconst DECLARATIONS = [\r\n TranslatePipe,\r\n];\r\n\r\n@NgModule({\r\n imports: [\r\n CommonModule,\r\n ],\r\n declarations: DECLARATIONS,\r\n exports: DECLARATIONS\r\n})\r\nexport class LocalizationModule {\r\n}\r\n\r\n","import { Directive, TemplateRef, ViewContainerRef, Inject, Optional, OnInit, OnDestroy } from '@angular/core';\r\nimport { NgForm } from '@angular/forms';\r\nimport { Subscription } from 'rxjs';\r\nimport { Locale, LOCALE, LocaleProvider } from '../../localization';\r\nimport { ErrorDirective } from './error.directive';\r\n\r\n@Directive({\r\n selector: '[jssFirstError]',\r\n exportAs: 'jssFirstError',\r\n})\r\nexport class FirstErrorDirective implements OnInit, OnDestroy {\r\n private readonly _locale?: Locale;\r\n private _subscription?: Subscription;\r\n\r\n constructor(\r\n private _templateRef: TemplateRef<any>,\r\n private _viewContainer: ViewContainerRef,\r\n @Optional() private _errorDirective: ErrorDirective,\r\n @Optional() private _form: NgForm,\r\n @Optional() @Inject(LOCALE) l: Locale | LocaleProvider,\r\n ) {\r\n if (!_errorDirective) {\r\n throw Error('FirstErrorDirective must be used inside a ErrorDirective.');\r\n }\r\n\r\n if (l) {\r\n this._locale = l instanceof Locale ? l : l.get();\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n this.showFirstError();\r\n this._subscription = this._form!.statusChanges!.subscribe(s => {\r\n const control = this._form.controls[this._errorDirective.fieldName];\r\n if (control.invalid) {\r\n this.showFirstError();\r\n }\r\n });\r\n }\r\n\r\n showFirstError() {\r\n const errors = this._errorDirective.errors;\r\n const firstErrorKey = Object.keys(errors!)[0];\r\n const firstError = errors![firstErrorKey];\r\n const firstErrorText = this._locale!.translateFirstError(errors);\r\n this._viewContainer.clear();\r\n this._viewContainer.createEmbeddedView(this._templateRef, { $implicit: firstError, errorText: firstErrorText });\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._subscription!.unsubscribe();\r\n }\r\n}\r\n","import { AbstractControl, ValidatorFn } from '@angular/forms';\r\n\r\nexport function equalWithValidator(targetValue?: string, inequalityMessage?: string): ValidatorFn {\r\n return (control: AbstractControl): { [key: string]: any } | null => {\r\n const isValid = control.value === targetValue;\r\n\r\n return isValid ? null :\r\n {\r\n equalWith: {\r\n value: control.value,\r\n message: inequalityMessage\r\n }\r\n };\r\n };\r\n}\r\n","import { Directive, Input } from '@angular/core';\r\nimport { AbstractControl, NG_VALIDATORS, Validator } from '@angular/forms';\r\nimport { equalWithValidator } from './equal-with-validator';\r\n\r\n@Directive({\r\n selector: '[jssEqualWith]',\r\n providers: [\r\n { provide: NG_VALIDATORS, useExisting: EqualWithDirective, multi: true }\r\n ]\r\n})\r\nexport class EqualWithDirective implements Validator {\r\n @Input('jssEqualWith') targetValue?: string;\r\n @Input() inequalityMessage?: string;\r\n\r\n constructor() {\r\n }\r\n\r\n validate(control: AbstractControl): { [key: string]: any } | null {\r\n return equalWithValidator(this.targetValue, this.inequalityMessage)(control);\r\n }\r\n}\r\n","import { Directive, Input } from '@angular/core';\r\nimport { FormControl, NG_VALIDATORS, ValidationErrors, Validator, Validators } from '@angular/forms';\r\n\r\n@Directive({\r\n selector: '[jssMax]',\r\n exportAs: 'jssMax',\r\n providers: [{ provide: NG_VALIDATORS, useExisting: MaxValidatorDirective, multi: true }]\r\n})\r\nexport class MaxValidatorDirective implements Validator {\r\n @Input('jssMax') max!: number;\r\n\r\n validate(control: FormControl): ValidationErrors | null {\r\n return Validators.max(this.max)(control);\r\n }\r\n}\r\n","import { Directive, Input } from '@angular/core';\r\nimport { FormControl, NG_VALIDATORS, ValidationErrors, Validator, Validators } from '@angular/forms';\r\n\r\n@Directive({\r\n selector: '[jssMin]',\r\n exportAs: 'jssMin',\r\n providers: [{ provide: NG_VALIDATORS, useExisting: MinValidatorDirective, multi: true }]\r\n})\r\nexport class MinValidatorDirective implements Validator {\r\n @Input('jssMin') min!: number;\r\n\r\n validate(control: FormControl): ValidationErrors | null {\r\n return Validators.min(this.min)(control);\r\n }\r\n}\r\n","import { AbstractControl, ValidatorFn } from '@angular/forms';\r\n\r\nexport function passwordValidator(options?: { minLength?: number }): ValidatorFn {\r\n return (control: AbstractControl): { [key: string]: any } | null => {\r\n const value = (control.value as string);\r\n const invalid = {\r\n 'password': {\r\n value: control.value,\r\n }\r\n };\r\n\r\n if (value == null) {\r\n return null;\r\n }\r\n \r\n if (Number.isInteger(options?.minLength)) {\r\n