{ "version": 3, "sources": ["libs/app-layout/sidenav/data-access/src/lib/types/side-navbar.types.ts", "libs/app-layout/sidenav/data-access/src/lib/services/sidenav.service.ts", "libs/app-layout/sidenav/data-access/src/lib/news/types/sidenav-item.model.ts"], "sourcesContent": ["/**\n * - Company Logo (or Company Name)\n * - Main Content:\n * - Top Section:\n * 1. Home (link)\n * 2. New (menu button)\n * 3. Documents (category)\n * 4. Templates (category)\n * 5. Forms (category)\n * - Bottom Section:\n * 1. Company Settings (link)\n * 2. Users (link) - for superusers\n * 3. Address Book (link)\n * 4. Swagger (link) - for developers\n * - Footer:\n * - Top: DocCycle Application Info - Logo, Version Change Log - Icon Button(open modal), Version Number (tooltip)\n * - Bottom: User Area - User Display Name, Avatar Icon Button (open overlay with options)\n *\n *\n * Note:\n * 1. foreach item (not category) has: link, icon, label, badge\n * 2. category has: label, items\n */\nimport {MenuItem, TreeNode} from 'primeng/api';\n\nimport {Router} from '@angular/router';\nimport {signal, WritableSignal} from '@angular/core';\nimport {PermissionType} from '@core/api/data-access'\nimport {MainInjector, uuidv4} from '@shared-types';\n\nexport enum SideNavSectionType {\n\tTop = 'top',\n\tBottom = 'bottom',\n}\n\nexport const SideNavbarItemType = {\n\tCategory: 'category', // category of items\n\tLink: 'link', // link to a route\n\tButton: 'button', // button with callback\n\tSeparator: 'separator', // separator\n} as const;\nexport type SideNavbarItemType = (typeof SideNavbarItemType)[keyof typeof SideNavbarItemType];\n\nexport abstract class SideNavbarItem {\n\tkey: K;\n\tabstract readonly type: SideNavbarItemType;\n\tabstract label: string;\n\tabstract availableOnMobile: boolean;\n\ticon?: string;\n\tbadge: WritableSignal = signal(NaN);\n\ttreeNode: TreeNode;\n\tnodeElement: HTMLElement;\n\n\tabstract permissions: {\n\t\tall?: PermissionType[];\n\t\tnone?: PermissionType[];\n\t};\n\n\tasCategory?(): SideNavbarCategory;\n\n\tasLink?(): SideNavbarLink;\n\n\tasButton?(): SideNavbarButton;\n\n\tprotected constructor() {\n\t\tthis.key = uuidv4() as K;\n\t}\n\n\t/* -------------------------------------------------- */\n\tget isCategory(): boolean {\n\t\treturn this.type === SideNavbarItemType.Category;\n\t}\n\n\tget isLink(): boolean {\n\t\treturn this.type === SideNavbarItemType.Link;\n\t}\n\n\tget isButton(): boolean {\n\t\treturn this.type === SideNavbarItemType.Button;\n\t}\n\n\tget isSeparator(): boolean {\n\t\treturn this.type === SideNavbarItemType.Separator;\n\t}\n\n\t/* -------------------------------------------------- */\n\tpublic resetNodeRecursively(): void {\n\t\tfunction resetNode(node: TreeNode) {\n\t\t\tnode.expanded = false;\n\t\t\tnode.styleClass = node.styleClass?.trim().replace('is-selected', '');\n\t\t}\n\n\t\tconst node = this.treeNode;\n\t\tif (node) {\n\t\t\tsetTimeout(() => {\n\t\t\t\tresetNode(node);\n\t\t\t\tif (node.children?.length) {\n\t\t\t\t\tnode.children.forEach(child => resetNode(child));\n\t\t\t\t}\n\t\t\t\tif (node.parent) {\n\t\t\t\t\tresetNode(node.parent);\n\t\t\t\t}\n\t\t\t}, 0);\n\t\t}\n\t}\n\t/* -------------------------------------------------------------------------------------------------------------- */\n\tmenuItem: MenuItem;\n}\n\nexport class SideNavbarCategory extends SideNavbarItem {\n\treadonly type: SideNavbarItemType = SideNavbarItemType.Category;\n\tlabel: string;\n\n\tavailableOnMobile: boolean = true;\n\n\tpermissions: {\n\t\tall?: PermissionType[];\n\t\tnone?: PermissionType[];\n\t} = {\n\t\tall: [],\n\t\tnone: [],\n\t};\n\n\titems: SideNavbarItem[] = [];\n\n\toverride asCategory(): SideNavbarCategory {\n\t\treturn this;\n\t}\n\n\tconstructor(init: Partial) {\n\t\tsuper();\n\t\tObject.assign(this, init);\n\t}\n}\n\n/* -------------------------------------------------- Link -------------------------------------------------- */\nexport class SideNavbarLink extends SideNavbarItem {\n\treadonly type: SideNavbarItemType = SideNavbarItemType.Link;\n\tlabel: string;\n\troute: string;\n\n\tavailableOnMobile: boolean = true;\n\n\tpermissions: {\n\t\tall?: PermissionType[];\n\t\tnone?: PermissionType[];\n\t} = {\n\t\tall: [],\n\t\tnone: [],\n\t};\n\n\tcloseParentAfterNavigation: boolean = false;\n\n\tcontextMenuItemsFn?: (item: SideNavbarLink) => MenuItem[] = undefined;\n\tcontextMenuItems: MenuItem[] = [];\n\n\toverride asLink(): SideNavbarLink {\n\t\treturn this;\n\t}\n\n\tconstructor(init: Partial>, key: K = uuidv4() as K) {\n\t\tsuper();\n\t\tObject.assign(this, init);\n\t\tthis.key = key;\n\t\tif (init.contextMenuItemsFn) {\n\t\t\tthis.contextMenuItems = init.contextMenuItemsFn(this);\n\t\t}\n\t}\n\n\tnavigate() {\n\t\tif (this.closeParentAfterNavigation) {\n\t\t\tthis.resetNodeRecursively();\n\t\t}\n\t\tconst router = MainInjector.get(Router);\n\t\treturn router.navigate([this.route]);\n\t}\n}\n\n/* -------------------------------------------------- Button -------------------------------------------------- */\nexport class SideNavbarButton extends SideNavbarItem {\n\treadonly type: SideNavbarItemType = SideNavbarItemType.Button;\n\tlabel: string;\n\tcallback: (e: MouseEvent, item: SideNavbarButton) => void;\n\n\tavailableOnMobile: boolean = true;\n\n\tpermissions: {\n\t\tall?: PermissionType[];\n\t\tnone?: PermissionType[];\n\t} = {\n\t\tall: [],\n\t\tnone: [],\n\t};\n\n\toverride asButton(): SideNavbarButton {\n\t\treturn this;\n\t}\n\n\tconstructor(init: Partial) {\n\t\tsuper();\n\t\tObject.assign(this, init);\n\t}\n}\n\n/* -------------------------------------------------- Separator -------------------------------------------------- */\nexport class SideNavbarSeparator extends SideNavbarItem {\n\tavailableOnMobile: boolean;\n\treadonly type: SideNavbarItemType = SideNavbarItemType.Separator;\n\tlabel: string;\n\tpermissions: {all?: PermissionType[]; none?: PermissionType[]} = {\n\t\tall: [],\n\t\tnone: [],\n\t};\n\n\tconstructor(init?: Partial) {\n\t\tsuper();\n\t\tObject.assign(this, init);\n\t}\n}\n", "import {computed, inject, Injectable, signal, Signal, WritableSignal} from '@angular/core';\nimport {ActivatedRoute, NavigationEnd, Router} from '@angular/router';\nimport {AuthService} from '@auth/data-access';\nimport {LanguageService} from '@core/language';\nimport {filter, map, mergeMap} from 'rxjs';\nimport {GlobalAppRouteConfig} from '@global-data';\nimport {environment} from '@shared-types';\nimport {DeviceType} from 'ngx-device-detector';\n\n@Injectable({\n\tprovidedIn: 'root',\n})\nexport class SidenavService {\n\t/* ------------------------------------------ PROVIDERS / SERVICES ------------------------------------------ */\n\tprotected readonly authService: AuthService = inject(AuthService);\n\tprivate readonly languageService: LanguageService = inject(LanguageService);\n\t/* ------------------------------------------------ Signals ------------------------------------------------ */\n\tpublic readonly isSidenavAvailable: Signal = computed(() => this.authService.isAuthenticated() && this.authService.ActiveUser.isPermanent());\n\tpublic readonly sideNavPosition: Signal<'right' | 'left'> = computed(() => {\n\t\tconst langData = this.languageService.currentLangData();\n\t\treturn langData?.dir === 'rtl' ? 'right' : 'left';\n\t});\n\n\tpublic readonly sideNavToggleBtnLabel: Signal = computed(() => {\n\t\treturn `dccomp.sidenav.modes.${this.isSidenavOpen() ? 'hide' : 'expand'}`;\n\t});\n\n\tpublic readonly sideNavToggleBtnIcon: Signal = computed(() => {\n\t\tconst langData = this.languageService.currentLangData();\n\t\tconst isSidenavOpen = this.isSidenavOpen();\n\t\tconst fromOrTo = isSidenavOpen ? 'from' : 'to';\n\t\tconst iconName = `fa-arrow-${isSidenavOpen ? langData.position : langData.oppositeLang.position}-${fromOrTo}-arc`;\n\t\treturn `fa-duotone ${iconName} fa-xl`;\n\t});\n\n\t/* -------------------------------------------------- Data -------------------------------------------------- */\n\tpublic readonly isSidenavOpen: WritableSignal = signal(environment.deviceType !== DeviceType.Mobile);\n\n\t/* ------------------------------------------------ Constructor ------------------------------------------------ */\n\tconstructor(\n\t\tprivate router: Router,\n\t\tprivate activatedRoute: ActivatedRoute,\n\t) {\n\t\tthis.startRouterListener();\n\t}\n\n\t/* ------------------------------------------------ Methods ------------------------------------------------ */\n\t/** @description - Open the sidenav */\n\tpublic open(): void {\n\t\tthis.isSidenavOpen.set(true);\n\t}\n\n\t/** @description - Close the sidenav */\n\tpublic close(): void {\n\t\tthis.isSidenavOpen.set(false);\n\t}\n\n\t/** @description - Toggle the sidenav */\n\tpublic toggle(): void {\n\t\tthis.isSidenavOpen.set(!this.isSidenavOpen());\n\t}\n\n\t/**\n\t * @description - Listen to router events and close the sidenav if the route has autoHideSidenav data\n\t * @returns void\n\t */\n\tprivate startRouterListener(): void {\n\t\tthis.router.events\n\t\t\t.pipe(\n\t\t\t\tfilter(event => event instanceof NavigationEnd),\n\t\t\t\tmap(() => this.activatedRoute),\n\t\t\t\tmap(route => {\n\t\t\t\t\twhile (route.firstChild) route = route.firstChild;\n\t\t\t\t\treturn route;\n\t\t\t\t}),\n\t\t\t\tfilter(route => route.outlet === 'primary'),\n\t\t\t\tmergeMap(route => route.data),\n\t\t\t)\n\t\t\t.subscribe((data: GlobalAppRouteConfig) => {\n\t\t\t\tif (data?.autoHideSidenav || environment.deviceType === DeviceType.Mobile) {\n\t\t\t\t\tthis.close();\n\t\t\t\t} else {\n\t\t\t\t\tthis.open();\n\t\t\t\t}\n\t\t\t});\n\t}\n}\n", "import {MenuItem} from 'primeng/api';\nimport {PermissionType} from '@core/api/data-access';\nimport {SidenavItemPermissionStruct} from './sidenav-item.types';\nimport {MenuItemCommandEvent} from 'primeng/api/menuitem';\n\nexport type ISidenavItem = MenuItem & {\n\tpermissions: SidenavItemPermissionStruct;\n\titems?: (SidenavItemModel | MenuItem)[] | undefined;\n};\n\nexport class SidenavItemModel implements MenuItem {\n\tlabel: string;\n\ticon: string;\n\tstyleClass: string;\n\tpermissions: SidenavItemPermissionStruct;\n\n\trouterLink?: string;\n\tcounter?: number = null\n\titems?: (SidenavItemModel | MenuItem)[];\n\tcommand?: (event: MenuItemCommandEvent) => void;\n\n\tisActive: (activeRoute: string) => boolean = (activeRoute: string) => activeRoute.includes(this.routerLink || '');\n\n\n\tconstructor(label: string, icon: string, allowedPermissions: PermissionType[], deniedPermissions: PermissionType[], items?: (SidenavItemModel | MenuItem)[], route?: string, command?: (event: MenuItemCommandEvent) => void, isActive?: (activeRoute: string) => boolean, counter?: number,) {\n\t\tthis.label = label;\n\t\tthis.icon = icon ? icon + 'sub-item-icon fa-lg border border-solid aspect-square rounded-md border-gray-300 p-1 m-0' : '';\n\t\tthis.styleClass = 'cursor-pointer font-dc';\n\t\tif (label === 'חדש' || label === 'New') this.styleClass = 'cursor-pointer font-dc bg-white text-gray-100 font-bold rounded-md';\n\t\tthis.permissions = {\n\t\t\tallowed: allowedPermissions,\n\t\t\tdenied: deniedPermissions,\n\t\t};\n\t\tthis.routerLink = route ? route : '';\n\t\tthis.counter = counter;\n\t\tthis.items = items?.map(item => {\n\t\t\titem.parent = this;\n\t\t\treturn item;\n\t\t});\n\t\tthis.command = command;\n\n\t\tthis.routerLink = route;\n\t\tisActive && (this.isActive = isActive);\n\n\t\t\n\t}\n\n\t/* ---------------------------------------------- Parent Node ---------------------------------------------- */\n\tprivate _parent: SidenavItemModel | null = null;\n\tpublic get parent(): SidenavItemModel | null {\n\t\treturn this._parent;\n\t}\n\n\tpublic set parent(parent: SidenavItemModel | null) {\n\t\tif (parent) this.styleClass += 'sub-item';\n\t\telse this.styleClass = this.styleClass.replace('sub-item', '');\n\t\tthis._parent = parent;\n\t}\n\n\t/* ------------------------------------------------ Icon ------------------------------------------------ */\n}\n"], "mappings": "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", "names": ["SideNavSectionType", "SidenavService", "constructor", "router", "activatedRoute", "authService", "inject", "AuthService", "languageService", "LanguageService", "isSidenavAvailable", "computed", "isAuthenticated", "ActiveUser", "isPermanent", "sideNavPosition", "currentLangData", "dir", "sideNavToggleBtnLabel", "isSidenavOpen", "sideNavToggleBtnIcon", "langData", "fromOrTo", "position", "oppositeLang", "signal", "environment", "deviceType", "DeviceType", "Mobile", "startRouterListener", "open", "set", "close", "toggle", "events", "pipe", "filter", "event", "NavigationEnd", "map", "route", "firstChild", "outlet", "mergeMap", "data", "subscribe", "autoHideSidenav", "\u0275\u0275inject", "Router", "ActivatedRoute", "factory", "\u0275fac", "providedIn", "_SidenavService", "SidenavItemModel", "constructor", "label", "icon", "allowedPermissions", "deniedPermissions", "items", "route", "command", "isActive", "counter", "activeRoute", "includes", "routerLink", "_parent", "styleClass", "permissions", "allowed", "denied", "map", "item", "parent", "replace"] }