@@ -311,11 +311,15 @@ export default function (context) {
311311 * @param {Function } [options.onClose] If given, will present an X for the dashboard, and call this method when clicked
312312 * @returns Promise<{Element}> - the div that holds the dashboard
313313 */
314- async function globalAppTabs ( subject , options = { } ) {
314+ async function globalAppTabs ( options = { } ) {
315315 console . log ( 'globalAppTabs @@' )
316316 const div = dom . createElement ( 'div' )
317317 const me = authn . currentUser ( )
318- const items = await getDashboardItems ( subject )
318+ if ( ! me ) {
319+ alert ( 'Must be logged in for this' )
320+ throw new Error ( 'Not logged in' )
321+ }
322+ const items = await getDashboardItems ( )
319323
320324 const selectedItem = options . selectedTab
321325 ? items . find (
@@ -329,29 +333,11 @@ export default function (context) {
329333
330334 div . dataset . globalPaneName = selectedItem . tabName || selectedItem . paneName
331335
332- if ( typeof options . onClose === 'function' ) {
333- const closeButton = dom . createElement ( 'button' )
334- closeButton . type = 'button'
335- closeButton . className = 'dashboard-close'
336- closeButton . textContent = '×'
337- closeButton . addEventListener ( 'click' , options . onClose )
338- div . appendChild ( closeButton )
339- }
340-
341336 const content = div . appendChild ( dom . createElement ( 'div' ) )
342- const webId = subject || selectedItem . subject || me
343- if ( ! webId ) {
344- const message = dom . createElement ( 'div' )
345- message . textContent =
346- 'Unable to display this dashboard item because no profile is loaded.'
347- content . appendChild ( message )
348- return div
349- }
350-
351337 const pane = paneRegistry . byName ( selectedItem . paneName ) // 20190701
352338 const table = content . appendChild ( dom . createElement ( 'table' ) )
353339 thisOutline . GotoSubject (
354- webId ,
340+ selectedItem . subject || me ,
355341 true ,
356342 pane ,
357343 false ,
@@ -363,30 +349,26 @@ export default function (context) {
363349 }
364350 this . getDashboard = globalAppTabs
365351
366- async function getDashboardItems ( subject ) {
352+ async function getDashboardItems ( ) {
353+ const me = authn . currentUser ( )
354+ if ( ! me ) return [ ]
367355 const div = dom . createElement ( 'div' )
368356 const panes = [
369357 {
370358 paneName : 'profile' ,
371- subject,
372- label : 'Profile ' ,
359+ subject : me ,
360+ label : 'Your profile ' ,
373361 icon : UI . icons . iconBase + 'noun_15059.svg'
374362 } ,
375363 {
376364 paneName : 'social' , // loads socialPane
377- subject,
378- label : 'Friends ' ,
365+ subject : me ,
366+ label : 'Your friends ' ,
379367 icon : UI . icons . originalIconBase + 'foaf/foafTiny.gif'
380368 }
381369 ]
382370
383- // if we are not logged in, we get the webId from the URI
384- const me = authn . currentUser ( )
385- if ( ! me ) {
386- return panes
387- }
388-
389- const [ pods ] = await Promise . all ( [ getPods ( subject , me ) ] )
371+ const [ pods ] = await Promise . all ( [ getPods ( ) ] )
390372
391373 panes . push ( ...pods )
392374
@@ -400,64 +382,19 @@ export default function (context) {
400382 */
401383 {
402384 paneName : 'home' ,
403- label : 'Stuff ' ,
385+ label : 'Your dashboard ' ,
404386 icon : UI . icons . iconBase + 'noun_547570.svg'
405387 } ,
406388 {
407389 paneName : 'basicPreferences' ,
408- label : 'Preferences ' ,
390+ label : 'Your preferences ' ,
409391 icon : UI . icons . iconBase + 'noun_Sliders_341315_000000.svg'
410392 }
411393 )
412394
413395 return panes
414396
415- async function getPods ( subject , me ) {
416- // Previous behavior (kept here for reference): when logged in, we only
417- // loaded storages from the logged-in WebID, which could hide the viewed
418- // profile's storage in mixed-profile browsing scenarios.
419- //
420- // let webId
421- // if (me) {
422- // webId = me
423- // try {
424- // await kb.fetcher.load(me.doc())
425- // } catch (err) {
426- // console.error('Unable to load profile', err)
427- // return []
428- // }
429- // } else {
430- // webId = await loadProfileFromURI(subject, kb, kb.fetcher)
431- // }
432- // let pods = kb.each(webId, ns.space('storage'), null, webId.doc())
433-
434- // New behavior: merge storages from both the logged-in profile and the
435- // currently viewed profile so both can appear in the left menu.
436- const webIds = [ ]
437-
438- if ( me && me . termType === 'NamedNode' ) {
439- webIds . push ( me )
440- }
441-
442- try {
443- // Also include the profile being viewed, so when I view someone else's
444- // profile while logged in I can still see both storages in the menu.
445- const subjectWebId = await loadProfileFromURI ( subject , kb , kb . fetcher )
446- if (
447- subjectWebId &&
448- subjectWebId . termType === 'NamedNode' &&
449- ! webIds . find ( node => node . equals ( subjectWebId ) )
450- ) {
451- webIds . push ( subjectWebId )
452- }
453- } catch ( err ) {
454- console . error ( 'Unable to resolve subject profile' , err )
455- }
456-
457- if ( ! webIds . length ) {
458- return [ ]
459- }
460-
397+ async function getPods ( ) {
461398 async function addPodStorage ( pod ) { // namedNode
462399 await loadContainerRepresentation ( pod )
463400 if ( kb . holds ( pod , ns . rdf ( 'type' ) , ns . space ( 'Storage' ) , pod . doc ( ) ) ) {
@@ -477,23 +414,19 @@ export default function (context) {
477414 // TODO should url.origin be added to pods list when there are no pim:Storage ???
478415 }
479416
480- // New behavior continued: resolve and aggregate storages from each WebID.
481- let pods = [ ]
482- for ( const webId of webIds ) {
483- try {
484- await kb . fetcher . load ( webId . doc ( ) )
485- pods = pods . concat ( kb . each ( webId , ns . space ( 'storage' ) , null , webId . doc ( ) ) )
486- } catch ( err ) {
487- console . error ( 'Unable to load profile' , err )
488- }
417+ try {
418+ // need to make sure that profile is loaded
419+ await kb . fetcher . load ( me . doc ( ) )
420+ } catch ( err ) {
421+ console . error ( 'Unable to load profile' , err )
422+ return [ ]
489423 }
490-
491- await Promise . all (
492- pods . map ( async ( pod ) => {
493- // TODO use addPodStorageFromUrl(pod.uri) to check for pim:Storage ???
494- await loadContainerRepresentation ( pod )
495- } )
496- )
424+ // load pod's storages from profile
425+ let pods = kb . each ( me , ns . space ( 'storage' ) , null , me . doc ( ) )
426+ pods . map ( async ( pod ) => {
427+ // TODO use addPodStorageFromUrl(pod.uri) to check for pim:Storage ???
428+ await loadContainerRepresentation ( pod )
429+ } )
497430
498431 try {
499432 // if uri then SolidOS is a browse.html web app
@@ -515,10 +448,7 @@ export default function (context) {
515448 if ( ! pods . length ) return [ ]
516449 return pods . map ( ( pod , index ) => {
517450 function split ( item ) { return item . uri . split ( '//' ) [ 1 ] . slice ( 0 , - 1 ) }
518- // Previous label logic kept as reference (single-webId flow):
519- // const label = split(webId).startsWith(split(pod)) ? 'Storage' : split(pod)
520- const meWebId = me && me . termType === 'NamedNode' ? me : null
521- const label = meWebId && split ( meWebId ) . startsWith ( split ( pod ) ) ? 'Storage' : split ( pod )
451+ const label = split ( me ) . startsWith ( split ( pod ) ) ? 'Your storage' : split ( pod )
522452 return {
523453 paneName : 'folder' ,
524454 tabName : `folder-${ index } ` ,
@@ -552,7 +482,7 @@ export default function (context) {
552482
553483 /**
554484 * Call this method to show the global dashboard.
555- * @param { NamedNode } [subject] The subject form the URI
485+ *
556486 * @param {Object } [options] A set of options that can be passed
557487 * @param {string } [options.pane] To open a specific dashboard pane
558488 * @returns {Promise<void> }
@@ -598,19 +528,14 @@ export default function (context) {
598528 dashboardContainer . innerHTML = ''
599529 }
600530
601- // create a new dashboard view without tab navigation
602- const dashboard = await globalAppTabs (
603- subject ,
604- {
605- selectedTab : options . pane ,
606- // onClose: closeDashboard -> we do not need to close tabs anymore
607- }
608- )
531+ // create a new dashboard if not already present
532+ const dashboard = await globalAppTabs ( {
533+ selectedTab : options . pane ,
534+ // onClose: closeDashboard
535+ } )
609536
537+ // close the dashboard if user log out
610538 authSession . events . on ( 'logout' , closeDashboard )
611- if ( subject && subject . value ) {
612- dashboard . dataset . subject = subject . value
613- }
614539
615540 // finally - switch to showing dashboard
616541 hideGlobalContainer ( outlineContainer )
@@ -634,32 +559,36 @@ export default function (context) {
634559 * @param {string } [ariaLabel] Optional aria-label for accessibility
635560 * @returns {HTMLElement }
636561 */
637- function getOrCreateContainer ( id , ariaLabel ) {
638- if ( id === 'outline' ) {
639- const existingOutline = document . getElementById ( 'outline' )
562+ function getOrCreateContainer ( id ) {
563+ // OutlineView is a table
564+ if ( id === 'OutlineView' ) {
565+ const existingOutline = document . getElementById ( 'OutlineView' )
640566 if ( existingOutline ) {
641567 return existingOutline
642568 }
643569
644- const outlineHost = document . getElementById ( 'OutlineView ' )
570+ const outlineHost = document . getElementById ( 'app-view ' )
645571 if ( outlineHost ) {
646- const outlineTable = document . createElement ( 'table' )
647- outlineTable . id = 'outline'
648- outlineTable . style . width = '100%'
649- outlineHost . appendChild ( outlineTable )
650- return outlineTable
572+ const OutlineView = document . createElement ( 'table' )
573+ OutlineView . id = 'OutlineView'
574+ OutlineView . classList . add ( 'outline-view' )
575+ OutlineView . setAttribute ( 'aria-label' , 'Resource browser' )
576+ outlineHost . appendChild ( OutlineView )
577+ return OutlineView
651578 }
652579 }
653580
581+ // or we deal with the section GlobalDashboard
654582 return (
655583 document . getElementById ( id ) ||
656584 ( ( ) => {
657- const container = document . createElement ( 'section' )
658- container . id = id
659- if ( ariaLabel ) container . setAttribute ( 'aria-label' , ariaLabel )
660- const mainContainer =
661- document . querySelector ( '[role="main"]' ) || document . body
662- return mainContainer . appendChild ( container )
585+ const GlobalDashboard = document . createElement ( 'section' )
586+ GlobalDashboard . id = id
587+ GlobalDashboard . setAttribute ( 'aria-label' , 'Dashboard' )
588+ GlobalDashboard . classList . add ( 'global-dashboard' )
589+ const dashboardHost =
590+ document . getElementById ( 'app-view' )
591+ return dashboardHost . appendChild ( GlobalDashboard )
663592 } ) ( )
664593 )
665594 }
@@ -2379,7 +2308,7 @@ export default function (context) {
23792308 @param table -- option -- default is an HTML table element in which to put the outline.
23802309*/
23812310 this . GotoSubject = function ( subject , expand , pane , solo , referrer , table ) {
2382- table = table || getOutlineContainer ( ) // if does not exist create a compatible host in the current shell
2311+ table = table || getOutlineContainer ( 'OutlineView' ) // if does not exist create a compatible host in the current shell
23832312 if ( solo ) {
23842313 UI . utils . emptyNode ( table )
23852314 table . style . width = '100%'
0 commit comments