@fhss-web-team/frontend-utils 4.0.4 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ViewEncapsulation, Component, InjectionToken, inject, signal, computed, Injectable, input, HostListener, linkedSignal, effect, Injector, model, untracked } from '@angular/core';
2
+ import { ViewEncapsulation, Component, InjectionToken, inject, signal, computed, Injectable, input, HostListener, linkedSignal, effect, Injector, model, Directive, untracked } from '@angular/core';
3
3
  import { NgTemplateOutlet } from '@angular/common';
4
4
  import { RouterLink, Router, RedirectCommand } from '@angular/router';
5
5
  import { isTRPCClientError } from '@trpc/client';
@@ -204,23 +204,27 @@ class ByuHeaderComponent {
204
204
  toggleMenu() {
205
205
  this.isMenuOpen.update(prev => !prev);
206
206
  }
207
- onDocumentClick(target) {
208
- if (target.className !== 'nav-item-content') {
209
- this.openDropdown = null;
210
- if (target.className !== 'hamburger' && target.className !== 'bar') {
211
- this.isMenuOpen.set(false);
207
+ onDocumentClick(ev) {
208
+ const path = (ev.composedPath?.() ?? []);
209
+ const target = path[0];
210
+ if (target instanceof Element) {
211
+ if (target.className !== 'nav-item-content') {
212
+ this.openDropdown = null;
213
+ if (target.className !== 'hamburger' && target.className !== 'bar') {
214
+ this.isMenuOpen.set(false);
215
+ }
212
216
  }
213
217
  }
214
218
  }
215
219
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ByuHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
216
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ByuHeaderComponent, isStandalone: true, selector: "byu-header", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event.target)" } }, ngImport: i0, template: "@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\"></byu-header-link>\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\"></byu-header-link>\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\"></byu-header-link>\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\"></byu-header-link>\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div [class]=\"'nav-item dropdown'\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\"></byu-header-link>\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n", styles: [":host{container:byu-header-container/inline-size;z-index:999}.signin{display:flex;align-items:center;gap:10px;font-size:16px;color:#fff;cursor:pointer}.signin .signin-icon{display:flex;margin-right:0;align-items:center;height:20px;width:20px}.signin .signin-link{text-decoration:none}header{color:#fff;--padding: 16px;--logo-extra-padding: 5px;--logo-width: 100px;--title-gap: 8px;--item-padding-block: 16px;--item-padding-inline: 22px;--item-padding: var(--item-padding-block) var(--item-padding-inline);--dropdown-arrow-width: 10px;--sqrt2: 1.414}header .top{background-color:#002e5d;display:flex;align-items:center;padding:var(--padding);padding-left:0}header .top .logo{width:var(--logo-width);height:25px;margin-inline:var(--logo-extra-padding);background-image:url(data:image/png;base64,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);background-size:cover;background-position:center}header .top .titles{display:flex;flex-direction:column;gap:var(--title-gap);padding-left:var(--padding);border-left:1px solid rgba(255,255,255,.25);margin-right:auto}header .top .titles .breadcrumbs byu-header-link{display:inline}header .top .titles .breadcrumbs byu-header-link:not(:first-child){padding-left:10px}header .top .titles .breadcrumbs byu-header-link:not(:last-child){padding-right:10px;border-right:1px solid rgba(255,255,255,.25)}header .top .titles .breadcrumbs:empty{display:none}header .bottom{box-shadow:0 3px 10px #ccc5c580;background-color:#fff}header .bottom nav{display:flex;flex-direction:row;flex-wrap:wrap;padding-left:calc(var(--logo-width) + 2 * var(--logo-extra-padding) + var(--padding) - var(--item-padding-inline))}header .bottom nav .signin{display:none}header .bottom nav .nav-item{display:block;list-style:none;transition:all .25s;text-decoration:none}header .bottom nav .nav-item:hover{box-shadow:inset 0 -5px #002e5d;background-color:#f1f1f1}header .bottom nav .nav-item .nav-item-content{display:inline-block;padding:var(--item-padding);text-decoration:none;color:#002e5d}header .bottom nav .nav-item.dropdown{position:relative;cursor:pointer}header .bottom nav .nav-item.dropdown .nav-item-content{position:relative;padding-right:calc(var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2))}header .bottom nav .nav-item.dropdown .nav-item-content:after{content:\"\";width:var(--dropdown-arrow-width);aspect-ratio:1/1;border-bottom:2px solid #002E5D;border-right:2px solid #002E5D;position:absolute;right:calc((var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2)) / 2);top:50%;transform-origin:75% 75%;transform:translateY(-75%) rotate(45deg);transition:transform .2s ease-in-out}header .bottom nav .nav-item.dropdown.open .nav-item-content:after{transform:translateY(-75%) rotate(225deg)}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:absolute;background:#fff;z-index:1000;top:calc(100% - 5px);padding:0;box-shadow:0 3px 3px #ccc5c5bf}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item:hover{background-color:#f1f1f1}@container byu-header-container (width <= 800px){header{--padding: 12px;--logo-extra-padding: 3px;--title-gap: 2px}header .top .logo{width:65px}header .top .signin{display:none}header .top .hamburger{margin-left:var(--padding)}header .top .hamburger .bar{--width: 28px;--height: 2px;--gap: calc(var(--width) / 3 - var(--height));display:block;width:var(--width);height:var(--height);background-color:#fff;transition:all .2s ease}header .top .hamburger .bar:nth-child(2){margin-block:var(--gap)}header .top .hamburger.open .bar:nth-child(1){transform:translateY(calc(1 * (var(--gap) + var(--height)))) rotate(45deg)}header .top .hamburger.open .bar:nth-child(2){width:0}header .top .hamburger.open .bar:nth-child(3){transform:translateY(calc(-1 * (var(--gap) + var(--height)))) rotate(-45deg)}header .bottom nav{display:none;flex-direction:column;flex-wrap:nowrap;padding-left:0}header .bottom nav.open{display:flex}header .bottom nav .signin{display:flex;color:#002e5d;align-self:end;padding:1em}header .bottom nav .nav-item:hover{box-shadow:inset 5px 0 #002e5d}header .bottom nav .nav-item.dropdown .nav-item-content{display:block}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:static;width:auto;box-shadow:none}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item{padding-left:1em}}\n"], dependencies: [{ kind: "component", type: NormalizedHeaderItem, selector: "byu-header-link", inputs: ["headerItem"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
220
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: ByuHeaderComponent, isStandalone: true, selector: "byu-header", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\"></byu-header-link>\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\"></byu-header-link>\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\"></byu-header-link>\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\"></byu-header-link>\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div class=\"nav-item dropdown\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\"></byu-header-link>\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n", styles: [":host{container:byu-header-container/inline-size;z-index:999}.signin{display:flex;align-items:center;gap:10px;font-size:16px;color:#fff;cursor:pointer}.signin .signin-icon{display:flex;margin-right:0;align-items:center;height:20px;width:20px}.signin .signin-link{text-decoration:none}header{color:#fff;--padding: 16px;--logo-extra-padding: 5px;--logo-width: 100px;--title-gap: 8px;--item-padding-block: 16px;--item-padding-inline: 22px;--item-padding: var(--item-padding-block) var(--item-padding-inline);--dropdown-arrow-width: 6px;--sqrt2: 1.414}header .top{background-color:#002e5d;display:flex;align-items:center;padding:var(--padding);padding-left:0}header .top .logo{width:var(--logo-width);height:25px;margin-inline:var(--logo-extra-padding);background-image:url(data:image/png;base64,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);background-size:cover;background-position:center}header .top .titles{display:flex;flex-direction:column;gap:var(--title-gap);padding-left:var(--padding);border-left:1px solid rgba(255,255,255,.25);margin-right:auto}header .top .titles .breadcrumbs byu-header-link{display:inline}header .top .titles .breadcrumbs byu-header-link:not(:first-child){padding-left:10px}header .top .titles .breadcrumbs byu-header-link:not(:last-child){padding-right:10px;border-right:1px solid rgba(255,255,255,.25)}header .top .titles .breadcrumbs:empty{display:none}header .bottom{box-shadow:0 3px 10px #ccc5c580;background-color:#fff}header .bottom nav{display:flex;flex-direction:row;flex-wrap:wrap;padding-left:calc(var(--logo-width) + 2 * var(--logo-extra-padding) + var(--padding) - var(--item-padding-inline))}header .bottom nav .signin{display:none}header .bottom nav .nav-item{display:block;list-style:none;transition:all .25s;text-decoration:none}header .bottom nav .nav-item:hover{box-shadow:inset 0 -5px #002e5d;background-color:#f1f1f1}header .bottom nav .nav-item .nav-item-content{display:inline-block;padding:var(--item-padding);text-decoration:none;color:#002e5d}header .bottom nav .nav-item.dropdown{position:relative;cursor:pointer}header .bottom nav .nav-item.dropdown .nav-item-content{position:relative;padding-right:calc(var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2))}header .bottom nav .nav-item.dropdown .nav-item-content:after{content:\"\";width:var(--dropdown-arrow-width);aspect-ratio:1/1;border-bottom:2px solid #002E5D;border-right:2px solid #002E5D;position:absolute;right:calc((var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2)) / 2);top:50%;transform-origin:75% 75%;transform:translateY(-75%) rotate(45deg);transition:transform .2s ease-in-out}header .bottom nav .nav-item.dropdown.open .nav-item-content:after{transform:translateY(-75%) rotate(225deg)}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:absolute;background:#fff;z-index:1000;top:calc(100% - 5px);padding:0;box-shadow:0 3px 3px #ccc5c5bf}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item:hover{background-color:#f1f1f1}@container byu-header-container (width <= 800px){header{--padding: 12px;--logo-extra-padding: 3px;--title-gap: 2px}header .top .logo{width:65px}header .top .signin{display:none}header .top .hamburger{margin-left:var(--padding)}header .top .hamburger .bar{--width: 28px;--height: 2px;--gap: calc(var(--width) / 3 - var(--height));display:block;width:var(--width);height:var(--height);background-color:#fff;transition:all .2s ease}header .top .hamburger .bar:nth-child(2){margin-block:var(--gap)}header .top .hamburger.open .bar:nth-child(1){transform:translateY(calc(1 * (var(--gap) + var(--height)))) rotate(45deg)}header .top .hamburger.open .bar:nth-child(2){width:0}header .top .hamburger.open .bar:nth-child(3){transform:translateY(calc(-1 * (var(--gap) + var(--height)))) rotate(-45deg)}header .bottom nav{display:none;flex-direction:column;flex-wrap:nowrap;padding-left:0}header .bottom nav.open{display:flex}header .bottom nav .signin{display:flex;color:#002e5d;align-self:end;padding:1em}header .bottom nav .nav-item:hover{box-shadow:inset 5px 0 #002e5d}header .bottom nav .nav-item.dropdown .nav-item-content{display:block}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:static;width:auto;box-shadow:none}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item{padding-left:1em}}\n"], dependencies: [{ kind: "component", type: NormalizedHeaderItem, selector: "byu-header-link", inputs: ["headerItem"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
217
221
  }
218
222
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ByuHeaderComponent, decorators: [{
219
223
  type: Component,
220
- args: [{ selector: 'byu-header', imports: [NormalizedHeaderItem, NgTemplateOutlet], encapsulation: ViewEncapsulation.ShadowDom, template: "@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\"></byu-header-link>\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\"></byu-header-link>\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\"></byu-header-link>\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\"></byu-header-link>\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div [class]=\"'nav-item dropdown'\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\"></byu-header-link>\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n", styles: [":host{container:byu-header-container/inline-size;z-index:999}.signin{display:flex;align-items:center;gap:10px;font-size:16px;color:#fff;cursor:pointer}.signin .signin-icon{display:flex;margin-right:0;align-items:center;height:20px;width:20px}.signin .signin-link{text-decoration:none}header{color:#fff;--padding: 16px;--logo-extra-padding: 5px;--logo-width: 100px;--title-gap: 8px;--item-padding-block: 16px;--item-padding-inline: 22px;--item-padding: var(--item-padding-block) var(--item-padding-inline);--dropdown-arrow-width: 10px;--sqrt2: 1.414}header .top{background-color:#002e5d;display:flex;align-items:center;padding:var(--padding);padding-left:0}header .top .logo{width:var(--logo-width);height:25px;margin-inline:var(--logo-extra-padding);background-image:url(data:image/png;base64,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);background-size:cover;background-position:center}header .top .titles{display:flex;flex-direction:column;gap:var(--title-gap);padding-left:var(--padding);border-left:1px solid rgba(255,255,255,.25);margin-right:auto}header .top .titles .breadcrumbs byu-header-link{display:inline}header .top .titles .breadcrumbs byu-header-link:not(:first-child){padding-left:10px}header .top .titles .breadcrumbs byu-header-link:not(:last-child){padding-right:10px;border-right:1px solid rgba(255,255,255,.25)}header .top .titles .breadcrumbs:empty{display:none}header .bottom{box-shadow:0 3px 10px #ccc5c580;background-color:#fff}header .bottom nav{display:flex;flex-direction:row;flex-wrap:wrap;padding-left:calc(var(--logo-width) + 2 * var(--logo-extra-padding) + var(--padding) - var(--item-padding-inline))}header .bottom nav .signin{display:none}header .bottom nav .nav-item{display:block;list-style:none;transition:all .25s;text-decoration:none}header .bottom nav .nav-item:hover{box-shadow:inset 0 -5px #002e5d;background-color:#f1f1f1}header .bottom nav .nav-item .nav-item-content{display:inline-block;padding:var(--item-padding);text-decoration:none;color:#002e5d}header .bottom nav .nav-item.dropdown{position:relative;cursor:pointer}header .bottom nav .nav-item.dropdown .nav-item-content{position:relative;padding-right:calc(var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2))}header .bottom nav .nav-item.dropdown .nav-item-content:after{content:\"\";width:var(--dropdown-arrow-width);aspect-ratio:1/1;border-bottom:2px solid #002E5D;border-right:2px solid #002E5D;position:absolute;right:calc((var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2)) / 2);top:50%;transform-origin:75% 75%;transform:translateY(-75%) rotate(45deg);transition:transform .2s ease-in-out}header .bottom nav .nav-item.dropdown.open .nav-item-content:after{transform:translateY(-75%) rotate(225deg)}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:absolute;background:#fff;z-index:1000;top:calc(100% - 5px);padding:0;box-shadow:0 3px 3px #ccc5c5bf}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item:hover{background-color:#f1f1f1}@container byu-header-container (width <= 800px){header{--padding: 12px;--logo-extra-padding: 3px;--title-gap: 2px}header .top .logo{width:65px}header .top .signin{display:none}header .top .hamburger{margin-left:var(--padding)}header .top .hamburger .bar{--width: 28px;--height: 2px;--gap: calc(var(--width) / 3 - var(--height));display:block;width:var(--width);height:var(--height);background-color:#fff;transition:all .2s ease}header .top .hamburger .bar:nth-child(2){margin-block:var(--gap)}header .top .hamburger.open .bar:nth-child(1){transform:translateY(calc(1 * (var(--gap) + var(--height)))) rotate(45deg)}header .top .hamburger.open .bar:nth-child(2){width:0}header .top .hamburger.open .bar:nth-child(3){transform:translateY(calc(-1 * (var(--gap) + var(--height)))) rotate(-45deg)}header .bottom nav{display:none;flex-direction:column;flex-wrap:nowrap;padding-left:0}header .bottom nav.open{display:flex}header .bottom nav .signin{display:flex;color:#002e5d;align-self:end;padding:1em}header .bottom nav .nav-item:hover{box-shadow:inset 5px 0 #002e5d}header .bottom nav .nav-item.dropdown .nav-item-content{display:block}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:static;width:auto;box-shadow:none}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item{padding-left:1em}}\n"] }]
224
+ args: [{ selector: 'byu-header', imports: [NormalizedHeaderItem, NgTemplateOutlet], encapsulation: ViewEncapsulation.ShadowDom, template: "@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\"></byu-header-link>\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\"></byu-header-link>\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\"></byu-header-link>\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\"></byu-header-link>\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div class=\"nav-item dropdown\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\"></byu-header-link>\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n", styles: [":host{container:byu-header-container/inline-size;z-index:999}.signin{display:flex;align-items:center;gap:10px;font-size:16px;color:#fff;cursor:pointer}.signin .signin-icon{display:flex;margin-right:0;align-items:center;height:20px;width:20px}.signin .signin-link{text-decoration:none}header{color:#fff;--padding: 16px;--logo-extra-padding: 5px;--logo-width: 100px;--title-gap: 8px;--item-padding-block: 16px;--item-padding-inline: 22px;--item-padding: var(--item-padding-block) var(--item-padding-inline);--dropdown-arrow-width: 6px;--sqrt2: 1.414}header .top{background-color:#002e5d;display:flex;align-items:center;padding:var(--padding);padding-left:0}header .top .logo{width:var(--logo-width);height:25px;margin-inline:var(--logo-extra-padding);background-image:url(data:image/png;base64,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);background-size:cover;background-position:center}header .top .titles{display:flex;flex-direction:column;gap:var(--title-gap);padding-left:var(--padding);border-left:1px solid rgba(255,255,255,.25);margin-right:auto}header .top .titles .breadcrumbs byu-header-link{display:inline}header .top .titles .breadcrumbs byu-header-link:not(:first-child){padding-left:10px}header .top .titles .breadcrumbs byu-header-link:not(:last-child){padding-right:10px;border-right:1px solid rgba(255,255,255,.25)}header .top .titles .breadcrumbs:empty{display:none}header .bottom{box-shadow:0 3px 10px #ccc5c580;background-color:#fff}header .bottom nav{display:flex;flex-direction:row;flex-wrap:wrap;padding-left:calc(var(--logo-width) + 2 * var(--logo-extra-padding) + var(--padding) - var(--item-padding-inline))}header .bottom nav .signin{display:none}header .bottom nav .nav-item{display:block;list-style:none;transition:all .25s;text-decoration:none}header .bottom nav .nav-item:hover{box-shadow:inset 0 -5px #002e5d;background-color:#f1f1f1}header .bottom nav .nav-item .nav-item-content{display:inline-block;padding:var(--item-padding);text-decoration:none;color:#002e5d}header .bottom nav .nav-item.dropdown{position:relative;cursor:pointer}header .bottom nav .nav-item.dropdown .nav-item-content{position:relative;padding-right:calc(var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2))}header .bottom nav .nav-item.dropdown .nav-item-content:after{content:\"\";width:var(--dropdown-arrow-width);aspect-ratio:1/1;border-bottom:2px solid #002E5D;border-right:2px solid #002E5D;position:absolute;right:calc((var(--item-padding-inline) + var(--dropdown-arrow-width) * var(--sqrt2)) / 2);top:50%;transform-origin:75% 75%;transform:translateY(-75%) rotate(45deg);transition:transform .2s ease-in-out}header .bottom nav .nav-item.dropdown.open .nav-item-content:after{transform:translateY(-75%) rotate(225deg)}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:absolute;background:#fff;z-index:1000;top:calc(100% - 5px);padding:0;box-shadow:0 3px 3px #ccc5c5bf}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item:hover{background-color:#f1f1f1}@container byu-header-container (width <= 800px){header{--padding: 12px;--logo-extra-padding: 3px;--title-gap: 2px}header .top .logo{width:65px}header .top .signin{display:none}header .top .hamburger{margin-left:var(--padding)}header .top .hamburger .bar{--width: 28px;--height: 2px;--gap: calc(var(--width) / 3 - var(--height));display:block;width:var(--width);height:var(--height);background-color:#fff;transition:all .2s ease}header .top .hamburger .bar:nth-child(2){margin-block:var(--gap)}header .top .hamburger.open .bar:nth-child(1){transform:translateY(calc(1 * (var(--gap) + var(--height)))) rotate(45deg)}header .top .hamburger.open .bar:nth-child(2){width:0}header .top .hamburger.open .bar:nth-child(3){transform:translateY(calc(-1 * (var(--gap) + var(--height)))) rotate(-45deg)}header .bottom nav{display:none;flex-direction:column;flex-wrap:nowrap;padding-left:0}header .bottom nav.open{display:flex}header .bottom nav .signin{display:flex;color:#002e5d;align-self:end;padding:1em}header .bottom nav .nav-item:hover{box-shadow:inset 5px 0 #002e5d}header .bottom nav .nav-item.dropdown .nav-item-content{display:block}header .bottom nav .nav-item.dropdown .dropdown-item-menu{position:static;width:auto;box-shadow:none}header .bottom nav .nav-item.dropdown .dropdown-item-menu .dropdown-item{padding-left:1em}}\n"] }]
221
225
  }], propDecorators: { onDocumentClick: [{
222
226
  type: HostListener,
223
- args: ['document:click', ['$event.target']]
227
+ args: ['document:click', ['$event']]
224
228
  }] } });
225
229
 
226
230
  function trpcResource(procedure, input, options) {
@@ -507,6 +511,63 @@ const provideFhss = (config) => ({
507
511
  useValue: config,
508
512
  });
509
513
 
514
+ class ScrollRegistryService {
515
+ anchors = new Map();
516
+ pending = new Map();
517
+ register(key, el) {
518
+ this.anchors.set(key, el);
519
+ const queue = this.pending.get(key);
520
+ if (queue) {
521
+ queue.forEach(fn => fn());
522
+ this.pending.delete(key);
523
+ }
524
+ }
525
+ unregister(key) {
526
+ this.anchors.delete(key);
527
+ }
528
+ scrollTo(key, opts = { behavior: 'smooth', block: 'center' }) {
529
+ const el = this.anchors.get(key);
530
+ if (el)
531
+ el.scrollIntoView(opts);
532
+ else {
533
+ const q = this.pending.get(key) ?? [];
534
+ q.push(() => this.anchors.get(key)?.scrollIntoView(opts));
535
+ this.pending.set(key, q);
536
+ }
537
+ }
538
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ScrollRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
539
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ScrollRegistryService, providedIn: 'root' });
540
+ }
541
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ScrollRegistryService, decorators: [{
542
+ type: Injectable,
543
+ args: [{
544
+ providedIn: 'root',
545
+ }]
546
+ }] });
547
+
548
+ class ScrollAnchorDirective {
549
+ element;
550
+ registery = inject(ScrollRegistryService);
551
+ scrollAnchor = input.required();
552
+ constructor(element) {
553
+ this.element = element;
554
+ }
555
+ ngOnInit() {
556
+ this.registery.register(this.scrollAnchor(), this.element.nativeElement);
557
+ }
558
+ ngOnDestroy() {
559
+ this.registery.unregister(this.scrollAnchor());
560
+ }
561
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ScrollAnchorDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
562
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.15", type: ScrollAnchorDirective, isStandalone: true, selector: "[scrollAnchor]", inputs: { scrollAnchor: { classPropertyName: "scrollAnchor", publicName: "scrollAnchor", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
563
+ }
564
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: ScrollAnchorDirective, decorators: [{
565
+ type: Directive,
566
+ args: [{
567
+ selector: '[scrollAnchor]',
568
+ }]
569
+ }], ctorParameters: () => [{ type: i0.ElementRef }] });
570
+
510
571
  /**
511
572
  * This guard checks if the client is authenticated, redirecting to login if not.
512
573
  */
@@ -825,5 +886,5 @@ fetchSignal.delete.arrayBuffer = createHelper('DELETE', arrayBufferTransformer);
825
886
  * Generated bundle index. Do not edit.
826
887
  */
827
888
 
828
- export { AuthErrorPage, AuthService, ByuFooterComponent, ByuHeaderComponent, ComboBoxComponent, ConfirmationDialog, FHSS_CONFIG, FhssTableComponent, ForbiddenPage, NotFoundPage, ServerErrorPage, authGuard, debounced, debugTrpcResource, fetchSignal, makeTableConfig, permissionGuard, provideFhss, trpcResource };
889
+ export { AuthErrorPage, AuthService, ByuFooterComponent, ByuHeaderComponent, ComboBoxComponent, ConfirmationDialog, FHSS_CONFIG, FhssTableComponent, ForbiddenPage, NotFoundPage, ScrollAnchorDirective, ScrollRegistryService, ServerErrorPage, authGuard, debounced, debugTrpcResource, fetchSignal, makeTableConfig, permissionGuard, provideFhss, trpcResource };
829
890
  //# sourceMappingURL=fhss-web-team-frontend-utils.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fhss-web-team-frontend-utils.mjs","sources":["../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.ts","../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.html","../../../projects/frontend-utils/src/lib/config/lib.config.ts","../../../projects/frontend-utils/src/lib/services/auth/auth.service.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.html","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.html","../../../projects/frontend-utils/src/lib/signals/trpcResource/trpcResource.ts","../../../projects/frontend-utils/src/lib/signals/debounced/debounced.ts","../../../projects/frontend-utils/src/lib/components/fhss-table/fhss-table.types.ts","../../../projects/frontend-utils/src/lib/components/fhss-table/fhss-table.component.ts","../../../projects/frontend-utils/src/lib/components/fhss-table/fhss-table.component.html","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.ts","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.html","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.ts","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.html","../../../projects/frontend-utils/src/lib/config/utils.config.ts","../../../projects/frontend-utils/src/lib/guards/auth/auth.guard.ts","../../../projects/frontend-utils/src/lib/guards/permission/permission.guard.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.html","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.ts","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.html","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.ts","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.html","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.ts","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.html","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.ts","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.html","../../../projects/frontend-utils/src/lib/signals/fetch-signal/fetch-signal.ts","../../../projects/frontend-utils/src/public-api.ts","../../../projects/frontend-utils/src/fhss-web-team-frontend-utils.ts"],"sourcesContent":["import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'byu-footer',\n imports: [],\n templateUrl: './byu-footer.component.html',\n styleUrl: './byu-footer.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuFooterComponent {\n currentYear: number = new Date().getFullYear(); // Automatically updates the year\n}\n","<footer>\n <p class=\"title\"><a href=\"https://www.byu.edu/\">BRIGHAM YOUNG UNIVERSITY</a></p>\n <p>Provo, UT 84602, USA | © {{ currentYear }} All rights reserved.</p>\n <p>\n <a href=\"https://privacy.byu.edu/privacy-notice\">Privacy Notice</a> |\n <a href=\"https://privacy.byu.edu/cookie-prefs\">Cookie Preferences</a>\n </p>\n</footer>\n \n\n","import { InjectionToken } from '@angular/core';\n\nexport const FHSS_CONFIG = new InjectionToken<FhssConfig>('FHSS_CONFIG');\n\nexport interface FhssConfig {\n rolePermissionMap: Record<string, string[]>;\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { FHSS_CONFIG } from '../../config/lib.config';\n\ntype AuthUser = {\n id: string;\n preferredFirstName: string;\n preferredLastName: string;\n roles: string[];\n permissions: string[];\n};\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthService {\n private readonly FhssConfig = inject(FHSS_CONFIG);\n private readonly readyPromise: Promise<AuthUser | null>;\n\n constructor() {\n this.readyPromise = this.whoAmI();\n }\n\n /**\n * Returns a promise that resolves when the authentication service is ready.\n */\n ready() {\n return this.readyPromise;\n }\n\n /**\n * Updates the authentication state by retrieving the current user's information.\n *\n * @returns A promise containing the current user's authentication details.\n */\n update() {\n return this.whoAmI();\n }\n\n readonly authenticated = signal(false);\n readonly userId = signal<string | undefined>(undefined);\n readonly preferredFirstName = signal<string | undefined>(undefined);\n readonly preferredLastName = signal<string | undefined>(undefined);\n readonly roles = signal<string[]>([]);\n readonly permissions = signal<string[]>([]);\n\n /**\n * Contains all of the user's permissions, meaning those explicitly given, as well as \n * those provided by the user's roles.\n *\n * The result is a `Set` containing all unique permissions granted to the user.\n */\n readonly effectivePermissions = computed(() => \n new Set(\n this.roles()\n .flatMap((role) => this.FhssConfig.rolePermissionMap[role])\n .concat(this.permissions())\n )\n );\n\n /**\n * Computes the user's preferred full name by concatenating the preferred first name\n * and, if available, the preferred last name separated by a space.\n * If the preferred first name is not set, an empty string is used.\n * If the preferred last name is not set, only the first name is returned.\n *\n * @returns The computed preferred full name as a string.\n */\n readonly preferredName = computed(() => {\n const prefLast = this.preferredLastName();\n return `${this.preferredFirstName() ?? ''}${prefLast ? ` ${prefLast}` : ''}`;\n });\n\n private resetAuthState() {\n this.authenticated.set(false);\n this.userId.set(undefined);\n this.preferredFirstName.set(undefined);\n this.preferredLastName.set(undefined);\n this.roles.set([]);\n this.permissions.set([]);\n }\n\n private setUser(user: AuthUser) {\n this.authenticated.set(true);\n this.userId.set(user.id);\n this.preferredFirstName.set(user.preferredFirstName);\n this.preferredLastName.set(user.preferredLastName);\n this.roles.set(user.roles);\n this.permissions.set(user.permissions);\n }\n\n /**\n * Redirects the user to the login page.\n *\n * @param nextUri - (Optional) The URI to redirect to after login.\n */\n login(nextUri?: string) {\n window.location.href = `/login${nextUri ? `?next_uri=${nextUri}` : ''}`;\n }\n\n /**\n * Logs the user out by resetting the authentication state and redirecting to the logout page.\n */\n logout() {\n this.resetAuthState();\n window.location.href = '/logout';\n }\n\n /**\n * Retrieves information about the currently authenticated user.\n *\n * @returns A promise that resolves to a `WhoAmI` object \n * representing the current user, or `null` if not authenticated or on error.\n */\n private async whoAmI(): Promise<AuthUser | null> {\n try {\n const res = await fetch('/sys/who-am-i');\n const user = await res.json();\n if (!user) {\n this.resetAuthState();\n return null;\n }\n this.setUser(user);\n return user;\n } catch (error) {\n this.resetAuthState();\n return null;\n }\n }\n}\n","import { Component, computed, input } from \"@angular/core\";\nimport { RouterLink, UrlTree } from \"@angular/router\";\n\nexport type HeaderLink = {\n /** text content of link */\n text: string;\n\n /** \n * If the path is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n};\n\n@Component({\n selector: 'byu-header-link',\n imports: [RouterLink],\n templateUrl: 'byu-header-link.html',\n styleUrl: 'byu-header-link.scss'\n})\nexport class NormalizedHeaderItem {\n headerItem = input.required<HeaderLink | string>();\n\n normalizeHeaderItem = computed(() => {\n const item = this.headerItem();\n if (typeof item === 'string') {\n return {\n text: item,\n routerLink: null,\n href: null,\n newTab: null,\n }\n } else {\n const httpPath = typeof item.path === 'string' && item.path.startsWith('http') ? item.path : null;\n return {\n text: item.text,\n routerLink: httpPath === null ? item.path : null,\n href: httpPath !== null ? httpPath : null,\n newTab: item.newTab ?? false\n }\n }\n })\n}","@let item = normalizeHeaderItem();\n\n@if (item.routerLink) {\n <a [routerLink]=\"item.routerLink\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else if (item.href) {\n <a [href]=\"item.href\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else {\n <a>{{ item.text }}</a>\n}","import { Component, input, inject, signal, HostListener, ViewEncapsulation } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { UrlTree } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { HeaderLink, NormalizedHeaderItem } from './byu-header-link/byu-header-link';\n\ntype MenuLink<T extends string> = {\n /** text content of the link */\n text: string,\n\n /** \n * If the link is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n\n /** list of permissions that a user must have at least one of to see the link */\n requiredPermissions?: T[];\n\n /** if instead the user should have all of the required permissions */\n haveAll?: boolean;\n\n /** if the user must be authenticated to see the link */\n needsAuthentication?: boolean;\n}\n\ntype MenuDropdown<T extends string> = {\n /** text content of the link */\n text: string;\n\n /** items to display in the dropdown menu */\n items: MenuLink<T>[];\n} \n\ntype HeaderMenu<T extends string> = MenuLink<T> | MenuDropdown<T>\n\nexport type HeaderConfig<Permission extends string> = {\n /** Main site title: a link or plain text */\n title: HeaderLink | string;\n\n /** Optional subtitle: a link or plain text */\n subtitle?: HeaderLink | string;\n\n /** Optional breadcrumbs for navigational context: links or plain texts */\n breadcrumbs?: (HeaderLink | string)[];\n\n /** Optional menu items: links or dropdowns, potentially restricted by authentication or permissions */\n menu?: HeaderMenu<Permission>[];\n}\n\n@Component({\n selector: 'byu-header',\n imports: [NormalizedHeaderItem, NgTemplateOutlet],\n templateUrl: './byu-header.component.html',\n styleUrl: './byu-header.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuHeaderComponent {\n auth = inject(AuthService)\n config = input.required<HeaderConfig<string>>();\n\n openDropdown: MenuDropdown<string> | null = null;\n isMenuOpen = signal(false);\n\n isMenuLink(item: HeaderMenu<string>): item is MenuLink<string> {\n return 'path' in item;\n }\n \n isMenuLinkVisible(link: MenuLink<string>) {\n return link.requiredPermissions !== undefined\n ? link.requiredPermissions[link.haveAll ? 'every' : 'some']((permission) => this.auth.effectivePermissions().has(permission))\n : this.auth.authenticated() || !link.needsAuthentication;\n }\n\n isMenuDropdownVisible(dropdown: MenuDropdown<string>) {\n return dropdown.items.some(item => this.isMenuLinkVisible(item));\n }\n \n toggleDropdown(dropdown: MenuDropdown<string>) {\n this.openDropdown = this.openDropdown === dropdown ? null : dropdown;\n }\n\n toggleMenu() {\n this.isMenuOpen.update(prev => !prev)\n }\n\n @HostListener('document:click', ['$event.target'])\n onDocumentClick(target: HTMLElement) {\n if (target.className !== 'nav-item-content') {\n this.openDropdown = null;\n\n if (target.className !== 'hamburger' && target.className !== 'bar') {\n this.isMenuOpen.set(false);\n }\n }\n }\n}\n","@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\"></byu-header-link>\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\"></byu-header-link>\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\"></byu-header-link>\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\"></byu-header-link>\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div [class]=\"'nav-item dropdown'\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\"></byu-header-link>\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n","import { computed, effect, inject, Injector, linkedSignal, signal } from \"@angular/core\";\nimport { isTRPCClientError, Resolver } from \"@trpc/client\";\nimport { ResolverDef, TrpcResource, TrpcResourceOptions } from \"./trpcResource.types\";\n\nfunction trpcResource<TDef extends ResolverDef>(procedure: Resolver<TDef>, input: () => TDef['input'] | undefined, options?: TrpcResourceOptions<TDef['output']>): TrpcResource<TDef> {\n const currentInput = computed(input);\n\n const value = linkedSignal<TDef['output'] | undefined>(options?.valueComputation ?? (() => options?.initialValue ?? options?.defaultValue), { equal: options?.equal });\n const error = signal<TDef['errorShape'] | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n\n if (options?.autoRefresh) {\n effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n // refresh reads currentInput which triggers the effect\n refresh(controller.signal, true);\n }, { injector: options?.injector || inject(Injector)});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort: boolean = true,\n ):Promise<boolean> => {\n // if we have the special case where the current input is undefined\n // then set everything to it's initial state\n if (currentInput() === undefined) {\n value.set(options?.initialValue ?? options?.defaultValue);\n error.set(undefined);\n isLoading.set(false);\n return true;\n }\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n error.set(undefined);\n\n try {\n value.set(await procedure(currentInput(), {\n signal: abortSignal\n }));\n error.set(undefined)\n } catch (err) {\n if (isTRPCClientError(err)) {\n // if the trpc request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.cause?.name === 'AbortError' && keepLoadingThroughAbort) {\n return false;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n console.error(\"A non-tRPC error has occured on this trpcResource: \", String(err));\n }\n value.set(options?.defaultValue);\n }\n isLoading.set(false);\n return !error();\n }\n\n return {\n value,\n error,\n isLoading,\n refresh\n };\n}\n\nfunction debugTrpcResource<TDef extends ResolverDef>(_trpcResource: TrpcResource<TDef>) {\n return {\n value: _trpcResource.value(),\n error: _trpcResource.error(),\n isLoading: _trpcResource.isLoading(),\n }\n}\n\nexport { debugTrpcResource, trpcResource };","import { effect, signal, Signal } from '@angular/core';\n\nexport const debounced = <T>(inputSignal: Signal<T>, wait: number = 400) => {\n const debouncedSignal = signal<T>(inputSignal());\n const setSignal = debounce(value => debouncedSignal.set(value), wait);\n\n effect(() => {\n setSignal(inputSignal());\n });\n\n return debouncedSignal;\n};\n\nconst debounce = (callback: (...args: any[]) => void, wait: number) => {\n let timeoutId: number | undefined;\n return (...args: any[]) => {\n window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(() => {\n callback(...args);\n }, wait);\n };\n};\n","import { Resolver } from '@trpc/client';\nimport { ResolverDef } from '../../signals/trpcResource/trpcResource.types';\nimport { trpcResource } from '../../signals/trpcResource/trpcResource';\n\nexport type FhssTableConfig<TDef extends ResolverDef> = {\n procedure: Resolver<TDef>;\n columns: {\n [K in keyof TDef['output']['data'][number]]: {\n hide?: boolean;\n header?: string;\n allowSort?: boolean;\n individualFilter?: boolean;\n };\n };\n showSearch?: boolean;\n sorting: {\n defaultSortBy: Extract<keyof TDef['output']['data'][number], string>;\n defaultSortDirection?: 'asc' | 'desc';\n };\n pagination: {\n pageSize: number;\n hideControls?: boolean;\n };\n disableAlternatingColors?: boolean;\n interaction?:\n | {\n type: 'click';\n onClick: (obj: TDef['output']['data'][number]) => void;\n }\n | {\n type: 'select';\n multi?: boolean;\n };\n};\n\nexport const makeTableConfig = <TDef extends ResolverDef>(config: FhssTableConfig<TDef>) => config;\n\nexport type AnyResolver = {\n input: any;\n output: { totalCount: number; data: any[] };\n transformer: any;\n errorShape: {\n code: any;\n message: string;\n data: any;\n };\n};\n\nexport type AnyResource = ReturnType<typeof trpcResource<AnyResolver>>;\n","import {\n Component,\n inject,\n Injector,\n input,\n linkedSignal,\n model,\n OnInit,\n signal,\n} from '@angular/core';\nimport { trpcResource } from '../../signals/trpcResource/trpcResource';\nimport { debounced } from '../../signals/debounced/debounced';\nimport { FhssTableConfig, AnyResolver, AnyResource } from './fhss-table.types';\nexport { makeTableConfig } from './fhss-table.types';\n\nimport { MatTableModule } from '@angular/material/table';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatPaginatorModule, PageEvent } from '@angular/material/paginator';\nimport { MatInputModule } from '@angular/material/input';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatSortModule, Sort } from '@angular/material/sort';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatRippleModule } from '@angular/material/core';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { SelectionModel } from '@angular/cdk/collections';\n\n@Component({\n selector: 'fhss-table',\n imports: [\n MatTableModule,\n MatProgressSpinnerModule,\n MatPaginatorModule,\n MatInputModule,\n FormsModule,\n MatButtonModule,\n MatSortModule,\n MatIconModule,\n MatRippleModule,\n MatCheckboxModule,\n ],\n templateUrl: './fhss-table.component.html',\n styleUrl: './fhss-table.component.scss',\n})\nexport class FhssTableComponent implements OnInit {\n private injector = inject(Injector);\n\n config = input.required<FhssTableConfig<AnyResolver>>();\n miscParams = input<Record<string, any>>({});\n\n columnKeys: string[] = [];\n columnsToDisplay: string[] = [];\n selection: SelectionModel<any> | undefined;\n selectedValues = model<any[]>([]);\n\n dataResource!: AnyResource;\n refresh() {\n this.dataResource.refresh()\n }\n\n ngOnInit() {\n const cfg = this.config();\n\n this.columnKeys = Object.keys(cfg.columns);\n this.columnsToDisplay = this.columnKeys.filter((k) => !cfg.columns[k].hide);\n\n if (cfg.interaction?.type === 'select') {\n this.columnsToDisplay.unshift('table-checkbox-column');\n this.selection = new SelectionModel<any>(\n cfg.interaction.multi,\n undefined,\n undefined,\n (o1, o2) => o1.id === o2.id,\n );\n }\n\n this.dataResource = trpcResource(\n this.config().procedure,\n () => ({\n search: this.debouncedSearch(),\n filters: this.debouncedFilters(),\n sort: {\n property: this.sortBy(),\n direction: this.sortDirection(),\n },\n page: {\n size: this.config().pagination.pageSize,\n index: this.pageIndex(),\n },\n ...this.miscParams(),\n }),\n {\n autoRefresh: true,\n injector: this.injector,\n },\n );\n }\n\n search = signal('');\n debouncedSearch = debounced(this.search);\n filters = signal<Record<string, string>>({});\n debouncedFilters = debounced(this.filters);\n\n sortBy = linkedSignal(() => this.config().sorting.defaultSortBy);\n sortDirection = linkedSignal<'asc' | 'desc'>(\n () => this.config().sorting.defaultSortDirection ?? 'asc',\n );\n\n pageIndex = linkedSignal(() => {\n this.search();\n return 0;\n });\n\n onFilterChange(col: string, val: string) {\n this.filters.update((f) => ({ ...f, [col]: val }));\n }\n onPaginationChange(e: PageEvent) {\n this.pageIndex.set(e.pageIndex);\n }\n onSortChange(sort: Sort) {\n this.sortBy.set(sort.active || this.config().sorting.defaultSortBy);\n this.sortDirection.set(\n sort.direction || this.config().sorting.defaultSortDirection || 'asc',\n );\n this.pageIndex.set(0);\n }\n onSelectionChange() {\n this.selectedValues.set(this.selection?.selected ?? []);\n }\n\n onRowClick(row: any) {\n const interaction = this.config().interaction;\n if (!interaction) return;\n\n if (interaction.type === 'click') {\n interaction.onClick(row);\n } else if (interaction.type === 'select') {\n this.selection?.toggle(row);\n }\n this.onSelectionChange();\n }\n\n isAllSelected() {\n if (!this.selection) return false;\n const numSelected = this.selection.selected.length;\n const numRows = this.dataResource.value()?.data?.length ?? 0;\n return numSelected === numRows;\n }\n\n toggleAllRows() {\n if (!this.selection) return;\n if (this.isAllSelected()) {\n this.selection.clear();\n } else {\n this.selection.select(...(this.dataResource.value()?.data ?? []));\n }\n this.onSelectionChange();\n }\n\n checkboxLabel(row?: any): string {\n if (!this.selection) return '';\n if (!row) {\n return `${this.isAllSelected() ? 'deselect' : 'select'} all`;\n }\n return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;\n }\n\n protected isBoolean = (val: unknown) => typeof val === 'boolean';\n}\n","<div class=\"table-container\">\n @if (dataResource.isLoading() || dataResource.error()) {\n <div class=\"shade\">\n @if (dataResource.isLoading()) {\n <mat-spinner />\n }\n @if (dataResource.error()) {\n <div class=\"msg-bkgd\">\n <div class=\"error-msg\">There was an error retrieving this data</div>\n <button mat-button (click)=\"this.dataResource.refresh()\">\n Retry\n </button>\n </div>\n }\n </div>\n }\n\n @if (config().showSearch) {\n <mat-form-field\n class=\"search\"\n subscriptSizing=\"dynamic\"\n appearance=\"outline\">\n <input matInput [(ngModel)]=\"search\" placeholder=\"Find...\" />\n @if (search()) {\n <button\n matSuffix\n mat-icon-button\n aria-label=\"Clear\"\n (click)=\"search.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n }\n\n <div class=\"other-controls\">\n <ng-content />\n </div>\n\n <table\n mat-table\n [dataSource]=\"dataResource.value()?.data ?? []\"\n matSort\n [matSortActive]=\"sortBy()\"\n [matSortDirection]=\"sortDirection()\"\n (matSortChange)=\"onSortChange($event)\"\n matSortDisableClear>\n @if (selection) {\n <ng-container matColumnDef=\"table-checkbox-column\">\n <mat-header-cell *matHeaderCellDef>\n @if (selection.isMultipleSelection()) {\n <mat-checkbox\n (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\" />\n } @else {\n <mat-checkbox disabled style=\"visibility: hidden\"></mat-checkbox>\n }\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? onRowClick(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\" />\n </mat-cell>\n </ng-container>\n }\n\n @for (key of columnKeys; track key) {\n <ng-container [matColumnDef]=\"key\">\n <mat-header-cell\n *matHeaderCellDef\n mat-sort-header\n [disabled]=\"!config().columns[key].allowSort\">\n <div class=\"header\">\n {{ config().columns[key].header || key }}\n @if (config().columns[key].individualFilter) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <input\n matInput\n (click)=\"$event.stopPropagation()\"\n [ngModel]=\"filters()[key] || ''\"\n (ngModelChange)=\"onFilterChange(key, $event)\"\n placeholder=\"Filter...\" />\n @if (filters()[key]) {\n <button\n matSuffix\n mat-icon-button\n aria-label=\"Clear\"\n (click)=\"onFilterChange(key, '')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n }\n </div>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n @if (isBoolean(row[key])) {\n <mat-checkbox [checked]=\"row[key]\" [disabled]=\"true\" />\n } @else {\n {{ row[key] }}\n }\n </mat-cell>\n </ng-container>\n }\n\n <mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></mat-header-row>\n @if (config().interaction) {\n <mat-row\n matRipple\n (click)=\"onRowClick(row)\"\n *matRowDef=\"let row; columns: columnsToDisplay; let even = even\"\n [class]=\"{\n alternating: !config().disableAlternatingColors,\n even: even,\n interactive: true,\n }\">\n </mat-row>\n } @else {\n <mat-row\n *matRowDef=\"let row; columns: columnsToDisplay; let even = even\"\n [class]=\"{\n alternating: !config().disableAlternatingColors,\n even: even,\n }\">\n </mat-row>\n }\n\n <tr class=\"mat-row\" *matNoDataRow>\n <td class=\"mat-cell\">\n <div class=\"no-data\">\n No data found\n <button mat-button (click)=\"this.dataResource.refresh()\">\n Retry\n </button>\n </div>\n </td>\n </tr>\n </table>\n\n @if (!config().pagination.hideControls) {\n <mat-paginator\n [length]=\"dataResource.value()?.totalCount\"\n [showFirstLastButtons]=\"true\"\n [pageSize]=\"config().pagination.pageSize\"\n [hidePageSize]=\"true\"\n [pageIndex]=\"pageIndex()\"\n [disabled]=\"dataResource.isLoading()\"\n (page)=\"onPaginationChange($event)\" />\n }\n</div>\n","import { Component, inject, Injectable } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogModule,\n MAT_DIALOG_DATA,\n MatDialog,\n} from '@angular/material/dialog';\n\ntype ConfirmationConfig =\n | {\n title?: string;\n action?: string;\n description?: never;\n buttons?: readonly string[];\n }\n | {\n title?: string;\n action?: never;\n description?: string;\n buttons?: readonly string[];\n };\n\ntype ConfirmationResult<C extends ConfirmationConfig | undefined> = C extends {\n buttons: readonly string[];\n}\n ? C['buttons'][number]\n : boolean;\n\n@Component({\n selector: 'fhss-confirmation',\n imports: [MatDialogModule, MatButtonModule],\n templateUrl: './confirmation.dialog.html',\n styleUrl: './confirmation.dialog.scss',\n})\nclass ConfirmationDialogContainer {\n protected readonly config: ConfirmationConfig | undefined =\n inject(MAT_DIALOG_DATA);\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ConfirmationDialog {\n private readonly dialog = inject(MatDialog);\n\n open<C extends ConfirmationConfig | undefined>(config?: C) {\n const dialogRef = this.dialog.open<\n ConfirmationDialogContainer,\n ConfirmationConfig,\n ConfirmationResult<C>\n >(ConfirmationDialogContainer, {\n data: config,\n });\n\n return dialogRef;\n }\n}\n","<h2 mat-dialog-title>{{ config?.title ?? \"Are you sure?\"}}</h2>\n\n<mat-dialog-content>\n @if (config?.description) {\n <p>{{ config?.description }}</p>\n } @else {\n <p>Are you sure you would like to {{ config?.action ?? 'continue' }}?</p>\n }</mat-dialog-content\n>\n\n<mat-dialog-actions>\n @if (config?.buttons) { @for (name of config?.buttons; track name) {\n <button mat-button [mat-dialog-close]=\"name\">{{name}}</button>\n } } @else {\n <button mat-button [mat-dialog-close]=\"false\">No</button>\n <button mat-button [mat-dialog-close]=\"true\">Yes</button>\n }\n</mat-dialog-actions>\n","import { Component, input, model, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\n\ntype value = string | number;\nexport type Option = { label: string; value: value | null };\n\ntype Boolish = string | boolean | undefined;\nfunction fromBoolish(v: Boolish): boolean {\n if (v === undefined || v === false) return false;\n if (typeof v === 'string') {\n return v.trim().toLowerCase() !== 'false';\n }\n return true;\n}\n\n@Component({\n selector: 'fhss-combo-box',\n imports: [\n MatSelectModule,\n MatButtonModule,\n MatIconModule,\n MatFormFieldModule,\n MatInputModule,\n FormsModule,\n ],\n templateUrl: './combo-box.component.html',\n styleUrl: './combo-box.component.scss',\n})\nexport class ComboBoxComponent {\n options = input.required<Option[]>();\n placeholder = input.required<string>();\n appearance = input<'outline' | 'fill'>('fill');\n multiple = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n showClear = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n\n /**\n * Takes a signal to store the selected value(s) in.\n */\n selected = model.required<value[] | value | null>();\n\n filter = signal('');\n protected isOptionHidden = (opt: Option) =>\n !opt.label.toLowerCase().includes(this.filter().toLowerCase());\n\n clearSelected() {\n if (Array.isArray(this.selected())) {\n this.selected.set([]);\n } else {\n this.selected.set(null);\n }\n }\n}\n","<mat-form-field\n (click)=\"filter.set('')\"\n [appearance]=\"appearance()\"\n subscriptSizing=\"dynamic\">\n <mat-label>{{ placeholder() }}</mat-label>\n <mat-select [(ngModel)]=\"selected\" [multiple]=\"multiple()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <input matInput placeholder=\"Search...\" [(ngModel)]=\"filter\" />\n <button mat-icon-button matSuffix (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n @for (option of options(); track option.value) {\n <mat-option\n [value]=\"option.value\"\n [class.hidden]=\"isOptionHidden(option)\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n\n @if (showClear()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"$event.stopPropagation(); clearSelected()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n</mat-form-field>\n","import { Provider } from \"@angular/core\";\nimport { FHSS_CONFIG, FhssConfig } from \"./lib.config\";\n\nexport const provideFhss = (config: FhssConfig): Provider => ({\n provide: FHSS_CONFIG,\n useValue: config,\n});\n","import { inject } from '@angular/core';\nimport { CanActivateFn } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\n\n/**\n * This guard checks if the client is authenticated, redirecting to login if not.\n */\nexport const authGuard: CanActivateFn = async (_route, state) => {\n const authService = inject(AuthService);\n if (!await authService.ready()) {\n authService.login(state.url);\n return false;\n }\n return true;\n};\n","import { CanActivateFn, RedirectCommand, Router } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { inject } from '@angular/core';\n\n/**\n * A permission-based route guard.\n *\n * This guard checks if the current user has the required permissions to access a route.\n * If the user is not authenticated, they are redirected to the login page.\n * If the user lacks the necessary permissions, they are redirected to the `/forbidden` page.\n *\n * Pass the Permission type to get intellisense on requiredPermissions\n * @param requiredPermissions - An array of permission strings that the user must have.\n * @param haveAll - If `true`, the user must have all required permissions. If `false` or omitted, the user must have at least one of the required permissions.\n * @returns A `CanActivateFn` function to be used as a route guard.\n * \n * @example\n * ```typescript\n * const routes: Routes = [\n * {\n * path: 'admin',\n * component: AdminPage,\n * canActivate: [permissionGuard<Permission>(['manage-users', 'see-data'], true)],\n * },\n * ];\n * ```\n */\nexport const permissionGuard: <Permission extends string>(\n requiredPermissions: Permission[],\n haveAll?: boolean,\n) => CanActivateFn = (reqPerms, haveAll) => {\n return async (_route, state) => {\n const router = inject(Router);\n const authService = inject(AuthService);\n\n if (!await authService.ready()) {\n authService.login(state.url);\n return false;\n }\n\n const hasAccess = reqPerms[haveAll ? 'every' : 'some']((role) =>\n authService.effectivePermissions().has(role),\n );\n\n return hasAccess || new RedirectCommand(router.parseUrl('/forbidden'));\n };\n};\n","import { Component, input } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport type SystemConfig = {\n title?: string,\n message?: string,\n image?: string\n}\n\n@Component({\n selector: 'fhss-system',\n imports: [MatButtonModule],\n templateUrl: './system.page.html',\n styleUrl: './system.page.scss',\n})\nexport class SystemPage {\n readonly config = input.required<SystemConfig>();\n}\n","@let title = config().title;\n@let message = config().message;\n@let image = config().image;\n\n<div class=\"container\">\n @if (image) {\n <div [class]=\"['image', image]\"></div>\n }\n <h1>{{title ? title : 'Application Error'}}</h1>\n <p>{{message ? message : 'Oops! Something went wrong!'}}</p>\n <a mat-flat-button href=\"/\">Go back home</a>\n</div>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from \"../system/system.page\";\n\n@Component({\n selector: 'fhss-auth-error',\n imports: [SystemPage],\n templateUrl: './auth-error.page.html',\n styleUrl: './auth-error.page.scss'\n})\nexport class AuthErrorPage {\n protected readonly config: SystemConfig = {\n title: 'Login Failed',\n message: 'Something went wrong while trying to log you in.',\n image: 'sad-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-forbidden',\n imports: [SystemPage],\n templateUrl: './forbidden.page.html',\n styleUrl: './forbidden.page.scss',\n})\nexport class ForbiddenPage {\n protected readonly config: SystemConfig = {\n title: \"403 - Forbidden\",\n message: \"You don't have permission to access this page.\",\n image: 'police-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from '../system/system.page';\n\n@Component({\n selector: 'fhss-not-found',\n imports: [SystemPage],\n templateUrl: './not-found.page.html',\n styleUrl: './not-found.page.scss',\n})\nexport class NotFoundPage {\n protected readonly config: SystemConfig = {\n title: \"404 - Page not found\",\n message: \"The page you are looking for doesn't exist or it may have moved.\",\n image: 'confused-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-server-error',\n imports: [SystemPage],\n templateUrl: './server-error.page.html',\n styleUrl: './server-error.page.scss',\n})\nexport class ServerErrorPage {\n protected readonly config: SystemConfig = {\n title: \"500 - Internal Server Error\",\n message: \"We ran into an unexpected error!\",\n image: 'error-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { computed, effect, EffectRef, inject, Injector, signal, untracked } from '@angular/core';\nimport { FetchSignal, FetchSignalFactory, FetchSignalOptions, FetchSignalRequest, FetchSignalStatus, HttpMethod, Json, ResponseTransformer } from './fetch-signal.types';\n\n\n/**\n * Creates a reactive fetch signal.\n *\n * The request function can include Signals for properties. These are unwrapped in the refresh function.\n */\nfunction createFetchSignal<Response, ErrorResponse, RawResponse>(\n request: () => FetchSignalRequest,\n method: HttpMethod,\n transform: ResponseTransformer<Response>,\n options?: FetchSignalOptions<Response, RawResponse>,\n): FetchSignal<Response, ErrorResponse> {\n // Use a computed signal so that any changes to Signals in the request object trigger updates.\n const currentRequest = computed<FetchSignalRequest>(request);\n\n const value = signal<Response | undefined>(options?.defaultValue, { equal: options?.equal });\n const errorResponse = signal<ErrorResponse | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n const statusCode = signal<number | undefined>(undefined);\n const headers = signal<Record<string, string> | undefined>(undefined);\n\n const status = signal<FetchSignalStatus>('idle');\n const error = signal<Error | undefined>(undefined);\n\n const injector = inject(Injector);\n let effectRef: EffectRef | undefined = undefined;\n if (options?.autoRefresh) {\n effectRef = effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n refresh(controller.signal, true);\n }, { injector: options?.injector || injector});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort?: boolean,\n ) => {\n // if the fetchSignal has been destroyed, do nothing\n if (untracked(status) === 'destroyed') return;\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n errorResponse.set(undefined);\n statusCode.set(undefined);\n headers.set(undefined);\n status.set('loading');\n error.set(undefined);\n\n // Unwrap the current request.\n const req = currentRequest();\n const url = req.url;\n const params = req.params;\n const requestHeaders = req.headers;\n const body = req.body;\n\n // Build URL with query parameters.\n let uri = url;\n if (params) {\n const searchParams = new URLSearchParams();\n for (const key in params) {\n if (params[key] !== undefined)\n searchParams.append(key, String(params[key]));\n }\n uri += (uri.includes('?') ? '&' : '?') + searchParams.toString();\n }\n \n // Filter out undefined header values\n const filteredHeaders = requestHeaders\n ? Object.fromEntries(\n Object.entries(requestHeaders).filter(\n ([, value]) => value !== undefined\n ) as [string, string][]\n )\n : undefined;\n \n try {\n // send the request\n const response = await fetch(uri, {\n method,\n headers: filteredHeaders,\n // Only include a body if one is provided.\n body: body,\n signal: abortSignal,\n });\n\n // set the status code\n statusCode.set(response.status);\n\n // Extract response headers.\n const headersObj: Record<string, string> = {};\n response.headers.forEach((val, key) => {\n headersObj[key] = val;\n });\n headers.set(headersObj);\n\n // if the response is ok, transform the body\n if (response.ok) {\n value.set(await transform(response));\n status.set('resolved');\n } else {\n // try to parse the error as json\n try {\n errorResponse.set(await response.json());\n value.set(undefined);\n status.set('resolved');\n } catch {\n throw new Error('Unable to parse error response.')\n }\n }\n } catch (err: any) {\n if (err instanceof Error) {\n // if the fetch request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.name === 'AbortError' && keepLoadingThroughAbort) {\n return;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n error.set(new Error(String(err)));\n }\n value.set(undefined);\n status.set('error');\n }\n isLoading.set(false);\n };\n\n const destroy = () => {\n // if the fetchSignal has been destroyed, do nothing\n if (status() === 'destroyed') return;\n\n if (effectRef) {\n effectRef.destroy();\n }\n status.set('destroyed');\n value.set(undefined);\n errorResponse.set(undefined);\n isLoading.set(false);\n statusCode.set(undefined);\n headers.set(undefined);\n error.set(undefined);\n }\n\n return {\n value,\n errorResponse,\n isLoading,\n statusCode,\n headers,\n status,\n error,\n refresh,\n destroy\n };\n}\n\n//\n// Helpers for attaching response transforms.\n//\nconst createHelper = <Response, Error>(method: HttpMethod, transform: ResponseTransformer<Response>) =>\n (request: () => FetchSignalRequest, options?: FetchSignalOptions<Response, any>): FetchSignal<Response, Error> =>\n createFetchSignal<Response, Error, any>(request, method, transform, options);\n\n// Transforms\nconst jsonTransformer: ResponseTransformer<any> = (response: Response) => response.json();\nconst textTransformer: ResponseTransformer<string> = (response: Response) => response.text();\nconst blobTransformer: ResponseTransformer<Blob> = (response: Response) => response.blob();\nconst arrayBufferTransformer: ResponseTransformer<ArrayBuffer> = (response: Response) => response.arrayBuffer();\n\n//\n// Build the defaults - GET chain\n//\nconst fetchSignal = createHelper('GET', jsonTransformer) as FetchSignalFactory;\nfetchSignal.json = createHelper('GET', jsonTransformer);\nfetchSignal.text = createHelper('GET', textTransformer);\nfetchSignal.blob = createHelper('GET', blobTransformer);\nfetchSignal.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the GET chain\n//\nfetchSignal.get = createHelper(\n 'GET',\n jsonTransformer,\n) as FetchSignalFactory['get'];\nfetchSignal.get.json = createHelper('GET', jsonTransformer);\nfetchSignal.get.text = createHelper('GET', textTransformer);\nfetchSignal.get.blob = createHelper('GET', blobTransformer);\nfetchSignal.get.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the POST chain.\n//\nfetchSignal.post = createHelper(\n 'POST',\n jsonTransformer,\n) as FetchSignalFactory['post'];\nfetchSignal.post.json = createHelper('POST', jsonTransformer);\nfetchSignal.post.text = createHelper('POST', textTransformer);\nfetchSignal.post.blob = createHelper('POST', blobTransformer);\nfetchSignal.post.arrayBuffer = createHelper('POST', arrayBufferTransformer);\n\n//\n// Build the PUT chain.\n//\nfetchSignal.put = createHelper(\n 'PUT',\n jsonTransformer,\n) as FetchSignalFactory['put'];\nfetchSignal.put.json = createHelper('PUT', jsonTransformer);\nfetchSignal.put.text = createHelper('PUT', textTransformer);\nfetchSignal.put.blob = createHelper('PUT', blobTransformer);\nfetchSignal.put.arrayBuffer = createHelper('PUT', arrayBufferTransformer);\n\n//\n// Build the PATCH chain.\n//\nfetchSignal.patch = createHelper(\n 'PATCH',\n jsonTransformer,\n) as FetchSignalFactory['patch'];\nfetchSignal.patch.json = createHelper('PATCH', jsonTransformer);\nfetchSignal.patch.text = createHelper('PATCH', textTransformer);\nfetchSignal.patch.blob = createHelper('PATCH', blobTransformer);\nfetchSignal.patch.arrayBuffer = createHelper('PATCH', arrayBufferTransformer);\n\n//\n// Build the DELETE chain\n//\nfetchSignal.delete = createHelper(\n 'DELETE',\n jsonTransformer,\n) as FetchSignalFactory['delete'];\nfetchSignal.delete.json = createHelper('DELETE', jsonTransformer);\nfetchSignal.delete.text = createHelper('DELETE', textTransformer);\nfetchSignal.delete.blob = createHelper('DELETE', blobTransformer);\nfetchSignal.delete.arrayBuffer = createHelper('DELETE', arrayBufferTransformer);\n\nexport { fetchSignal };\nexport type { Json };\n\n","/**\n * Components\n */\nexport * from './lib/components/byu-footer/byu-footer.component';\nexport { ByuHeaderComponent } from './lib/components/byu-header/byu-header.component';\nexport type { HeaderConfig } from './lib/components/byu-header/byu-header.component';\nexport * from './lib/components/fhss-table/fhss-table.component';\nexport * from './lib/components/confirmation/confirmation.dialog';\nexport * from './lib/components/combo-box/combo-box.component';\n\n/**\n * Config\n */\nexport * from './lib/config/lib.config';\nexport * from './lib/config/utils.config';\n\n/**\n * Guards\n */\nexport * from './lib/guards/auth/auth.guard';\nexport * from './lib/guards/permission/permission.guard';\n\n/**\n * Pages\n */\nexport * from './lib/pages/auth-error/auth-error.page';\nexport * from './lib/pages/forbidden/forbidden.page';\nexport * from './lib/pages/not-found/not-found.page';\nexport * from './lib/pages/server-error/server-error.page';\n\n/**\n * Services\n */\nexport * from './lib/services/auth/auth.service';\n\n/**\n * Signals\n */\nexport * from './lib/signals/trpcResource/trpcResource';\nexport * from './lib/signals/fetch-signal/fetch-signal';\nexport * from './lib/signals/debounced/debounced';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i1","i3","i4"],"mappings":"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"}
1
+ {"version":3,"file":"fhss-web-team-frontend-utils.mjs","sources":["../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.ts","../../../projects/frontend-utils/src/lib/components/byu-footer/byu-footer.component.html","../../../projects/frontend-utils/src/lib/config/lib.config.ts","../../../projects/frontend-utils/src/lib/services/auth/auth.service.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header-link/byu-header-link.html","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.ts","../../../projects/frontend-utils/src/lib/components/byu-header/byu-header.component.html","../../../projects/frontend-utils/src/lib/signals/trpcResource/trpcResource.ts","../../../projects/frontend-utils/src/lib/signals/debounced/debounced.ts","../../../projects/frontend-utils/src/lib/components/fhss-table/fhss-table.types.ts","../../../projects/frontend-utils/src/lib/components/fhss-table/fhss-table.component.ts","../../../projects/frontend-utils/src/lib/components/fhss-table/fhss-table.component.html","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.ts","../../../projects/frontend-utils/src/lib/components/confirmation/confirmation.dialog.html","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.ts","../../../projects/frontend-utils/src/lib/components/combo-box/combo-box.component.html","../../../projects/frontend-utils/src/lib/config/utils.config.ts","../../../projects/frontend-utils/src/lib/services/scroll-registry/scroll-registry.service.ts","../../../projects/frontend-utils/src/lib/directives/scroll-anchor.directive.ts","../../../projects/frontend-utils/src/lib/guards/auth/auth.guard.ts","../../../projects/frontend-utils/src/lib/guards/permission/permission.guard.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.ts","../../../projects/frontend-utils/src/lib/pages/system/system.page.html","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.ts","../../../projects/frontend-utils/src/lib/pages/auth-error/auth-error.page.html","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.ts","../../../projects/frontend-utils/src/lib/pages/forbidden/forbidden.page.html","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.ts","../../../projects/frontend-utils/src/lib/pages/not-found/not-found.page.html","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.ts","../../../projects/frontend-utils/src/lib/pages/server-error/server-error.page.html","../../../projects/frontend-utils/src/lib/signals/fetch-signal/fetch-signal.ts","../../../projects/frontend-utils/src/public-api.ts","../../../projects/frontend-utils/src/fhss-web-team-frontend-utils.ts"],"sourcesContent":["import { Component, ViewEncapsulation } from '@angular/core';\n\n@Component({\n selector: 'byu-footer',\n imports: [],\n templateUrl: './byu-footer.component.html',\n styleUrl: './byu-footer.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuFooterComponent {\n currentYear: number = new Date().getFullYear(); // Automatically updates the year\n}\n","<footer>\n <p class=\"title\"><a href=\"https://www.byu.edu/\">BRIGHAM YOUNG UNIVERSITY</a></p>\n <p>Provo, UT 84602, USA | © {{ currentYear }} All rights reserved.</p>\n <p>\n <a href=\"https://privacy.byu.edu/privacy-notice\">Privacy Notice</a> |\n <a href=\"https://privacy.byu.edu/cookie-prefs\">Cookie Preferences</a>\n </p>\n</footer>\n \n\n","import { InjectionToken } from '@angular/core';\n\nexport const FHSS_CONFIG = new InjectionToken<FhssConfig>('FHSS_CONFIG');\n\nexport interface FhssConfig {\n rolePermissionMap: Record<string, string[]>;\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { FHSS_CONFIG } from '../../config/lib.config';\n\ntype AuthUser = {\n id: string;\n preferredFirstName: string;\n preferredLastName: string;\n roles: string[];\n permissions: string[];\n};\n\n@Injectable({\n providedIn: 'root',\n})\nexport class AuthService {\n private readonly FhssConfig = inject(FHSS_CONFIG);\n private readonly readyPromise: Promise<AuthUser | null>;\n\n constructor() {\n this.readyPromise = this.whoAmI();\n }\n\n /**\n * Returns a promise that resolves when the authentication service is ready.\n */\n ready() {\n return this.readyPromise;\n }\n\n /**\n * Updates the authentication state by retrieving the current user's information.\n *\n * @returns A promise containing the current user's authentication details.\n */\n update() {\n return this.whoAmI();\n }\n\n readonly authenticated = signal(false);\n readonly userId = signal<string | undefined>(undefined);\n readonly preferredFirstName = signal<string | undefined>(undefined);\n readonly preferredLastName = signal<string | undefined>(undefined);\n readonly roles = signal<string[]>([]);\n readonly permissions = signal<string[]>([]);\n\n /**\n * Contains all of the user's permissions, meaning those explicitly given, as well as \n * those provided by the user's roles.\n *\n * The result is a `Set` containing all unique permissions granted to the user.\n */\n readonly effectivePermissions = computed(() => \n new Set(\n this.roles()\n .flatMap((role) => this.FhssConfig.rolePermissionMap[role])\n .concat(this.permissions())\n )\n );\n\n /**\n * Computes the user's preferred full name by concatenating the preferred first name\n * and, if available, the preferred last name separated by a space.\n * If the preferred first name is not set, an empty string is used.\n * If the preferred last name is not set, only the first name is returned.\n *\n * @returns The computed preferred full name as a string.\n */\n readonly preferredName = computed(() => {\n const prefLast = this.preferredLastName();\n return `${this.preferredFirstName() ?? ''}${prefLast ? ` ${prefLast}` : ''}`;\n });\n\n private resetAuthState() {\n this.authenticated.set(false);\n this.userId.set(undefined);\n this.preferredFirstName.set(undefined);\n this.preferredLastName.set(undefined);\n this.roles.set([]);\n this.permissions.set([]);\n }\n\n private setUser(user: AuthUser) {\n this.authenticated.set(true);\n this.userId.set(user.id);\n this.preferredFirstName.set(user.preferredFirstName);\n this.preferredLastName.set(user.preferredLastName);\n this.roles.set(user.roles);\n this.permissions.set(user.permissions);\n }\n\n /**\n * Redirects the user to the login page.\n *\n * @param nextUri - (Optional) The URI to redirect to after login.\n */\n login(nextUri?: string) {\n window.location.href = `/login${nextUri ? `?next_uri=${nextUri}` : ''}`;\n }\n\n /**\n * Logs the user out by resetting the authentication state and redirecting to the logout page.\n */\n logout() {\n this.resetAuthState();\n window.location.href = '/logout';\n }\n\n /**\n * Retrieves information about the currently authenticated user.\n *\n * @returns A promise that resolves to a `WhoAmI` object \n * representing the current user, or `null` if not authenticated or on error.\n */\n private async whoAmI(): Promise<AuthUser | null> {\n try {\n const res = await fetch('/sys/who-am-i');\n const user = await res.json();\n if (!user) {\n this.resetAuthState();\n return null;\n }\n this.setUser(user);\n return user;\n } catch (error) {\n this.resetAuthState();\n return null;\n }\n }\n}\n","import { Component, computed, input } from \"@angular/core\";\nimport { RouterLink, UrlTree } from \"@angular/router\";\n\nexport type HeaderLink = {\n /** text content of link */\n text: string;\n\n /** \n * If the path is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n};\n\n@Component({\n selector: 'byu-header-link',\n imports: [RouterLink],\n templateUrl: 'byu-header-link.html',\n styleUrl: 'byu-header-link.scss'\n})\nexport class NormalizedHeaderItem {\n headerItem = input.required<HeaderLink | string>();\n\n normalizeHeaderItem = computed(() => {\n const item = this.headerItem();\n if (typeof item === 'string') {\n return {\n text: item,\n routerLink: null,\n href: null,\n newTab: null,\n }\n } else {\n const httpPath = typeof item.path === 'string' && item.path.startsWith('http') ? item.path : null;\n return {\n text: item.text,\n routerLink: httpPath === null ? item.path : null,\n href: httpPath !== null ? httpPath : null,\n newTab: item.newTab ?? false\n }\n }\n })\n}","@let item = normalizeHeaderItem();\n\n@if (item.routerLink) {\n <a [routerLink]=\"item.routerLink\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else if (item.href) {\n <a [href]=\"item.href\" [target]=\"item.newTab ? '_blank' : '_self'\">{{ item.text }}</a>\n} @else {\n <a>{{ item.text }}</a>\n}","import { Component, input, inject, signal, HostListener, ViewEncapsulation } from '@angular/core';\nimport { NgTemplateOutlet } from '@angular/common';\nimport { UrlTree } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { HeaderLink, NormalizedHeaderItem } from './byu-header-link/byu-header-link';\n\ntype MenuLink<T extends string> = {\n /** text content of the link */\n text: string,\n\n /** \n * If the link is a string that starts with `http`, it will be used as an absolute path for the href\n * \n * Else it will be used as a relative path for the routerLink\n */\n path: string | any[] | UrlTree | null | undefined;\n\n /** if the link should open in a new tab */\n newTab?: boolean;\n\n /** list of permissions that a user must have at least one of to see the link */\n requiredPermissions?: T[];\n\n /** if instead the user should have all of the required permissions */\n haveAll?: boolean;\n\n /** if the user must be authenticated to see the link */\n needsAuthentication?: boolean;\n}\n\ntype MenuDropdown<T extends string> = {\n /** text content of the link */\n text: string;\n\n /** items to display in the dropdown menu */\n items: MenuLink<T>[];\n} \n\ntype HeaderMenu<T extends string> = MenuLink<T> | MenuDropdown<T>\n\nexport type HeaderConfig<Permission extends string> = {\n /** Main site title: a link or plain text */\n title: HeaderLink | string;\n\n /** Optional subtitle: a link or plain text */\n subtitle?: HeaderLink | string;\n\n /** Optional breadcrumbs for navigational context: links or plain texts */\n breadcrumbs?: (HeaderLink | string)[];\n\n /** Optional menu items: links or dropdowns, potentially restricted by authentication or permissions */\n menu?: HeaderMenu<Permission>[];\n}\n\n@Component({\n selector: 'byu-header',\n imports: [NormalizedHeaderItem, NgTemplateOutlet],\n templateUrl: './byu-header.component.html',\n styleUrl: './byu-header.component.scss',\n encapsulation: ViewEncapsulation.ShadowDom\n})\nexport class ByuHeaderComponent {\n auth = inject(AuthService)\n config = input.required<HeaderConfig<string>>();\n\n openDropdown: MenuDropdown<string> | null = null;\n isMenuOpen = signal(false);\n\n isMenuLink(item: HeaderMenu<string>): item is MenuLink<string> {\n return 'path' in item;\n }\n \n isMenuLinkVisible(link: MenuLink<string>) {\n return link.requiredPermissions !== undefined\n ? link.requiredPermissions[link.haveAll ? 'every' : 'some']((permission) => this.auth.effectivePermissions().has(permission))\n : this.auth.authenticated() || !link.needsAuthentication;\n }\n\n isMenuDropdownVisible(dropdown: MenuDropdown<string>) {\n return dropdown.items.some(item => this.isMenuLinkVisible(item));\n }\n \n toggleDropdown(dropdown: MenuDropdown<string>) {\n this.openDropdown = this.openDropdown === dropdown ? null : dropdown;\n }\n\n toggleMenu() {\n this.isMenuOpen.update(prev => !prev)\n }\n\n @HostListener('document:click', ['$event'])\n onDocumentClick(ev: MouseEvent) {\n const path = (ev.composedPath?.() ?? []);\n const target = path[0];\n\n if (target instanceof Element) {\n if (target.className !== 'nav-item-content') {\n this.openDropdown = null;\n \n if (target.className !== 'hamburger' && target.className !== 'bar') {\n this.isMenuOpen.set(false);\n }\n }\n }\n\n }\n}\n","@let title = config().title;\n@let subtitle = config().subtitle;\n@let breadcrumbs = config().breadcrumbs;\n@let menu = config().menu;\n@let authenticated = auth.authenticated();\n\n<ng-template #signin>\n <div class=\"signin\" (click)=\"authenticated ? auth.logout() : auth.login()\">\n <p>{{ auth.preferredName() }}</p>\n <svg class=\"signin-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\">\n <path fill=\"currentcolor\" d=\"M50 95c-26 0-34-18-34-18 3-12 8-18 17-18 5 5 10 7 17 7s12-2 17-7c9 0 14 6 17 18 0 0-7 18-34 18z\"></path>\n <circle cx=\"50\" cy=\"50\" r=\"45\" fill=\"none\" stroke=\"currentcolor\" stroke-width=\"10\"></circle>\n <circle fill=\"currentcolor\" cx=\"50\" cy=\"40\" r=\"20\"></circle>\n </svg>\n <a class=\"signin-link\">{{authenticated ? 'Sign Out' : 'Sign In'}}</a>\n </div>\n</ng-template>\n\n<header>\n <div class=\"top\" >\n <div class=\"logo\" alt=\"BYU\"></div>\n <div class=\"titles\"> \n <div class=\"breadcrumbs\">\n @for (breadcrumb of breadcrumbs; track breadcrumb) {\n <byu-header-link [headerItem]=\"breadcrumb\" class=\"breadcrumb\"></byu-header-link>\n }\n </div>\n <byu-header-link [headerItem]=\"title\" class=\"title\"></byu-header-link>\n @if (subtitle) {\n <byu-header-link [headerItem]=\"subtitle\" class=\"subtitle\"></byu-header-link>\n }\n </div>\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n <div class=\"hamburger\" [class.open]=\"isMenuOpen()\" (click)=\"toggleMenu()\">\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n <div class=\"bar\"></div>\n </div>\n </div>\n <div class=\"bottom\">\n <nav [class.open]=\"isMenuOpen()\">\n <ng-container *ngTemplateOutlet=\"signin\"></ng-container>\n @for (menuItem of menu; track menuItem.text){\n @if (isMenuLink(menuItem)) {\n @if (isMenuLinkVisible(menuItem)) {\n <byu-header-link [headerItem]=\"menuItem\" class=\"nav-item\"></byu-header-link>\n }\n }\n @else {\n @if (isMenuDropdownVisible(menuItem)) {\n <div class=\"nav-item dropdown\" [class.open]=\"openDropdown === menuItem\" (click)=\"toggleDropdown(menuItem)\">\n <div class=\"nav-item-content\" >{{ menuItem.text }}</div>\n @if (openDropdown === menuItem) {\n <div class = \"dropdown-item-menu\">\n @for(dropItem of menuItem.items; track dropItem.text){\n @if (isMenuLinkVisible(dropItem)) {\n <byu-header-link [headerItem]=\"dropItem\" itemType=\"dropdown\" class=\"dropdown-item\"></byu-header-link>\n }\n }\n </div>\n }\n </div>\n }\n }\n }\n </nav>\n </div>\n</header>\n","import { computed, effect, inject, Injector, linkedSignal, signal } from \"@angular/core\";\nimport { isTRPCClientError, Resolver } from \"@trpc/client\";\nimport { ResolverDef, TrpcResource, TrpcResourceOptions } from \"./trpcResource.types\";\n\nfunction trpcResource<TDef extends ResolverDef>(procedure: Resolver<TDef>, input: () => TDef['input'] | undefined, options?: TrpcResourceOptions<TDef['output']>): TrpcResource<TDef> {\n const currentInput = computed(input);\n\n const value = linkedSignal<TDef['output'] | undefined>(options?.valueComputation ?? (() => options?.initialValue ?? options?.defaultValue), { equal: options?.equal });\n const error = signal<TDef['errorShape'] | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n\n if (options?.autoRefresh) {\n effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n // refresh reads currentInput which triggers the effect\n refresh(controller.signal, true);\n }, { injector: options?.injector || inject(Injector)});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort: boolean = true,\n ):Promise<boolean> => {\n // if we have the special case where the current input is undefined\n // then set everything to it's initial state\n if (currentInput() === undefined) {\n value.set(options?.initialValue ?? options?.defaultValue);\n error.set(undefined);\n isLoading.set(false);\n return true;\n }\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n error.set(undefined);\n\n try {\n value.set(await procedure(currentInput(), {\n signal: abortSignal\n }));\n error.set(undefined)\n } catch (err) {\n if (isTRPCClientError(err)) {\n // if the trpc request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.cause?.name === 'AbortError' && keepLoadingThroughAbort) {\n return false;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n console.error(\"A non-tRPC error has occured on this trpcResource: \", String(err));\n }\n value.set(options?.defaultValue);\n }\n isLoading.set(false);\n return !error();\n }\n\n return {\n value,\n error,\n isLoading,\n refresh\n };\n}\n\nfunction debugTrpcResource<TDef extends ResolverDef>(_trpcResource: TrpcResource<TDef>) {\n return {\n value: _trpcResource.value(),\n error: _trpcResource.error(),\n isLoading: _trpcResource.isLoading(),\n }\n}\n\nexport { debugTrpcResource, trpcResource };","import { effect, signal, Signal } from '@angular/core';\n\nexport const debounced = <T>(inputSignal: Signal<T>, wait: number = 400) => {\n const debouncedSignal = signal<T>(inputSignal());\n const setSignal = debounce(value => debouncedSignal.set(value), wait);\n\n effect(() => {\n setSignal(inputSignal());\n });\n\n return debouncedSignal;\n};\n\nconst debounce = (callback: (...args: any[]) => void, wait: number) => {\n let timeoutId: number | undefined;\n return (...args: any[]) => {\n window.clearTimeout(timeoutId);\n timeoutId = window.setTimeout(() => {\n callback(...args);\n }, wait);\n };\n};\n","import { Resolver } from '@trpc/client';\nimport { ResolverDef } from '../../signals/trpcResource/trpcResource.types';\nimport { trpcResource } from '../../signals/trpcResource/trpcResource';\n\nexport type FhssTableConfig<TDef extends ResolverDef> = {\n procedure: Resolver<TDef>;\n columns: {\n [K in keyof TDef['output']['data'][number]]: {\n hide?: boolean;\n header?: string;\n allowSort?: boolean;\n individualFilter?: boolean;\n };\n };\n showSearch?: boolean;\n sorting: {\n defaultSortBy: Extract<keyof TDef['output']['data'][number], string>;\n defaultSortDirection?: 'asc' | 'desc';\n };\n pagination: {\n pageSize: number;\n hideControls?: boolean;\n };\n disableAlternatingColors?: boolean;\n interaction?:\n | {\n type: 'click';\n onClick: (obj: TDef['output']['data'][number]) => void;\n }\n | {\n type: 'select';\n multi?: boolean;\n };\n};\n\nexport const makeTableConfig = <TDef extends ResolverDef>(config: FhssTableConfig<TDef>) => config;\n\nexport type AnyResolver = {\n input: any;\n output: { totalCount: number; data: any[] };\n transformer: any;\n errorShape: {\n code: any;\n message: string;\n data: any;\n };\n};\n\nexport type AnyResource = ReturnType<typeof trpcResource<AnyResolver>>;\n","import {\n Component,\n inject,\n Injector,\n input,\n linkedSignal,\n model,\n OnInit,\n signal,\n} from '@angular/core';\nimport { trpcResource } from '../../signals/trpcResource/trpcResource';\nimport { debounced } from '../../signals/debounced/debounced';\nimport { FhssTableConfig, AnyResolver, AnyResource } from './fhss-table.types';\nexport { makeTableConfig } from './fhss-table.types';\n\nimport { MatTableModule } from '@angular/material/table';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { MatPaginatorModule, PageEvent } from '@angular/material/paginator';\nimport { MatInputModule } from '@angular/material/input';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatSortModule, Sort } from '@angular/material/sort';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatRippleModule } from '@angular/material/core';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { SelectionModel } from '@angular/cdk/collections';\n\n@Component({\n selector: 'fhss-table',\n imports: [\n MatTableModule,\n MatProgressSpinnerModule,\n MatPaginatorModule,\n MatInputModule,\n FormsModule,\n MatButtonModule,\n MatSortModule,\n MatIconModule,\n MatRippleModule,\n MatCheckboxModule,\n ],\n templateUrl: './fhss-table.component.html',\n styleUrl: './fhss-table.component.scss',\n})\nexport class FhssTableComponent implements OnInit {\n private injector = inject(Injector);\n\n config = input.required<FhssTableConfig<AnyResolver>>();\n miscParams = input<Record<string, any>>({});\n\n columnKeys: string[] = [];\n columnsToDisplay: string[] = [];\n selection: SelectionModel<any> | undefined;\n selectedValues = model<any[]>([]);\n\n dataResource!: AnyResource;\n refresh() {\n this.dataResource.refresh()\n }\n\n ngOnInit() {\n const cfg = this.config();\n\n this.columnKeys = Object.keys(cfg.columns);\n this.columnsToDisplay = this.columnKeys.filter((k) => !cfg.columns[k].hide);\n\n if (cfg.interaction?.type === 'select') {\n this.columnsToDisplay.unshift('table-checkbox-column');\n this.selection = new SelectionModel<any>(\n cfg.interaction.multi,\n undefined,\n undefined,\n (o1, o2) => o1.id === o2.id,\n );\n }\n\n this.dataResource = trpcResource(\n this.config().procedure,\n () => ({\n search: this.debouncedSearch(),\n filters: this.debouncedFilters(),\n sort: {\n property: this.sortBy(),\n direction: this.sortDirection(),\n },\n page: {\n size: this.config().pagination.pageSize,\n index: this.pageIndex(),\n },\n ...this.miscParams(),\n }),\n {\n autoRefresh: true,\n injector: this.injector,\n },\n );\n }\n\n search = signal('');\n debouncedSearch = debounced(this.search);\n filters = signal<Record<string, string>>({});\n debouncedFilters = debounced(this.filters);\n\n sortBy = linkedSignal(() => this.config().sorting.defaultSortBy);\n sortDirection = linkedSignal<'asc' | 'desc'>(\n () => this.config().sorting.defaultSortDirection ?? 'asc',\n );\n\n pageIndex = linkedSignal(() => {\n this.search();\n return 0;\n });\n\n onFilterChange(col: string, val: string) {\n this.filters.update((f) => ({ ...f, [col]: val }));\n }\n onPaginationChange(e: PageEvent) {\n this.pageIndex.set(e.pageIndex);\n }\n onSortChange(sort: Sort) {\n this.sortBy.set(sort.active || this.config().sorting.defaultSortBy);\n this.sortDirection.set(\n sort.direction || this.config().sorting.defaultSortDirection || 'asc',\n );\n this.pageIndex.set(0);\n }\n onSelectionChange() {\n this.selectedValues.set(this.selection?.selected ?? []);\n }\n\n onRowClick(row: any) {\n const interaction = this.config().interaction;\n if (!interaction) return;\n\n if (interaction.type === 'click') {\n interaction.onClick(row);\n } else if (interaction.type === 'select') {\n this.selection?.toggle(row);\n }\n this.onSelectionChange();\n }\n\n isAllSelected() {\n if (!this.selection) return false;\n const numSelected = this.selection.selected.length;\n const numRows = this.dataResource.value()?.data?.length ?? 0;\n return numSelected === numRows;\n }\n\n toggleAllRows() {\n if (!this.selection) return;\n if (this.isAllSelected()) {\n this.selection.clear();\n } else {\n this.selection.select(...(this.dataResource.value()?.data ?? []));\n }\n this.onSelectionChange();\n }\n\n checkboxLabel(row?: any): string {\n if (!this.selection) return '';\n if (!row) {\n return `${this.isAllSelected() ? 'deselect' : 'select'} all`;\n }\n return `${this.selection.isSelected(row) ? 'deselect' : 'select'} row ${row.position + 1}`;\n }\n\n protected isBoolean = (val: unknown) => typeof val === 'boolean';\n}\n","<div class=\"table-container\">\n @if (dataResource.isLoading() || dataResource.error()) {\n <div class=\"shade\">\n @if (dataResource.isLoading()) {\n <mat-spinner />\n }\n @if (dataResource.error()) {\n <div class=\"msg-bkgd\">\n <div class=\"error-msg\">There was an error retrieving this data</div>\n <button mat-button (click)=\"this.dataResource.refresh()\">\n Retry\n </button>\n </div>\n }\n </div>\n }\n\n @if (config().showSearch) {\n <mat-form-field\n class=\"search\"\n subscriptSizing=\"dynamic\"\n appearance=\"outline\">\n <input matInput [(ngModel)]=\"search\" placeholder=\"Find...\" />\n @if (search()) {\n <button\n matSuffix\n mat-icon-button\n aria-label=\"Clear\"\n (click)=\"search.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n }\n\n <div class=\"other-controls\">\n <ng-content />\n </div>\n\n <table\n mat-table\n [dataSource]=\"dataResource.value()?.data ?? []\"\n matSort\n [matSortActive]=\"sortBy()\"\n [matSortDirection]=\"sortDirection()\"\n (matSortChange)=\"onSortChange($event)\"\n matSortDisableClear>\n @if (selection) {\n <ng-container matColumnDef=\"table-checkbox-column\">\n <mat-header-cell *matHeaderCellDef>\n @if (selection.isMultipleSelection()) {\n <mat-checkbox\n (change)=\"$event ? toggleAllRows() : null\"\n [checked]=\"selection.hasValue() && isAllSelected()\"\n [indeterminate]=\"selection.hasValue() && !isAllSelected()\"\n [aria-label]=\"checkboxLabel()\" />\n } @else {\n <mat-checkbox disabled style=\"visibility: hidden\"></mat-checkbox>\n }\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n <mat-checkbox\n (click)=\"$event.stopPropagation()\"\n (change)=\"$event ? onRowClick(row) : null\"\n [checked]=\"selection.isSelected(row)\"\n [aria-label]=\"checkboxLabel(row)\" />\n </mat-cell>\n </ng-container>\n }\n\n @for (key of columnKeys; track key) {\n <ng-container [matColumnDef]=\"key\">\n <mat-header-cell\n *matHeaderCellDef\n mat-sort-header\n [disabled]=\"!config().columns[key].allowSort\">\n <div class=\"header\">\n {{ config().columns[key].header || key }}\n @if (config().columns[key].individualFilter) {\n <mat-form-field appearance=\"outline\" subscriptSizing=\"dynamic\">\n <input\n matInput\n (click)=\"$event.stopPropagation()\"\n [ngModel]=\"filters()[key] || ''\"\n (ngModelChange)=\"onFilterChange(key, $event)\"\n placeholder=\"Filter...\" />\n @if (filters()[key]) {\n <button\n matSuffix\n mat-icon-button\n aria-label=\"Clear\"\n (click)=\"onFilterChange(key, '')\">\n <mat-icon>close</mat-icon>\n </button>\n }\n </mat-form-field>\n }\n </div>\n </mat-header-cell>\n <mat-cell *matCellDef=\"let row\">\n @if (isBoolean(row[key])) {\n <mat-checkbox [checked]=\"row[key]\" [disabled]=\"true\" />\n } @else {\n {{ row[key] }}\n }\n </mat-cell>\n </ng-container>\n }\n\n <mat-header-row *matHeaderRowDef=\"columnsToDisplay\"></mat-header-row>\n @if (config().interaction) {\n <mat-row\n matRipple\n (click)=\"onRowClick(row)\"\n *matRowDef=\"let row; columns: columnsToDisplay; let even = even\"\n [class]=\"{\n alternating: !config().disableAlternatingColors,\n even: even,\n interactive: true,\n }\">\n </mat-row>\n } @else {\n <mat-row\n *matRowDef=\"let row; columns: columnsToDisplay; let even = even\"\n [class]=\"{\n alternating: !config().disableAlternatingColors,\n even: even,\n }\">\n </mat-row>\n }\n\n <tr class=\"mat-row\" *matNoDataRow>\n <td class=\"mat-cell\">\n <div class=\"no-data\">\n No data found\n <button mat-button (click)=\"this.dataResource.refresh()\">\n Retry\n </button>\n </div>\n </td>\n </tr>\n </table>\n\n @if (!config().pagination.hideControls) {\n <mat-paginator\n [length]=\"dataResource.value()?.totalCount\"\n [showFirstLastButtons]=\"true\"\n [pageSize]=\"config().pagination.pageSize\"\n [hidePageSize]=\"true\"\n [pageIndex]=\"pageIndex()\"\n [disabled]=\"dataResource.isLoading()\"\n (page)=\"onPaginationChange($event)\" />\n }\n</div>\n","import { Component, inject, Injectable } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport {\n MatDialogModule,\n MAT_DIALOG_DATA,\n MatDialog,\n} from '@angular/material/dialog';\n\ntype ConfirmationConfig =\n | {\n title?: string;\n action?: string;\n description?: never;\n buttons?: readonly string[];\n }\n | {\n title?: string;\n action?: never;\n description?: string;\n buttons?: readonly string[];\n };\n\ntype ConfirmationResult<C extends ConfirmationConfig | undefined> = C extends {\n buttons: readonly string[];\n}\n ? C['buttons'][number]\n : boolean;\n\n@Component({\n selector: 'fhss-confirmation',\n imports: [MatDialogModule, MatButtonModule],\n templateUrl: './confirmation.dialog.html',\n styleUrl: './confirmation.dialog.scss',\n})\nclass ConfirmationDialogContainer {\n protected readonly config: ConfirmationConfig | undefined =\n inject(MAT_DIALOG_DATA);\n}\n\n@Injectable({ providedIn: 'root' })\nexport class ConfirmationDialog {\n private readonly dialog = inject(MatDialog);\n\n open<C extends ConfirmationConfig | undefined>(config?: C) {\n const dialogRef = this.dialog.open<\n ConfirmationDialogContainer,\n ConfirmationConfig,\n ConfirmationResult<C>\n >(ConfirmationDialogContainer, {\n data: config,\n });\n\n return dialogRef;\n }\n}\n","<h2 mat-dialog-title>{{ config?.title ?? \"Are you sure?\"}}</h2>\n\n<mat-dialog-content>\n @if (config?.description) {\n <p>{{ config?.description }}</p>\n } @else {\n <p>Are you sure you would like to {{ config?.action ?? 'continue' }}?</p>\n }</mat-dialog-content\n>\n\n<mat-dialog-actions>\n @if (config?.buttons) { @for (name of config?.buttons; track name) {\n <button mat-button [mat-dialog-close]=\"name\">{{name}}</button>\n } } @else {\n <button mat-button [mat-dialog-close]=\"false\">No</button>\n <button mat-button [mat-dialog-close]=\"true\">Yes</button>\n }\n</mat-dialog-actions>\n","import { Component, input, model, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatInputModule } from '@angular/material/input';\nimport { MatSelectModule } from '@angular/material/select';\n\ntype value = string | number;\nexport type Option = { label: string; value: value | null };\n\ntype Boolish = string | boolean | undefined;\nfunction fromBoolish(v: Boolish): boolean {\n if (v === undefined || v === false) return false;\n if (typeof v === 'string') {\n return v.trim().toLowerCase() !== 'false';\n }\n return true;\n}\n\n@Component({\n selector: 'fhss-combo-box',\n imports: [\n MatSelectModule,\n MatButtonModule,\n MatIconModule,\n MatFormFieldModule,\n MatInputModule,\n FormsModule,\n ],\n templateUrl: './combo-box.component.html',\n styleUrl: './combo-box.component.scss',\n})\nexport class ComboBoxComponent {\n options = input.required<Option[]>();\n placeholder = input.required<string>();\n appearance = input<'outline' | 'fill'>('fill');\n multiple = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n showClear = input<boolean, Boolish>(false, {\n transform: fromBoolish,\n });\n\n /**\n * Takes a signal to store the selected value(s) in.\n */\n selected = model.required<value[] | value | null>();\n\n filter = signal('');\n protected isOptionHidden = (opt: Option) =>\n !opt.label.toLowerCase().includes(this.filter().toLowerCase());\n\n clearSelected() {\n if (Array.isArray(this.selected())) {\n this.selected.set([]);\n } else {\n this.selected.set(null);\n }\n }\n}\n","<mat-form-field\n (click)=\"filter.set('')\"\n [appearance]=\"appearance()\"\n subscriptSizing=\"dynamic\">\n <mat-label>{{ placeholder() }}</mat-label>\n <mat-select [(ngModel)]=\"selected\" [multiple]=\"multiple()\">\n <mat-form-field subscriptSizing=\"dynamic\">\n <input matInput placeholder=\"Search...\" [(ngModel)]=\"filter\" />\n <button mat-icon-button matSuffix (click)=\"filter.set('')\">\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n @for (option of options(); track option.value) {\n <mat-option\n [value]=\"option.value\"\n [class.hidden]=\"isOptionHidden(option)\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n\n @if (showClear()) {\n <button\n mat-icon-button\n matSuffix\n (click)=\"$event.stopPropagation(); clearSelected()\">\n <mat-icon>close</mat-icon>\n </button>\n }\n</mat-form-field>\n","import { Provider } from \"@angular/core\";\nimport { FHSS_CONFIG, FhssConfig } from \"./lib.config\";\n\nexport const provideFhss = (config: FhssConfig): Provider => ({\n provide: FHSS_CONFIG,\n useValue: config,\n});\n","import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root',\n})\nexport class ScrollRegistryService {\n private anchors = new Map<string, HTMLElement>();\n private pending = new Map<string, (() => void)[]>();\n\n register(key: string, el: HTMLElement) {\n this.anchors.set(key, el);\n const queue = this.pending.get(key);\n if (queue) {\n queue.forEach(fn => fn());\n this.pending.delete(key);\n }\n }\n\n unregister(key: string) {\n this.anchors.delete(key);\n }\n\n scrollTo(\n key: string,\n opts: ScrollIntoViewOptions = { behavior: 'smooth', block: 'center' }\n ) {\n const el = this.anchors.get(key);\n if (el) el.scrollIntoView(opts);\n else {\n const q = this.pending.get(key) ?? [];\n q.push(() => this.anchors.get(key)?.scrollIntoView(opts));\n this.pending.set(key, q);\n }\n }\n}\n","import { Directive, ElementRef, inject, input } from '@angular/core';\nimport { ScrollRegistryService } from '../services/scroll-registry/scroll-registry.service';\n\n@Directive({\n selector: '[scrollAnchor]',\n})\nexport class ScrollAnchorDirective {\n private readonly registery = inject(ScrollRegistryService);\n scrollAnchor = input.required<string>();\n\n constructor(private element: ElementRef<HTMLElement>) {}\n\n ngOnInit() {\n this.registery.register(this.scrollAnchor(), this.element.nativeElement);\n }\n\n ngOnDestroy() {\n this.registery.unregister(this.scrollAnchor());\n }\n}\n","import { inject } from '@angular/core';\nimport { CanActivateFn } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\n\n/**\n * This guard checks if the client is authenticated, redirecting to login if not.\n */\nexport const authGuard: CanActivateFn = async (_route, state) => {\n const authService = inject(AuthService);\n if (!await authService.ready()) {\n authService.login(state.url);\n return false;\n }\n return true;\n};\n","import { CanActivateFn, RedirectCommand, Router } from '@angular/router';\nimport { AuthService } from '../../services/auth/auth.service';\nimport { inject } from '@angular/core';\n\n/**\n * A permission-based route guard.\n *\n * This guard checks if the current user has the required permissions to access a route.\n * If the user is not authenticated, they are redirected to the login page.\n * If the user lacks the necessary permissions, they are redirected to the `/forbidden` page.\n *\n * Pass the Permission type to get intellisense on requiredPermissions\n * @param requiredPermissions - An array of permission strings that the user must have.\n * @param haveAll - If `true`, the user must have all required permissions. If `false` or omitted, the user must have at least one of the required permissions.\n * @returns A `CanActivateFn` function to be used as a route guard.\n * \n * @example\n * ```typescript\n * const routes: Routes = [\n * {\n * path: 'admin',\n * component: AdminPage,\n * canActivate: [permissionGuard<Permission>(['manage-users', 'see-data'], true)],\n * },\n * ];\n * ```\n */\nexport const permissionGuard: <Permission extends string>(\n requiredPermissions: Permission[],\n haveAll?: boolean,\n) => CanActivateFn = (reqPerms, haveAll) => {\n return async (_route, state) => {\n const router = inject(Router);\n const authService = inject(AuthService);\n\n if (!await authService.ready()) {\n authService.login(state.url);\n return false;\n }\n\n const hasAccess = reqPerms[haveAll ? 'every' : 'some']((role) =>\n authService.effectivePermissions().has(role),\n );\n\n return hasAccess || new RedirectCommand(router.parseUrl('/forbidden'));\n };\n};\n","import { Component, input } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport type SystemConfig = {\n title?: string,\n message?: string,\n image?: string\n}\n\n@Component({\n selector: 'fhss-system',\n imports: [MatButtonModule],\n templateUrl: './system.page.html',\n styleUrl: './system.page.scss',\n})\nexport class SystemPage {\n readonly config = input.required<SystemConfig>();\n}\n","@let title = config().title;\n@let message = config().message;\n@let image = config().image;\n\n<div class=\"container\">\n @if (image) {\n <div [class]=\"['image', image]\"></div>\n }\n <h1>{{title ? title : 'Application Error'}}</h1>\n <p>{{message ? message : 'Oops! Something went wrong!'}}</p>\n <a mat-flat-button href=\"/\">Go back home</a>\n</div>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from \"../system/system.page\";\n\n@Component({\n selector: 'fhss-auth-error',\n imports: [SystemPage],\n templateUrl: './auth-error.page.html',\n styleUrl: './auth-error.page.scss'\n})\nexport class AuthErrorPage {\n protected readonly config: SystemConfig = {\n title: 'Login Failed',\n message: 'Something went wrong while trying to log you in.',\n image: 'sad-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-forbidden',\n imports: [SystemPage],\n templateUrl: './forbidden.page.html',\n styleUrl: './forbidden.page.scss',\n})\nexport class ForbiddenPage {\n protected readonly config: SystemConfig = {\n title: \"403 - Forbidden\",\n message: \"You don't have permission to access this page.\",\n image: 'police-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { Component } from '@angular/core';\nimport { SystemPage, SystemConfig } from '../system/system.page';\n\n@Component({\n selector: 'fhss-not-found',\n imports: [SystemPage],\n templateUrl: './not-found.page.html',\n styleUrl: './not-found.page.scss',\n})\nexport class NotFoundPage {\n protected readonly config: SystemConfig = {\n title: \"404 - Page not found\",\n message: \"The page you are looking for doesn't exist or it may have moved.\",\n image: 'confused-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { Component } from '@angular/core';\nimport { SystemConfig, SystemPage } from '../system/system.page';\n\n@Component({\n selector: 'fhss-server-error',\n imports: [SystemPage],\n templateUrl: './server-error.page.html',\n styleUrl: './server-error.page.scss',\n})\nexport class ServerErrorPage {\n protected readonly config: SystemConfig = {\n title: \"500 - Internal Server Error\",\n message: \"We ran into an unexpected error!\",\n image: 'error-duck'\n }\n}\n","<fhss-system [config]=\"config\" ></fhss-system>","import { computed, effect, EffectRef, inject, Injector, signal, untracked } from '@angular/core';\nimport { FetchSignal, FetchSignalFactory, FetchSignalOptions, FetchSignalRequest, FetchSignalStatus, HttpMethod, Json, ResponseTransformer } from './fetch-signal.types';\n\n\n/**\n * Creates a reactive fetch signal.\n *\n * The request function can include Signals for properties. These are unwrapped in the refresh function.\n */\nfunction createFetchSignal<Response, ErrorResponse, RawResponse>(\n request: () => FetchSignalRequest,\n method: HttpMethod,\n transform: ResponseTransformer<Response>,\n options?: FetchSignalOptions<Response, RawResponse>,\n): FetchSignal<Response, ErrorResponse> {\n // Use a computed signal so that any changes to Signals in the request object trigger updates.\n const currentRequest = computed<FetchSignalRequest>(request);\n\n const value = signal<Response | undefined>(options?.defaultValue, { equal: options?.equal });\n const errorResponse = signal<ErrorResponse | undefined>(undefined);\n const isLoading = signal<boolean>(false);\n const statusCode = signal<number | undefined>(undefined);\n const headers = signal<Record<string, string> | undefined>(undefined);\n\n const status = signal<FetchSignalStatus>('idle');\n const error = signal<Error | undefined>(undefined);\n\n const injector = inject(Injector);\n let effectRef: EffectRef | undefined = undefined;\n if (options?.autoRefresh) {\n effectRef = effect((onCleanup) => {\n // pass abort signal to refresh on cleanup of effect\n const controller = new AbortController();\n onCleanup(() => controller.abort());\n\n // call refresh with this abort controller\n refresh(controller.signal, true);\n }, { injector: options?.injector || injector});\n }\n\n const refresh = async (\n abortSignal?: AbortSignal,\n keepLoadingThroughAbort?: boolean,\n ) => {\n // if the fetchSignal has been destroyed, do nothing\n if (untracked(status) === 'destroyed') return;\n\n // Reset signals for a fresh request.\n isLoading.set(true);\n errorResponse.set(undefined);\n statusCode.set(undefined);\n headers.set(undefined);\n status.set('loading');\n error.set(undefined);\n\n // Unwrap the current request.\n const req = currentRequest();\n const url = req.url;\n const params = req.params;\n const requestHeaders = req.headers;\n const body = req.body;\n\n // Build URL with query parameters.\n let uri = url;\n if (params) {\n const searchParams = new URLSearchParams();\n for (const key in params) {\n if (params[key] !== undefined)\n searchParams.append(key, String(params[key]));\n }\n uri += (uri.includes('?') ? '&' : '?') + searchParams.toString();\n }\n \n // Filter out undefined header values\n const filteredHeaders = requestHeaders\n ? Object.fromEntries(\n Object.entries(requestHeaders).filter(\n ([, value]) => value !== undefined\n ) as [string, string][]\n )\n : undefined;\n \n try {\n // send the request\n const response = await fetch(uri, {\n method,\n headers: filteredHeaders,\n // Only include a body if one is provided.\n body: body,\n signal: abortSignal,\n });\n\n // set the status code\n statusCode.set(response.status);\n\n // Extract response headers.\n const headersObj: Record<string, string> = {};\n response.headers.forEach((val, key) => {\n headersObj[key] = val;\n });\n headers.set(headersObj);\n\n // if the response is ok, transform the body\n if (response.ok) {\n value.set(await transform(response));\n status.set('resolved');\n } else {\n // try to parse the error as json\n try {\n errorResponse.set(await response.json());\n value.set(undefined);\n status.set('resolved');\n } catch {\n throw new Error('Unable to parse error response.')\n }\n }\n } catch (err: any) {\n if (err instanceof Error) {\n // if the fetch request was aborted\n // we check if we would like to continue loading (the next request)\n // if so then we just leave this refresh in an undefined state\n // else we error as usual\n if (err.name === 'AbortError' && keepLoadingThroughAbort) {\n return;\n }\n error.set(err);\n } else {\n // Fallback for non-Error values\n error.set(new Error(String(err)));\n }\n value.set(undefined);\n status.set('error');\n }\n isLoading.set(false);\n };\n\n const destroy = () => {\n // if the fetchSignal has been destroyed, do nothing\n if (status() === 'destroyed') return;\n\n if (effectRef) {\n effectRef.destroy();\n }\n status.set('destroyed');\n value.set(undefined);\n errorResponse.set(undefined);\n isLoading.set(false);\n statusCode.set(undefined);\n headers.set(undefined);\n error.set(undefined);\n }\n\n return {\n value,\n errorResponse,\n isLoading,\n statusCode,\n headers,\n status,\n error,\n refresh,\n destroy\n };\n}\n\n//\n// Helpers for attaching response transforms.\n//\nconst createHelper = <Response, Error>(method: HttpMethod, transform: ResponseTransformer<Response>) =>\n (request: () => FetchSignalRequest, options?: FetchSignalOptions<Response, any>): FetchSignal<Response, Error> =>\n createFetchSignal<Response, Error, any>(request, method, transform, options);\n\n// Transforms\nconst jsonTransformer: ResponseTransformer<any> = (response: Response) => response.json();\nconst textTransformer: ResponseTransformer<string> = (response: Response) => response.text();\nconst blobTransformer: ResponseTransformer<Blob> = (response: Response) => response.blob();\nconst arrayBufferTransformer: ResponseTransformer<ArrayBuffer> = (response: Response) => response.arrayBuffer();\n\n//\n// Build the defaults - GET chain\n//\nconst fetchSignal = createHelper('GET', jsonTransformer) as FetchSignalFactory;\nfetchSignal.json = createHelper('GET', jsonTransformer);\nfetchSignal.text = createHelper('GET', textTransformer);\nfetchSignal.blob = createHelper('GET', blobTransformer);\nfetchSignal.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the GET chain\n//\nfetchSignal.get = createHelper(\n 'GET',\n jsonTransformer,\n) as FetchSignalFactory['get'];\nfetchSignal.get.json = createHelper('GET', jsonTransformer);\nfetchSignal.get.text = createHelper('GET', textTransformer);\nfetchSignal.get.blob = createHelper('GET', blobTransformer);\nfetchSignal.get.arrayBuffer = createHelper('GET', arrayBufferTransformer);\n\n//\n// Build the POST chain.\n//\nfetchSignal.post = createHelper(\n 'POST',\n jsonTransformer,\n) as FetchSignalFactory['post'];\nfetchSignal.post.json = createHelper('POST', jsonTransformer);\nfetchSignal.post.text = createHelper('POST', textTransformer);\nfetchSignal.post.blob = createHelper('POST', blobTransformer);\nfetchSignal.post.arrayBuffer = createHelper('POST', arrayBufferTransformer);\n\n//\n// Build the PUT chain.\n//\nfetchSignal.put = createHelper(\n 'PUT',\n jsonTransformer,\n) as FetchSignalFactory['put'];\nfetchSignal.put.json = createHelper('PUT', jsonTransformer);\nfetchSignal.put.text = createHelper('PUT', textTransformer);\nfetchSignal.put.blob = createHelper('PUT', blobTransformer);\nfetchSignal.put.arrayBuffer = createHelper('PUT', arrayBufferTransformer);\n\n//\n// Build the PATCH chain.\n//\nfetchSignal.patch = createHelper(\n 'PATCH',\n jsonTransformer,\n) as FetchSignalFactory['patch'];\nfetchSignal.patch.json = createHelper('PATCH', jsonTransformer);\nfetchSignal.patch.text = createHelper('PATCH', textTransformer);\nfetchSignal.patch.blob = createHelper('PATCH', blobTransformer);\nfetchSignal.patch.arrayBuffer = createHelper('PATCH', arrayBufferTransformer);\n\n//\n// Build the DELETE chain\n//\nfetchSignal.delete = createHelper(\n 'DELETE',\n jsonTransformer,\n) as FetchSignalFactory['delete'];\nfetchSignal.delete.json = createHelper('DELETE', jsonTransformer);\nfetchSignal.delete.text = createHelper('DELETE', textTransformer);\nfetchSignal.delete.blob = createHelper('DELETE', blobTransformer);\nfetchSignal.delete.arrayBuffer = createHelper('DELETE', arrayBufferTransformer);\n\nexport { fetchSignal };\nexport type { Json };\n\n","/**\n * Components\n */\nexport * from './lib/components/byu-footer/byu-footer.component';\nexport { ByuHeaderComponent } from './lib/components/byu-header/byu-header.component';\nexport type { HeaderConfig } from './lib/components/byu-header/byu-header.component';\nexport * from './lib/components/fhss-table/fhss-table.component';\nexport * from './lib/components/confirmation/confirmation.dialog';\nexport * from './lib/components/combo-box/combo-box.component';\n\n/**\n * Config\n */\nexport * from './lib/config/lib.config';\nexport * from './lib/config/utils.config';\n\n/**\n * Directives\n */\nexport * from './lib/directives/scroll-anchor.directive';\n\n/**\n * Guards\n */\nexport * from './lib/guards/auth/auth.guard';\nexport * from './lib/guards/permission/permission.guard';\n\n/**\n * Pages\n */\nexport * from './lib/pages/auth-error/auth-error.page';\nexport * from './lib/pages/forbidden/forbidden.page';\nexport * from './lib/pages/not-found/not-found.page';\nexport * from './lib/pages/server-error/server-error.page';\n\n/**\n * Services\n */\nexport * from './lib/services/auth/auth.service';\nexport * from './lib/services/scroll-registry/scroll-registry.service';\n\n/**\n * Signals\n */\nexport * from './lib/signals/trpcResource/trpcResource';\nexport * from './lib/signals/fetch-signal/fetch-signal';\nexport * from './lib/signals/debounced/debounced';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i2","i1","i3","i4"],"mappings":"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"}
@@ -47,7 +47,7 @@ export declare class ByuHeaderComponent {
47
47
  isMenuDropdownVisible(dropdown: MenuDropdown<string>): boolean;
48
48
  toggleDropdown(dropdown: MenuDropdown<string>): void;
49
49
  toggleMenu(): void;
50
- onDocumentClick(target: HTMLElement): void;
50
+ onDocumentClick(ev: MouseEvent): void;
51
51
  static ɵfac: i0.ɵɵFactoryDeclaration<ByuHeaderComponent, never>;
52
52
  static ɵcmp: i0.ɵɵComponentDeclaration<ByuHeaderComponent, "byu-header", never, { "config": { "alias": "config"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
53
53
  }
@@ -0,0 +1,12 @@
1
+ import { ElementRef } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ export declare class ScrollAnchorDirective {
4
+ private element;
5
+ private readonly registery;
6
+ scrollAnchor: import("@angular/core").InputSignal<string>;
7
+ constructor(element: ElementRef<HTMLElement>);
8
+ ngOnInit(): void;
9
+ ngOnDestroy(): void;
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<ScrollAnchorDirective, never>;
11
+ static ɵdir: i0.ɵɵDirectiveDeclaration<ScrollAnchorDirective, "[scrollAnchor]", never, { "scrollAnchor": { "alias": "scrollAnchor"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
12
+ }
@@ -0,0 +1,10 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class ScrollRegistryService {
3
+ private anchors;
4
+ private pending;
5
+ register(key: string, el: HTMLElement): void;
6
+ unregister(key: string): void;
7
+ scrollTo(key: string, opts?: ScrollIntoViewOptions): void;
8
+ static ɵfac: i0.ɵɵFactoryDeclaration<ScrollRegistryService, never>;
9
+ static ɵprov: i0.ɵɵInjectableDeclaration<ScrollRegistryService>;
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fhss-web-team/frontend-utils",
3
- "version": "4.0.4",
3
+ "version": "4.1.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^19.2.0",
6
6
  "@angular/core": "^19.2.0"
package/public-api.d.ts CHANGED
@@ -12,6 +12,10 @@ export * from './lib/components/combo-box/combo-box.component';
12
12
  */
13
13
  export * from './lib/config/lib.config';
14
14
  export * from './lib/config/utils.config';
15
+ /**
16
+ * Directives
17
+ */
18
+ export * from './lib/directives/scroll-anchor.directive';
15
19
  /**
16
20
  * Guards
17
21
  */
@@ -28,6 +32,7 @@ export * from './lib/pages/server-error/server-error.page';
28
32
  * Services
29
33
  */
30
34
  export * from './lib/services/auth/auth.service';
35
+ export * from './lib/services/scroll-registry/scroll-registry.service';
31
36
  /**
32
37
  * Signals
33
38
  */