mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-30 20:55:42 +00:00 
			
		
		
		
	feat(frontend): Add samples for dashboard (#10306)
* feat(forntend): Add sampels to dashboard Closes #9990 * add sessions storage to disable sample dash once cleared/removed
This commit is contained in:
		| @@ -1,5 +1,13 @@ | |||||||
| import { t } from '@lingui/core/macro'; | import { t } from '@lingui/core/macro'; | ||||||
| import { Alert, Card, Center, Divider, Loader, Text } from '@mantine/core'; | import { | ||||||
|  |   Alert, | ||||||
|  |   Card, | ||||||
|  |   Center, | ||||||
|  |   Divider, | ||||||
|  |   Loader, | ||||||
|  |   Space, | ||||||
|  |   Text | ||||||
|  | } from '@mantine/core'; | ||||||
| import { useDisclosure, useHotkeys } from '@mantine/hooks'; | import { useDisclosure, useHotkeys } from '@mantine/hooks'; | ||||||
| import { IconExclamationCircle, IconInfoCircle } from '@tabler/icons-react'; | import { IconExclamationCircle, IconInfoCircle } from '@tabler/icons-react'; | ||||||
| import { useCallback, useEffect, useMemo, useState } from 'react'; | import { useCallback, useEffect, useMemo, useState } from 'react'; | ||||||
| @@ -21,13 +29,21 @@ export default function DashboardLayout() { | |||||||
|   const [widgets, setWidgets] = useState<DashboardWidgetProps[]>([]); |   const [widgets, setWidgets] = useState<DashboardWidgetProps[]>([]); | ||||||
|  |  | ||||||
|   // local/remote storage values for widget / layout |   // local/remote storage values for widget / layout | ||||||
|   const [remoteWidgets, setRemoteWidgets, remoteLayouts, setRemoteLayouts] = |   const [ | ||||||
|     useLocalState( |     remoteWidgets, | ||||||
|  |     setRemoteWidgets, | ||||||
|  |     remoteLayouts, | ||||||
|  |     setRemoteLayouts, | ||||||
|  |     showSampleDashboard, | ||||||
|  |     setShowSampleDashboard | ||||||
|  |   ] = useLocalState( | ||||||
|     useShallow((state) => [ |     useShallow((state) => [ | ||||||
|       state.widgets, |       state.widgets, | ||||||
|       state.setWidgets, |       state.setWidgets, | ||||||
|       state.layouts, |       state.layouts, | ||||||
|         state.setLayouts |       state.setLayouts, | ||||||
|  |       state.showSampleDashboard, | ||||||
|  |       state.setShowSampleDashboard | ||||||
|     ]) |     ]) | ||||||
|   ); |   ); | ||||||
|  |  | ||||||
| @@ -75,6 +91,9 @@ export default function DashboardLayout() { | |||||||
|       ); |       ); | ||||||
|  |  | ||||||
|       if (newWidget) { |       if (newWidget) { | ||||||
|  |         if (showSampleDashboard) { | ||||||
|  |           setShowSampleDashboard(false); | ||||||
|  |         } | ||||||
|         setWidgets([...widgets, newWidget]); |         setWidgets([...widgets, newWidget]); | ||||||
|       } |       } | ||||||
|  |  | ||||||
| @@ -195,10 +214,48 @@ export default function DashboardLayout() { | |||||||
|  |  | ||||||
|   // Clear all widgets from the dashboard |   // Clear all widgets from the dashboard | ||||||
|   const clearWidgets = useCallback(() => { |   const clearWidgets = useCallback(() => { | ||||||
|  |     if (showSampleDashboard) { | ||||||
|  |       setShowSampleDashboard(false); | ||||||
|  |     } | ||||||
|     setWidgets([]); |     setWidgets([]); | ||||||
|     setLayouts({}); |     setLayouts({}); | ||||||
|   }, []); |   }, []); | ||||||
|  |  | ||||||
|  |   const defaultLayouts = { | ||||||
|  |     lg: [ | ||||||
|  |       { | ||||||
|  |         w: 6, | ||||||
|  |         h: 4, | ||||||
|  |         x: 0, | ||||||
|  |         y: 0, | ||||||
|  |         i: 'gstart', | ||||||
|  |         minW: 5, | ||||||
|  |         minH: 4, | ||||||
|  |         moved: false, | ||||||
|  |         static: false | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         w: 6, | ||||||
|  |         h: 4, | ||||||
|  |         x: 6, | ||||||
|  |         y: 0, | ||||||
|  |         i: 'news', | ||||||
|  |         minW: 5, | ||||||
|  |         minH: 4, | ||||||
|  |         moved: false, | ||||||
|  |         static: false | ||||||
|  |       } | ||||||
|  |     ] | ||||||
|  |   }; | ||||||
|  |   const loadWigs = ['news', 'gstart']; | ||||||
|  |   const defaultWidgets = useMemo(() => { | ||||||
|  |     return loadWigs | ||||||
|  |       .map((lwid: string) => | ||||||
|  |         availableWidgets.items.find((wid) => wid.label === lwid) | ||||||
|  |       ) | ||||||
|  |       .filter((widget): widget is DashboardWidgetProps => widget !== undefined); | ||||||
|  |   }, [availableWidgets.items, defaultLayouts]); | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <> |     <> | ||||||
|       <DashboardWidgetDrawer |       <DashboardWidgetDrawer | ||||||
| @@ -228,6 +285,7 @@ export default function DashboardLayout() { | |||||||
|       {layouts && loaded && availableWidgets.loaded ? ( |       {layouts && loaded && availableWidgets.loaded ? ( | ||||||
|         <> |         <> | ||||||
|           {widgetLabels.length == 0 ? ( |           {widgetLabels.length == 0 ? ( | ||||||
|  |             <> | ||||||
|               <Center> |               <Center> | ||||||
|                 <Card shadow='xs' padding='xl' style={{ width: '100%' }}> |                 <Card shadow='xs' padding='xl' style={{ width: '100%' }}> | ||||||
|                   <Alert |                   <Alert | ||||||
| @@ -239,7 +297,49 @@ export default function DashboardLayout() { | |||||||
|                   </Alert> |                   </Alert> | ||||||
|                 </Card> |                 </Card> | ||||||
|               </Center> |               </Center> | ||||||
|  |               {showSampleDashboard && ( | ||||||
|  |                 <> | ||||||
|  |                   <Space h='lg' /> | ||||||
|  |                   {WidgetGrid( | ||||||
|  |                     defaultLayouts, | ||||||
|  |                     () => {}, | ||||||
|  |                     editing, | ||||||
|  |                     defaultWidgets, | ||||||
|  |                     removing, | ||||||
|  |                     () => {} | ||||||
|  |                   )} | ||||||
|  |                 </> | ||||||
|  |               )} | ||||||
|  |             </> | ||||||
|           ) : ( |           ) : ( | ||||||
|  |             WidgetGrid( | ||||||
|  |               layouts, | ||||||
|  |               onLayoutChange, | ||||||
|  |               editing, | ||||||
|  |               widgets, | ||||||
|  |               removing, | ||||||
|  |               removeWidget | ||||||
|  |             ) | ||||||
|  |           )} | ||||||
|  |         </> | ||||||
|  |       ) : ( | ||||||
|  |         <Center> | ||||||
|  |           <Loader size='xl' /> | ||||||
|  |         </Center> | ||||||
|  |       )} | ||||||
|  |     </> | ||||||
|  |   ); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function WidgetGrid( | ||||||
|  |   layouts: {}, | ||||||
|  |   onLayoutChange: (layout: any, newLayouts: any) => void, | ||||||
|  |   editing: boolean, | ||||||
|  |   widgets: DashboardWidgetProps[], | ||||||
|  |   removing: boolean, | ||||||
|  |   removeWidget: (widget: string) => void | ||||||
|  | ) { | ||||||
|  |   return ( | ||||||
|     <ReactGridLayout |     <ReactGridLayout | ||||||
|       className='dashboard-layout' |       className='dashboard-layout' | ||||||
|       breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }} |       breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }} | ||||||
| @@ -265,13 +365,5 @@ export default function DashboardLayout() { | |||||||
|         }); |         }); | ||||||
|       })} |       })} | ||||||
|     </ReactGridLayout> |     </ReactGridLayout> | ||||||
|           )} |  | ||||||
|         </> |  | ||||||
|       ) : ( |  | ||||||
|         <Center> |  | ||||||
|           <Loader size='xl' /> |  | ||||||
|         </Center> |  | ||||||
|       )} |  | ||||||
|     </> |  | ||||||
|   ); |   ); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,6 +31,8 @@ interface LocalStateProps { | |||||||
|   setWidgets: (widgets: string[], noPatch?: boolean) => void; |   setWidgets: (widgets: string[], noPatch?: boolean) => void; | ||||||
|   layouts: any; |   layouts: any; | ||||||
|   setLayouts: (layouts: any, noPatch?: boolean) => void; |   setLayouts: (layouts: any, noPatch?: boolean) => void; | ||||||
|  |   showSampleDashboard: boolean; | ||||||
|  |   setShowSampleDashboard: (value: boolean) => void; | ||||||
|   // panels |   // panels | ||||||
|   lastUsedPanels: Record<string, string>; |   lastUsedPanels: Record<string, string>; | ||||||
|   setLastUsedPanel: (panelKey: string) => (value: string) => void; |   setLastUsedPanel: (panelKey: string) => (value: string) => void; | ||||||
| @@ -118,6 +120,10 @@ export const useLocalState = create<LocalStateProps>()( | |||||||
|         if (!noPatch) |         if (!noPatch) | ||||||
|           patchUser('widgets', { widgets: get().widgets, layouts: newLayouts }); |           patchUser('widgets', { widgets: get().widgets, layouts: newLayouts }); | ||||||
|       }, |       }, | ||||||
|  |       showSampleDashboard: true, | ||||||
|  |       setShowSampleDashboard: (value) => { | ||||||
|  |         set({ showSampleDashboard: value }); | ||||||
|  |       }, | ||||||
|       // panels |       // panels | ||||||
|       lastUsedPanels: {}, |       lastUsedPanels: {}, | ||||||
|       setLastUsedPanel: (panelKey) => (value) => { |       setLastUsedPanel: (panelKey) => (value) => { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user