{ "version": 3, "sources": ["src/app/shared/directives/render-if.directive.ts"], "sourcesContent": ["\r\nimport { Directive, Input, TemplateRef, ViewContainerRef, EmbeddedViewRef, Renderer2 } from '@angular/core';\r\nimport { Observable, of, Subject } from 'rxjs';\r\nimport { switchMap, map } from 'rxjs/operators';\r\nimport { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';\r\nimport { Platform } from '@angular/cdk/platform';\r\nimport { UsersService } from '@shared/services/users/users.service';\r\nimport { UserRolesEnum } from '@collections/users/enums/user-roles.enums';\r\nimport { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';\r\nimport { Breakpoints } from '@fuse/services/match-media.service';\r\n\r\nexport const ExtBreakpoints = {\r\n ...Breakpoints,\r\n 'lt-sm': '(max-width: 639px)',\r\n 'lt-md': '(max-width: 767px)',\r\n 'lt-lg': '(max-width: 1023px)',\r\n 'lt-xl': '(max-width: 1279px)',\r\n 'lt-2xl': '(max-width: 1589px)',\r\n 'gt-xs': '(min-width: 480px)',\r\n 'gt-sm': '(min-width: 640px)',\r\n 'gt-md': '(min-width: 768px)',\r\n 'gt-lg': '(min-width: 1024px)',\r\n 'gt-xl': '(min-width: 1280px)'\r\n};\r\n\r\nexport type MediaSelector = 'sm' | 'md' | 'lg' | 'xl' | '2xl'\r\n| 'lt-sm' | 'lt-md' | 'lt-lg' | 'lt-xl' | 'lt-2xl'\r\n| 'gt-xs'| 'gt-sm' | 'gt-md' | 'gt-lg' | 'gt-xl' ;\r\n\r\nexport type RenderIfConditions = {\r\n mediaSelector?: MediaSelector,\r\n roles?: UserRolesEnum[],\r\n baseCondition?: boolean,\r\n logicalMode?: 'AND' | 'OR',\r\n // flex block inline-flex ecc.\r\n // https://tailwindcss.com/docs/display\r\n // (serve lato server per visualizzare un elemento da uno specifico breakpoint in poi)\r\n displayClass?: string;\r\n };\r\n\r\n@UntilDestroy()\r\n@Directive({\r\n selector: '[renderIf]',\r\n standalone: true\r\n})\r\nexport class RenderIfDirective {\r\n\r\n private viewRef: EmbeddedViewRef = undefined;\r\n private renderIfmatcher = new Subject();\r\n private lastValue: RenderIfConditions;\r\n\r\n // fa si che vengano incluse queste classi (!important)\r\n private tailwind_hidden_class = `\r\n sm:!hidden\r\n md:!hidden\r\n lg:!hidden\r\n xl:!hidden\r\n 2xl:!hidden\r\n `;\r\n /**\r\n *\r\n * @param {RenderIfConditions} value\r\n */\r\n @Input()\r\n set renderIf(value: RenderIfConditions) {\r\n const baseCondition = value.baseCondition;\r\n value.baseCondition = baseCondition === undefined ? true : baseCondition;\r\n this.lastValue = value;\r\n this.renderIfmatcher.next(value);\r\n }\r\n\r\n // https://angular.io/guide/structural-directives#directive-type-checks\r\n // dovrebbe effettuare un type check sull'input, ma sembra non funzionare\r\n static ngTemplateGuard_renderIf(dir: RenderIfDirective, expr: RenderIfConditions): expr is RenderIfConditions {\r\n return true;\r\n }\r\n\r\n constructor(\r\n private platform: Platform,\r\n private viewContainer: ViewContainerRef,\r\n private templateRef: TemplateRef,\r\n private usersService: UsersService,\r\n private renderer: Renderer2,\r\n private observer: BreakpointObserver\r\n ) {\r\n if (this.platform.isBrowser) {\r\n this.watchMedia();\r\n this.usersService.onUserChange\r\n .pipe(\r\n untilDestroyed(this)\r\n ).subscribe( () => {\r\n if (this.lastValue) {\r\n this.renderIfmatcher.next(this.lastValue);\r\n }\r\n });\r\n } else {\r\n\r\n this.renderIfmatcher.pipe(\r\n untilDestroyed(this)\r\n ).subscribe(val => {\r\n // lato server, effettua il render se non è prevista come condizione essenziale\r\n // che l'utente abbia un ruolo determinato.\r\n if ((val.logicalMode && val.logicalMode !== 'AND') || !val.roles) {\r\n this.updateView(true, val.mediaSelector, val.displayClass);\r\n }\r\n });\r\n }\r\n\r\n }\r\n\r\n /**\r\n * Watch for mediaChange(s) on new mediaQuery\r\n */\r\n private watchMedia(): void {\r\n const updateView = this.updateView.bind(this);\r\n const getQuery = (selector) => {\r\n return ExtBreakpoints[selector];\r\n };\r\n\r\n this.renderIfmatcher.pipe(\r\n switchMap(v => {\r\n // se baseCondition è impostata a false non effettua mai il render\r\n if (!v.baseCondition) {\r\n return of(false);\r\n }\r\n const query = getQuery(v.mediaSelector);\r\n return query ? this.observer.observe(query)\r\n .pipe(\r\n map((state: BreakpointState) => {\r\n\r\n if (v.logicalMode === 'AND' || !v.roles) {\r\n return state.matches && this.usersService.isInRole(v.roles);\r\n } else {\r\n return state.matches || this.usersService.isInRole(v.roles);\r\n }\r\n })\r\n ) : new Observable( observer => {\r\n observer.next(this.usersService.isInRole(v.roles));\r\n });\r\n }),\r\n untilDestroyed(this)\r\n )\r\n .subscribe(updateView);\r\n }\r\n\r\n /**\r\n * Create or clear view instance\r\n */\r\n private updateView(isActive: boolean, mediaSelector?: string, displayClass?: string): void {\r\n if (isActive && !this.viewRef) {\r\n this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef);\r\n if ( mediaSelector) { // eseguito solo lato server, per aggiungere classe\r\n const el = this.viewRef.rootNodes[0];\r\n if (el instanceof HTMLElement) {\r\n\r\n // Se il media selector è di tipo lower than, applica la classe hidden a quel punto\r\n const bp = mediaSelector.replace('lt-', '').replace('gt-', '');\r\n if (mediaSelector.startsWith('lt-')) {\r\n this.renderer.addClass(el, `${bp}:!hidden`);\r\n } else if (mediaSelector.startsWith('gt-')) {\r\n\r\n // tutti gli altri selettori (sm md lg xl 2xl)\r\n // andrebbero inserite tutte le possibili combinazioni tra selettore e display\r\n // come per tailwind_hidden_class, ma forse non ne vale la pena. vediamo in futuro.\r\n // this.renderer.addClass(el, `!hidden`);\r\n // displayClass = displayClass ?? 'block';\r\n // this.renderer.addClass(el, `${bp}:!${displayClass}`);\r\n }\r\n }\r\n }\r\n } else if (!isActive && this.viewRef) {\r\n this.viewContainer.clear();\r\n this.viewRef = undefined;\r\n }\r\n }\r\n\r\n}\r\n"], "mappings": "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", "names": ["ExtBreakpoints", "__spreadProps", "__spreadValues", "Breakpoints", "RenderIfDirective", "_a", "renderIf", "value", "baseCondition", "undefined", "lastValue", "renderIfmatcher", "next", "ngTemplateGuard_renderIf", "dir", "expr", "constructor", "platform", "viewContainer", "templateRef", "usersService", "renderer", "observer", "viewRef", "Subject", "tailwind_hidden_class", "isBrowser", "watchMedia", "onUserChange", "pipe", "untilDestroyed", "subscribe", "val", "logicalMode", "roles", "updateView", "mediaSelector", "displayClass", "bind", "getQuery", "selector", "switchMap", "v", "of", "query", "observe", "map", "state", "matches", "isInRole", "Observable", "isActive", "createEmbeddedView", "el", "rootNodes", "HTMLElement", "bp", "replace", "startsWith", "addClass", "clear", "\u0275\u0275directiveInject", "Platform", "ViewContainerRef", "TemplateRef", "UsersService", "Renderer2", "BreakpointObserver", "selectors", "inputs", "standalone", "__decorate", "UntilDestroy", "__metadata"] }