1- import { Box , Button , Divider , Sheet , Snackbar , Stack , Typography } from '@mui/joy' ;
1+ import { Box , Divider , Sheet , Stack , Typography } from '@mui/joy' ;
22import React , { useContext , useState } from 'react' ;
3- import { elementType , shape , object , string , arrayOf , oneOf , node } from 'prop-types' ;
3+ import { elementType , shape , object , string , arrayOf , node } from 'prop-types' ;
44import QueryStats from '@mui/icons-material/QueryStats' ;
5- import TipsAndUpdates from '@mui/icons-material/TipsAndUpdates' ;
65
76import { getBackgroundInfo , isMonitored , isSearchJob } from '../../core/background/BackgroundUtil.js' ;
8- import { dispatchShowDropDown } from '../../core/LayoutCntlr.js' ;
7+ import { dispatchShowDropDown , getMenuTabNodes } from '../../core/LayoutCntlr.js' ;
98import { AppPropertiesCtx } from '../../ui/AppPropertiesCtx.jsx' ;
109import { Slot , useStoreConnector } from '../../ui/SimpleComponent.jsx' ;
1110import { FileDropZone } from '../../visualize/ui/FileUploadViewPanel.jsx' ;
12- import { dispatchAddPreference , getPreference } from 'firefly/core/AppDataCntlr' ;
13-
14- export const APP_HINT_IDS = {
15- TABS_MENU : 'tabsMenu' ,
16- BG_MONITOR : 'bgMonitor'
17- } ;
11+ import { APP_HINT_IDS , AppHint , HINT_TIP_PLACEMENTS } from 'firefly/ui/AppHint' ;
1812
1913
2014export function LandingPage ( { slotProps= { } , sx, ...props } ) {
2115 const { appTitle, footer,
2216 fileDropEventAction= 'FileUploadDropDownCmd' } = useContext ( AppPropertiesCtx ) ;
2317
18+ const { first : tabsMenuHintAnchor , last : bgMonitorHintAnchor } = useStoreConnector ( getMenuTabNodes ) ;
19+
2420 const defSlotProps = {
25- tabsMenuHint : { appTitle, id : APP_HINT_IDS . TABS_MENU , hintText : 'Choose a tab to search for or upload data.' , sx : { left : '16rem' } } ,
26- bgMonitorHint : { appTitle, id : APP_HINT_IDS . BG_MONITOR , hintText : 'Load job results from background monitor' , tipPlacement : 'end' , sx : { right : 8 } } ,
21+ tabsMenuHint : { appTitle, id : APP_HINT_IDS . TABS_MENU , anchorNode : tabsMenuHintAnchor , hintText : 'Choose a tab to search for or upload data.' } ,
22+ bgMonitorHint : { appTitle, id : APP_HINT_IDS . BG_MONITOR , anchorNode : bgMonitorHintAnchor , hintText : 'Load job results from background monitor' , tipPlacement : HINT_TIP_PLACEMENTS . START } ,
2723 topSection : { title : `Welcome to ${ appTitle } ` } ,
2824 bottomSection : {
2925 icon : < QueryStats sx = { { width : '6rem' , height : '6rem' } } /> ,
@@ -47,7 +43,7 @@ export function LandingPage({slotProps={}, sx, ...props}) {
4743
4844 return (
4945 < Sheet className = 'ff-ResultsPanel-StandardView' sx = { { width : 1 , height : 1 , ...sx } } { ...props } >
50- < Slot component = { AppHint } { ...defSlotProps . tabsMenuHint } slotProps = { slotProps ?. tabsMenuHint } />
46+ { tabsMenuHintAnchor && < Slot component = { AppHint } { ...defSlotProps . tabsMenuHint } slotProps = { slotProps ?. tabsMenuHint } /> }
5147 { haveBgJobs && < Slot component = { AppHint } { ...defSlotProps . bgMonitorHint } slotProps = { slotProps ?. bgMonitorHint } /> }
5248 < FileDropZone { ...{
5349 dropEvent, setDropEvent,
@@ -118,61 +114,6 @@ function EmptyResults({icon, text, subtext, summaryText, actionItems, slotProps}
118114 ) ;
119115}
120116
121- // An app hint needs to be shown only the first time user loads an app. So this is controlled by a flag saved as app preference
122- export const appHintPrefName = ( appTitle , hintId ) => `showAppHint__${ appTitle } --${ hintId } ` ;
123-
124- function AppHint ( { appTitle, id, hintText, tipPlacement= 'middle' , sx= { } } ) {
125- const showAppHint = useStoreConnector ( ( ) => getPreference ( appHintPrefName ( appTitle , id ) , true ) ) ;
126-
127- const arrowTip = {
128- '&::before' : {
129- content : '""' ,
130- width : '1rem' ,
131- height : '1rem' ,
132- backgroundColor : 'inherit' ,
133- transform : 'rotate(-45deg)' ,
134- position : 'absolute' ,
135- top : '-0.5rem' ,
136- left : 'calc(50% - 0.5rem)' ,
137- ...tipPlacement === 'start' && { left : 'var(--Snackbar-padding)' } ,
138- ...tipPlacement === 'end' && { left : 'auto' , right : 'var(--Snackbar-padding)' }
139- }
140- } ;
141-
142- // to undo positioning controlled by anchorOrigin prop of Snackbar, and to place it directly below Banner
143- const positioningSx = {
144- position : 'absolute' ,
145- top : '0.75rem' ,
146- left : 'auto' ,
147- right : 'auto' ,
148- bottom : 'auto'
149- } ;
150-
151- return (
152- < Snackbar open = { Boolean ( showAppHint ) }
153- size = 'lg'
154- variant = 'solid' //to make it look different from alerts
155- color = 'primary'
156- invertedColors = { true }
157- onClose = { ( e , reason ) => {
158- //don't close a hint if the click made outside it (clickaway) originated from another hint
159- if ( reason === 'clickaway' && e ?. target ?. closest ( '.MuiSnackbar-root' ) ) return ;
160- dispatchAddPreference ( appHintPrefName ( appTitle , id ) , false ) ;
161- } }
162- sx = { { ...positioningSx , ...sx , ...arrowTip } }
163- startDecorator = { < TipsAndUpdates /> }
164- endDecorator = {
165- < Button
166- onClick = { ( ) => dispatchAddPreference ( appHintPrefName ( appTitle , id ) , false ) }
167- variant = 'outlined'
168- color = 'primary' >
169- Got it
170- </ Button >
171- } >
172- { hintText }
173- </ Snackbar >
174- ) ;
175- }
176117
177118
178119LandingPage . propTypes = {
@@ -216,12 +157,3 @@ EmptyResults.propTypes = {
216157 } ) ) ,
217158 slotProps : object ,
218159} ;
219-
220-
221- AppHint . propTypes = {
222- appTitle : string . isRequired ,
223- id : string . isRequired ,
224- hintText : string . isRequired ,
225- tipPlacement : oneOf ( [ 'start' , 'middle' , 'end' ] ) ,
226- sx : object ,
227- } ;
0 commit comments