44 work in solid-ui by adjusting where imported functions are found.
55 */
66import { IndexedFormula , NamedNode } from 'rdflib'
7- import { icons } from '..'
7+ import { icons } from '../iconBase '
88import { loginStatusBox , authSession , currentUser } from '../authn/authn'
99import * as widgets from '../widgets'
1010import { emptyProfile } from './empty-profile'
11- import { addStyleClassToElement , getPod , throttle } from './headerHelpers'
11+ import { addStyleClassToElement , getPod , throttle } from '../utils/headerFooterHelpers'
12+
13+ /**
14+ * menu icons
15+ */
16+ const DEFAULT_HELP_MENU_ICON = icons . iconBase + 'noun_help.svg'
17+ const DEFAUL_SOLID_ICON_URL = 'https://solidproject.org/assets/img/solid-emblem.svg'
1218
1319export type MenuItemLink = {
1420 label : string ,
15- url : string
21+ url : string ,
22+ target ?: string
1623}
1724
1825export type MenuItemButton = {
@@ -23,69 +30,73 @@ export type MenuItemButton = {
2330export type MenuItems = MenuItemLink | MenuItemButton
2431
2532/*
26- HeaderOptions allow for customizing the logo and menu list. If a logo is not provided the default
27- is solid. Menulist will always show a link to logout and to the users profile.
33+ HeaderOptions allow for customizing the logo and menu list. If a logo is not provided the default
34+ is solid. Menulist will always show a link to logout and to the users profile.
2835 */
2936export type HeaderOptions = {
3037 logo ?: string ,
31- menuList ?: MenuItems [ ]
38+ helpIcon ?: string ,
39+ helpMenuList ?: MenuItems [ ]
3240}
3341
3442/**
3543 * Initialize header component, the header object returned depends on whether the user is authenticated.
3644 * @param store the data store
37- * @param options allow the header to be customized with a personalized logo and a menu list of links or buttons.
45+ * @param userMenuList a list of menu items when the user is logged in
46+ * @param options allow the header to be customized with a personalized logo, help icon and a help menu list of links or buttons.
3847 * @returns a header for an authenticated user with menu items given or a login screen
3948 */
40- export async function initHeader ( store : IndexedFormula , options ?: HeaderOptions ) {
49+ export async function initHeader ( store : IndexedFormula , userMenuList : MenuItems [ ] , options ?: HeaderOptions ) {
4150 const header = document . getElementById ( 'PageHeader' )
4251 if ( ! header ) {
4352 return
4453 }
4554
4655 const pod = getPod ( )
47- rebuildHeader ( header , store , pod , options ) ( )
48- authSession . onLogout ( rebuildHeader ( header , store , pod , options ) )
49- authSession . onLogin ( rebuildHeader ( header , store , pod , options ) )
56+ rebuildHeader ( header , store , pod , userMenuList , options ) ( )
57+ authSession . onLogout ( rebuildHeader ( header , store , pod , userMenuList , options ) )
58+ authSession . onLogin ( rebuildHeader ( header , store , pod , userMenuList , options ) )
5059}
5160/**
5261 * @ignore exporting this only for the unit test
5362 */
54- export function rebuildHeader ( header : HTMLElement , store : IndexedFormula , pod : NamedNode , options ?: HeaderOptions ) {
63+ export function rebuildHeader ( header : HTMLElement , store : IndexedFormula , pod : NamedNode , userMenuList : MenuItems [ ] , options ?: HeaderOptions ) {
5564 return async ( ) => {
5665 const user = currentUser ( )
5766 header . innerHTML = ''
58- header . appendChild ( await createBanner ( store , pod , user , options ) )
67+ header . appendChild ( await createBanner ( store , pod , user , userMenuList , options ) )
5968 }
6069}
6170/**
6271 * @ignore exporting this only for the unit test
6372 */
64- export async function createBanner ( store : IndexedFormula , pod : NamedNode , user : NamedNode | null , options ?: HeaderOptions ) : Promise < HTMLElement > {
73+ export async function createBanner ( store : IndexedFormula , pod : NamedNode , user : NamedNode | null , userMenuList : MenuItems [ ] , options ?: HeaderOptions ) : Promise < HTMLElement > {
6574 const podLink = document . createElement ( 'a' )
6675 podLink . href = pod . uri
6776 addStyleClassToElement ( podLink , [ 'header-banner__link' ] )
6877 const image = document . createElement ( 'img' )
6978 if ( options ) {
70- image . src = options . logo ? options . logo : 'https://solidproject.org/assets/img/solid-emblem.svg'
79+ image . src = options . logo ? options . logo : DEFAUL_SOLID_ICON_URL
7180 }
7281 addStyleClassToElement ( image , [ 'header-banner__icon' ] )
7382 podLink . appendChild ( image )
7483
7584 const userMenu = user
76- ? await createUserMenu ( store , user , options )
85+ ? await createUserMenu ( store , user , userMenuList , options )
7786 : createLoginSignUpButtons ( )
7887
79- const helpMenu = createHelpMenu ( )
80-
8188 const banner = document . createElement ( 'div' )
8289 addStyleClassToElement ( banner , [ 'header-banner' ] )
8390 banner . appendChild ( podLink )
8491
8592 const leftSideOfHeader = document . createElement ( 'div' )
8693 addStyleClassToElement ( leftSideOfHeader , [ 'header-banner__right-menu' ] )
8794 leftSideOfHeader . appendChild ( userMenu )
88- leftSideOfHeader . appendChild ( helpMenu )
95+
96+ if ( options && options . helpMenuList ) {
97+ const helpMenu = createHelpMenu ( options , options . helpMenuList )
98+ leftSideOfHeader . appendChild ( helpMenu )
99+ }
89100
90101 banner . appendChild ( leftSideOfHeader )
91102
@@ -94,20 +105,24 @@ export async function createBanner (store: IndexedFormula, pod: NamedNode, user:
94105/**
95106 * @ignore exporting this only for the unit test
96107 */
97- export function createHelpMenu ( ) {
108+ export function createHelpMenu ( options : HeaderOptions , helpMenuItems : MenuItems [ ] ) {
98109 const helpMenuList = document . createElement ( 'ul' )
99110 addStyleClassToElement ( helpMenuList , [ 'header-user-menu__list' ] )
100- helpMenuList . appendChild ( createUserMenuItem ( createUserMenuLink ( 'User guide' , 'https://github.com/solid/userguide' , '_blank' ) ) )
101- helpMenuList . appendChild ( createUserMenuItem ( createUserMenuLink ( 'Report a problem' , 'https://github.com/solid/solidos/issues' , '_blank' ) ) )
111+ helpMenuItems . forEach ( function ( menuItem ) {
112+ const menuItemType : string = ( menuItem as MenuItemLink ) . url ? 'url' : 'onclick'
113+ if ( menuItemType === 'url' ) {
114+ helpMenuList . appendChild ( createUserMenuItem ( createUserMenuLink ( menuItem . label , ( menuItem as MenuItemLink ) . url , ( menuItem as MenuItemLink ) . target ) ) )
115+ } else {
116+ helpMenuList . appendChild ( createUserMenuItem ( createUserMenuButton ( menuItem . label , ( menuItem as MenuItemButton ) . onclick ) ) )
117+ }
118+ } )
102119
103120 const helpMenu = document . createElement ( 'nav' )
104121
105122 addStyleClassToElement ( helpMenu , [ 'header-user-menu__navigation-menu' ] )
106123 helpMenu . setAttribute ( 'aria-hidden' , 'true' )
107124 helpMenu . appendChild ( helpMenuList )
108125
109- const helpIcon = icons . iconBase + 'noun_144.svg'
110-
111126 const helpMenuContainer = document . createElement ( 'div' )
112127 addStyleClassToElement ( helpMenuContainer , [ 'header-banner__user-menu' ] )
113128 addStyleClassToElement ( helpMenuContainer , [ 'header-user-menu' ] )
@@ -118,7 +133,7 @@ export function createHelpMenu () {
118133 helpMenuTrigger . type = 'button'
119134
120135 const helpMenuIcon = document . createElement ( 'img' )
121- helpMenuIcon . src = helpIcon
136+ helpMenuIcon . src = ( options && options . helpIcon ) ? options . helpIcon : icons . iconBase + DEFAULT_HELP_MENU_ICON
122137 addStyleClassToElement ( helpMenuIcon , [ 'header-banner__help-icon' ] )
123138 helpMenuContainer . appendChild ( helpMenuTrigger )
124139 helpMenuTrigger . appendChild ( helpMenuIcon )
@@ -158,7 +173,7 @@ export function createUserMenuButton (label: string, onClick: EventListenerOrEve
158173/**
159174 * @ignore exporting this only for the unit test
160175 */
161- export function createUserMenuLink ( label : string , href : string , target ?:string ) : HTMLElement {
176+ export function createUserMenuLink ( label : string , href : string , target ?: string ) : HTMLElement {
162177 const link = document . createElement ( 'a' )
163178 addStyleClassToElement ( link , [ 'header-user-menu__link' ] )
164179 link . href = href
@@ -170,30 +185,25 @@ export function createUserMenuLink (label: string, href: string, target?:string)
170185/**
171186 * @ignore exporting this only for the unit test
172187 */
173- export async function createUserMenu ( store : IndexedFormula , user : NamedNode , options ?: HeaderOptions ) : Promise < HTMLElement > {
188+ export async function createUserMenu ( store : IndexedFormula , user : NamedNode , userMenuList : MenuItems [ ] , options ?: HeaderOptions ) : Promise < HTMLElement > {
174189 const fetcher = ( < any > store ) . fetcher
175190 if ( fetcher ) {
176191 // Making sure that Profile is loaded before building menu
177192 await fetcher . load ( user )
178193 }
194+
179195 const loggedInMenuList = document . createElement ( 'ul' )
180196 addStyleClassToElement ( loggedInMenuList , [ 'header-user-menu__list' ] )
181- loggedInMenuList . appendChild ( createUserMenuItem ( createUserMenuLink ( 'Show your profile' , user . uri ) ) )
182- if ( options ) {
183- if ( options . menuList ) {
184- options . menuList . forEach ( function ( menuItem ) {
185- const menuItemType : string = ( menuItem as MenuItemLink ) . url ? 'url' : 'onclick'
186- if ( menuItemType === 'url' ) {
187- loggedInMenuList . appendChild ( createUserMenuItem ( createUserMenuLink ( menuItem . label , menuItem [ menuItemType ] ) ) )
188- } else {
189- loggedInMenuList . appendChild ( createUserMenuItem ( createUserMenuButton ( menuItem . label , menuItem [ menuItemType ] ) ) )
190- }
191- } )
192- }
197+ if ( userMenuList ) {
198+ userMenuList . forEach ( function ( menuItem ) {
199+ const menuItemType : string = ( menuItem as MenuItemLink ) . url ? 'url' : 'onclick'
200+ if ( menuItemType === 'url' ) {
201+ loggedInMenuList . appendChild ( createUserMenuItem ( createUserMenuLink ( menuItem . label , ( menuItem as MenuItemLink ) . url , ( menuItem as MenuItemLink ) . target ) ) )
202+ } else {
203+ loggedInMenuList . appendChild ( createUserMenuItem ( createUserMenuButton ( menuItem . label , ( menuItem as MenuItemButton ) . onclick ) ) )
204+ }
205+ } )
193206 }
194-
195- loggedInMenuList . appendChild ( createUserMenuItem ( createUserMenuButton ( 'Log out' , ( ) => authSession . logout ( ) ) ) )
196-
197207 const loggedInMenu = document . createElement ( 'nav' )
198208
199209 addStyleClassToElement ( loggedInMenu , [ 'header-user-menu__navigation-menu' ] )
0 commit comments