{ "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": ["import {signal, WritableSignal} from '@angular/core';\nimport {Router} from '@angular/router';\n\nimport {PermissionType} from '@core/api/data-access';\nimport {MainInjector, uuidv4} from '@shared-types';\n\n/**\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\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 = 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 = 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 = 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 = 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';\n\nimport {AuthService} from '@auth/data-access';\nimport {LanguageService} from '@core/language';\nimport {GlobalAppRouteConfig} from '@global-data';\nimport {environment} from '@shared-types';\n\nimport {DeviceType} from 'ngx-device-detector';\nimport {filter, map, mergeMap} from 'rxjs';\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 {MenuItemCommandEvent} from 'primeng/api/menuitem';\n\nimport {SidenavItemPermissionCriteria, SidenavItemPermissions} from './sidenav-item.types';\n\ntype SidenavItemConfig = {\n\tlabel: string;\n\ticon: string;\n} & Partial<{\n\tstyleClass?: string;\n\tallowedPermissions:\n\t\t| SidenavItemPermissionCriteria[]\n\t\t| {\n\t\t\t\tallowed: {\n\t\t\t\t\trequired: SidenavItemPermissionCriteria[];\n\t\t\t\t\toptional?: SidenavItemPermissionCriteria[];\n\t\t\t\t};\n\t\t\t\tdenied: SidenavItemPermissionCriteria[];\n\t\t };\n\tdeniedPermissions: SidenavItemPermissionCriteria[];\n\toptionalPermissions: SidenavItemPermissionCriteria[];\n\titems?: (SidenavItemModel | MenuItem)[];\n\troute?: string;\n\tcommand?: (event: MenuItemCommandEvent) => void;\n\tisActive?: (activeRoute: string) => boolean;\n\tcounter?: number;\n}>;\n\nexport class SidenavItemModel implements MenuItem {\n\tlabel: string;\n\ticon: string;\n\tstyleClass: string;\n\tpermissions: SidenavItemPermissions;\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\tconstructor(config: SidenavItemConfig) {\n\t\tthis.label = config.label;\n\t\tthis.icon = config.icon ? config.icon + 'sub-item-icon fa-lg border border-solid aspect-square rounded-md border-gray-300 p-1 m-0' : '';\n\n\t\tthis.styleClass = config?.styleClass ? `'cursor-pointer font-dc ${config.styleClass}` : 'cursor-pointer font-dc';\n\t\tif (this.label === 'חדש' || this.label === 'New') this.styleClass = 'cursor-pointer font-dc bg-white text-gray-100 font-bold rounded-md';\n\n\t\tconfig.allowedPermissions = config.allowedPermissions || [];\n\t\tconfig.deniedPermissions = config.deniedPermissions || [];\n\t\tconfig.optionalPermissions = config.optionalPermissions || [];\n\t\tthis.permissions = Array.isArray(config.allowedPermissions)\n\t\t\t? {\n\t\t\t\t\tallowed: {\n\t\t\t\t\t\trequired: config.allowedPermissions,\n\t\t\t\t\t\toptional: config.optionalPermissions,\n\t\t\t\t\t},\n\t\t\t\t\tdenied: config.deniedPermissions,\n\t\t\t\t}\n\t\t\t: config.allowedPermissions;\n\n\t\tthis.routerLink = config?.route ? config.route : undefined;\n\t\tthis.counter = config?.counter ?? null;\n\t\tthis.items = config?.items?.map(item => {\n\t\t\titem.parent = this;\n\t\t\treturn item;\n\t\t});\n\t\tthis.command = config?.command ?? null;\n\t\tthis.isActive = config?.isActive ?? (activeRoute => activeRoute.includes(this.routerLink || ''));\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": "mRA+BA,IAAYA,EAAZ,SAAYA,EAAkB,CAC7BA,OAAAA,EAAA,IAAA,MACAA,EAAA,OAAA,SAFWA,CAGZ,EAHYA,GAAkB,CAAA,CAAA,ECjB9B,IAAaC,GAAc,IAAA,CAArB,MAAOA,CAAc,CA2B1BC,YACSC,EACAC,EAA8B,CAD9B,KAAAD,OAAAA,EACA,KAAAC,eAAAA,EA3BU,KAAAC,YAA2BC,EAAOC,CAAW,EAC/C,KAAAC,gBAAmCF,EAAOG,CAAe,EAE1D,KAAAC,mBAAsCC,EAAS,IAAM,KAAKN,YAAYO,gBAAe,GAAM,KAAKP,YAAYQ,WAAWC,YAAW,CAAE,EACpI,KAAAC,gBAA4CJ,EAAS,IACnD,KAAKH,gBAAgBQ,gBAAe,GACpCC,MAAQ,MAAQ,QAAU,MAC3C,EAEe,KAAAC,sBAAwCP,EAAS,IACzD,wBAAwB,KAAKQ,cAAa,EAAK,OAAS,QAAQ,EACvE,EAEe,KAAAC,qBAAuCT,EAAS,IAAK,CACpE,IAAMU,EAAW,KAAKb,gBAAgBQ,gBAAe,EAC/CG,EAAgB,KAAKA,cAAa,EAClCG,EAAWH,EAAgB,OAAS,KAE1C,MAAO,cADU,YAAYA,EAAgBE,EAASE,SAAWF,EAASG,aAAaD,QAAQ,IAAID,CAAQ,MAC9E,QAC9B,CAAC,EAGe,KAAAH,cAAyCM,EAAOC,EAAYC,aAAeC,EAAWC,MAAM,EAO3G,KAAKC,oBAAmB,CACzB,CAIOC,MAAI,CACV,KAAKZ,cAAca,IAAI,EAAI,CAC5B,CAGOC,OAAK,CACX,KAAKd,cAAca,IAAI,EAAK,CAC7B,CAGOE,QAAM,CACZ,KAAKf,cAAca,IAAI,CAAC,KAAKb,cAAa,CAAE,CAC7C,CAMQW,qBAAmB,CAC1B,KAAK3B,OAAOgC,OACVC,KACAC,EAAOC,GAASA,aAAiBC,CAAa,EAC9CC,EAAI,IAAM,KAAKpC,cAAc,EAC7BoC,EAAIC,GAAQ,CACX,KAAOA,EAAMC,YAAYD,EAAQA,EAAMC,WACvC,OAAOD,CACR,CAAC,EACDJ,EAAOI,GAASA,EAAME,SAAW,SAAS,EAC1CC,EAASH,GAASA,EAAMI,IAAI,CAAC,EAE7BC,UAAWD,GAA8B,CACrCA,GAAME,iBAAmBrB,EAAYC,aAAeC,EAAWC,OAClE,KAAKI,MAAK,EAEV,KAAKF,KAAI,CAEX,CAAC,CACH,iDAzEY9B,GAAc+C,EAAAC,CAAA,EAAAD,EAAAE,CAAA,CAAA,CAAA,CAAA,iCAAdjD,EAAckD,QAAdlD,EAAcmD,UAAAC,WAFd,MAAM,CAAA,CAAA,SAENpD,CAAc,GAAA,ECcrB,IAAOqD,EAAP,KAAuB,CAY5BC,YAAYC,EAAyB,CANrC,KAAAC,QAAmB,KAInB,KAAAC,SAA8CC,GAAwBA,EAAYC,SAAS,KAAKC,YAAc,EAAE,EAiCxG,KAAAC,QAAmC,KA9B1C,KAAKC,MAAQP,EAAOO,MACpB,KAAKC,KAAOR,EAAOQ,KAAOR,EAAOQ,KAAO,2FAA6F,GAErI,KAAKC,WAAaT,GAAQS,WAAa,2BAA2BT,EAAOS,UAAU,GAAK,0BACpF,KAAKF,QAAU,sBAAS,KAAKA,QAAU,SAAO,KAAKE,WAAa,sEAEpET,EAAOU,mBAAqBV,EAAOU,oBAAsB,CAAA,EACzDV,EAAOW,kBAAoBX,EAAOW,mBAAqB,CAAA,EACvDX,EAAOY,oBAAsBZ,EAAOY,qBAAuB,CAAA,EAC3D,KAAKC,YAAcC,MAAMC,QAAQf,EAAOU,kBAAkB,EACvD,CACAM,QAAS,CACRC,SAAUjB,EAAOU,mBACjBQ,SAAUlB,EAAOY,qBAElBO,OAAQnB,EAAOW,mBAEfX,EAAOU,mBAEV,KAAKL,WAAaL,GAAQoB,MAAQpB,EAAOoB,MAAQC,OACjD,KAAKpB,QAAUD,GAAQC,SAAW,KAClC,KAAKqB,MAAQtB,GAAQsB,OAAOC,IAAIC,IAC/BA,EAAKC,OAAS,KACPD,EACP,EACD,KAAKE,QAAU1B,GAAQ0B,SAAW,KAClC,KAAKxB,SAAWF,GAAQE,WAAaC,GAAeA,EAAYC,SAAS,KAAKC,YAAc,EAAE,EAC/F,CAIA,IAAWoB,QAAM,CAChB,OAAO,KAAKnB,OACb,CAEA,IAAWmB,OAAOA,EAA+B,CAC5CA,EAAQ,KAAKhB,YAAc,WAC1B,KAAKA,WAAa,KAAKA,WAAWkB,QAAQ,WAAY,EAAE,EAC7D,KAAKrB,QAAUmB,CAChB", "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", "SidenavItemModel", "constructor", "config", "counter", "isActive", "activeRoute", "includes", "routerLink", "_parent", "label", "icon", "styleClass", "allowedPermissions", "deniedPermissions", "optionalPermissions", "permissions", "Array", "isArray", "allowed", "required", "optional", "denied", "route", "undefined", "items", "map", "item", "parent", "command", "replace"] }