navigation-items.ts
1 import { 2 isSome, 3 unwrapOptional as unwrap, 4 } from '@jet/environment/types/optional'; 5 6 import type { NavigationItem } from '@amp/web-app-components/src/components/Navigation/types'; 7 import type { NavigationId } from '@amp/web-app-components/src/types'; 8 import type { 9 WebNavigation, 10 WebNavigationLink, 11 } from '@jet-app/app-store/api/models/web-navigation'; 12 13 import { 14 isSystemImageArtwork, 15 getIconNameFromTemplate, 16 } from '~/components/SystemImage.svelte'; 17 import { getIconComponentByName } from '../SFSymbol.svelte'; 18 import type { Artwork } from '@jet-app/app-store/api/models'; 19 import CategoryTabItem from '~/components/jet/web-navigation/CategoryTabItem.svelte'; 20 21 /** 22 * A {@linkcode NavigationItem} that includes the original {@linkcode WebNavigationLink} 23 * it was defined from, which is needed for the 24 */ 25 export interface NavigationItemWithTab extends NavigationItem { 26 tab: WebNavigationLink; 27 artwork?: Artwork; 28 isActive?: boolean; 29 } 30 31 export function navigationIdFromLink(link: WebNavigationLink): NavigationId { 32 const intent = unwrap(link.action.destination); 33 34 return { 35 type: intent.$kind, 36 // `intent.$kind` will be unique for each `Intent` used here as they are 37 // each a different `LandingPageIntent` 38 resourceId: link.action.pageUrl ?? intent.$kind, 39 }; 40 } 41 42 /** 43 * Transform the "tabs" in the `WebNavigation` into a shape that works with our 44 * shared navigation side-bar components. 45 */ 46 export function makeNavLinks( 47 tabs: WebNavigationLink[], 48 { shouldShowSearchTab = false }, 49 ): NavigationItemWithTab[] { 50 return tabs 51 .filter((tab) => { 52 const isSearchTab = 53 tab.action?.destination?.['$kind'].includes('search_Intent'); 54 55 // Allows for filtering our the search tab, which we use when the sidebar is visible, 56 // since there is a search input in the sidebar 57 return isSearchTab ? shouldShowSearchTab : true; 58 }) 59 .map((tab) => { 60 const { action, artwork: tabArtwork } = tab; 61 const { artwork } = action || {}; 62 const hasSystemImageArtwork = 63 isSome(artwork) && isSystemImageArtwork(artwork); 64 65 return { 66 id: navigationIdFromLink(tab), 67 label: unwrap(tab.action.title), 68 url: action.pageUrl ?? undefined, 69 icon: hasSystemImageArtwork 70 ? getIconComponentByName( 71 getIconNameFromTemplate(artwork.template), 72 ) 73 : undefined, 74 artwork: tabArtwork, 75 component: !hasSystemImageArtwork ? CategoryTabItem : undefined, 76 tab, 77 }; 78 }); 79 }