mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	fix: slightly improve tabs markup (#888)
This commit is contained in:
		
							parent
							
								
									2e5e25bfe5
								
							
						
					
					
						commit
						73c601cc7b
					
				| @ -1,7 +1,6 @@ | |||||||
| import React from 'react'; | import React from 'react'; | ||||||
| import AdminMenu from '../menu/AdminMenu'; | import AdminMenu from '../menu/AdminMenu'; | ||||||
| import { Alert } from '@material-ui/lab'; | import { Alert } from '@material-ui/lab'; | ||||||
| import TabNav from 'component/common/TabNav/TabNav'; |  | ||||||
| import PageContent from 'component/common/PageContent/PageContent'; | import PageContent from 'component/common/PageContent/PageContent'; | ||||||
| import ConditionallyRender from 'component/common/ConditionallyRender/ConditionallyRender'; | import ConditionallyRender from 'component/common/ConditionallyRender/ConditionallyRender'; | ||||||
| import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | import useUiConfig from 'hooks/api/getters/useUiConfig/useUiConfig'; | ||||||
| @ -9,6 +8,7 @@ import { OidcAuth } from './OidcAuth/OidcAuth'; | |||||||
| import { SamlAuth } from './SamlAuth/SamlAuth'; | import { SamlAuth } from './SamlAuth/SamlAuth'; | ||||||
| import { PasswordAuth } from './PasswordAuth/PasswordAuth'; | import { PasswordAuth } from './PasswordAuth/PasswordAuth'; | ||||||
| import { GoogleAuth } from './GoogleAuth/GoogleAuth'; | import { GoogleAuth } from './GoogleAuth/GoogleAuth'; | ||||||
|  | import { TabNav } from 'component/common/TabNav/TabNav/TabNav'; | ||||||
| 
 | 
 | ||||||
| export const AuthSettings = () => { | export const AuthSettings = () => { | ||||||
|     const { authenticationType } = useUiConfig().uiConfig; |     const { authenticationType } = useUiConfig().uiConfig; | ||||||
|  | |||||||
| @ -13,7 +13,6 @@ import ConditionallyRender from 'component/common/ConditionallyRender/Conditiona | |||||||
| import { UPDATE_APPLICATION } from 'component/providers/AccessProvider/permissions'; | import { UPDATE_APPLICATION } from 'component/providers/AccessProvider/permissions'; | ||||||
| import { ApplicationView } from '../ApplicationView/ApplicationView'; | import { ApplicationView } from '../ApplicationView/ApplicationView'; | ||||||
| import { ApplicationUpdate } from '../ApplicationUpdate/ApplicationUpdate'; | import { ApplicationUpdate } from '../ApplicationUpdate/ApplicationUpdate'; | ||||||
| import TabNav from 'component/common/TabNav/TabNav'; |  | ||||||
| import Dialogue from 'component/common/Dialogue'; | import Dialogue from 'component/common/Dialogue'; | ||||||
| import PageContent from 'component/common/PageContent'; | import PageContent from 'component/common/PageContent'; | ||||||
| import HeaderTitle from 'component/common/HeaderTitle'; | import HeaderTitle from 'component/common/HeaderTitle'; | ||||||
| @ -26,6 +25,7 @@ import useToast from 'hooks/useToast'; | |||||||
| import PermissionButton from 'component/common/PermissionButton/PermissionButton'; | import PermissionButton from 'component/common/PermissionButton/PermissionButton'; | ||||||
| import { formatDateYMD } from 'utils/formatDate'; | import { formatDateYMD } from 'utils/formatDate'; | ||||||
| import { formatUnknownError } from 'utils/formatUnknownError'; | import { formatUnknownError } from 'utils/formatUnknownError'; | ||||||
|  | import { TabNav } from 'component/common/TabNav/TabNav/TabNav'; | ||||||
| 
 | 
 | ||||||
| export const ApplicationEdit = () => { | export const ApplicationEdit = () => { | ||||||
|     const history = useHistory(); |     const history = useHistory(); | ||||||
|  | |||||||
| @ -1,45 +1,43 @@ | |||||||
| import React, { useState } from 'react'; | import React, { useState, ReactNode } from 'react'; | ||||||
| import classnames from 'classnames'; | import classnames from 'classnames'; | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| import { Tabs, Tab, Paper } from '@material-ui/core'; | import { Tabs, Tab, Paper } from '@material-ui/core'; | ||||||
|  | import { useStyles } from 'component/common/TabNav/TabNav/TabNav.styles'; | ||||||
|  | import { TabPanel } from 'component/common/TabNav/TabPanel/TabPanel'; | ||||||
| 
 | 
 | ||||||
| import TabPanel from './TabPanel'; | interface ITabNavProps { | ||||||
|  |     tabData: ITabData[]; | ||||||
|  |     className?: string; | ||||||
|  |     navClass?: string; | ||||||
|  |     startingTab?: number; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| import { useStyles } from './styles'; | interface ITabData { | ||||||
| import { useHistory } from 'react-router-dom'; |     label: string; | ||||||
|  |     component: ReactNode; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| const a11yProps = index => ({ | export const TabNav = ({ | ||||||
|     id: `tab-${index}`, |  | ||||||
|     'aria-controls': `tabpanel-${index}`, |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| const TabNav = ({ |  | ||||||
|     tabData, |     tabData, | ||||||
|     className = '', |     className = '', | ||||||
|     navClass = '', |     navClass = '', | ||||||
|     startingTab = 0, |     startingTab = 0, | ||||||
| }) => { | }: ITabNavProps) => { | ||||||
|     const styles = useStyles(); |     const styles = useStyles(); | ||||||
|     const [activeTab, setActiveTab] = useState(startingTab); |     const [activeTab, setActiveTab] = useState(startingTab); | ||||||
|     const history = useHistory(); |  | ||||||
| 
 | 
 | ||||||
|     const renderTabs = () => |     const renderTabs = () => | ||||||
|         tabData.map((tab, index) => ( |         tabData.map((tab, index) => ( | ||||||
|             <Tab |             <Tab | ||||||
|                 key={`${tab.label}_${index}`} |                 key={`${tab.label}_${index}`} | ||||||
|                 label={tab.label} |                 label={tab.label} | ||||||
|                 {...a11yProps(index)} |                 id={`tab-${index}`} | ||||||
|                 onClick={() => history.push(tab.path)} |                 aria-controls={`tabpanel-${index}`} | ||||||
|             /> |             /> | ||||||
|         )); |         )); | ||||||
| 
 | 
 | ||||||
|     const renderTabPanels = () => |     const renderTabPanels = () => | ||||||
|         tabData.map((tab, index) => ( |         tabData.map((tab, index) => ( | ||||||
|             <TabPanel |             <TabPanel key={index} value={activeTab} index={index}> | ||||||
|                 key={`tab_panel_${index}`} |  | ||||||
|                 value={activeTab} |  | ||||||
|                 index={index} |  | ||||||
|             > |  | ||||||
|                 {tab.component} |                 {tab.component} | ||||||
|             </TabPanel> |             </TabPanel> | ||||||
|         )); |         )); | ||||||
| @ -63,12 +61,3 @@ const TabNav = ({ | |||||||
|         </> |         </> | ||||||
|     ); |     ); | ||||||
| }; | }; | ||||||
| 
 |  | ||||||
| TabNav.propTypes = { |  | ||||||
|     tabData: PropTypes.array.isRequired, |  | ||||||
|     navClass: PropTypes.string, |  | ||||||
|     className: PropTypes.string, |  | ||||||
|     startingTab: PropTypes.number, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default TabNav; |  | ||||||
| @ -1,22 +0,0 @@ | |||||||
| import React from 'react'; |  | ||||||
| import PropTypes from 'prop-types'; |  | ||||||
| 
 |  | ||||||
| const TabPanel = ({ children, value, index, ...other }) => ( |  | ||||||
|     <div |  | ||||||
|         role="tabpanel" |  | ||||||
|         hidden={value !== index} |  | ||||||
|         id={`wrapped-tabpanel-${index}`} |  | ||||||
|         aria-labelledby={`wrapped-tab-${index}`} |  | ||||||
|         {...other} |  | ||||||
|     > |  | ||||||
|         {value === index && children} |  | ||||||
|     </div> |  | ||||||
| ); |  | ||||||
| 
 |  | ||||||
| TabPanel.propTypes = { |  | ||||||
|     value: PropTypes.number, |  | ||||||
|     index: PropTypes.number, |  | ||||||
|     children: PropTypes.object, |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| export default TabPanel; |  | ||||||
							
								
								
									
										18
									
								
								frontend/src/component/common/TabNav/TabPanel/TabPanel.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								frontend/src/component/common/TabNav/TabPanel/TabPanel.tsx
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | import React, { ReactNode } from 'react'; | ||||||
|  | 
 | ||||||
|  | interface ITabPanelProps { | ||||||
|  |     value: number; | ||||||
|  |     index: number; | ||||||
|  |     children: ReactNode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export const TabPanel = ({ children, value, index }: ITabPanelProps) => ( | ||||||
|  |     <div | ||||||
|  |         role="tabpanel" | ||||||
|  |         hidden={value !== index} | ||||||
|  |         id={`tabpanel-${index}`} | ||||||
|  |         aria-labelledby={`tab-${index}`} | ||||||
|  |     > | ||||||
|  |         {value === index && children} | ||||||
|  |     </div> | ||||||
|  | ); | ||||||
| @ -1,3 +0,0 @@ | |||||||
| import TabPanel from './TabPanel'; |  | ||||||
| 
 |  | ||||||
| export default TabPanel; |  | ||||||
| @ -1,3 +0,0 @@ | |||||||
| import TabNav from './TabNav'; |  | ||||||
| 
 |  | ||||||
| export default TabNav; |  | ||||||
| @ -5,7 +5,6 @@ import { Link, Route, useHistory, useParams, Switch } from 'react-router-dom'; | |||||||
| import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; | import useFeatureApi from 'hooks/api/actions/useFeatureApi/useFeatureApi'; | ||||||
| import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; | import { useFeature } from 'hooks/api/getters/useFeature/useFeature'; | ||||||
| import useProject from 'hooks/api/getters/useProject/useProject'; | import useProject from 'hooks/api/getters/useProject/useProject'; | ||||||
| import useTabs from 'hooks/useTabs'; |  | ||||||
| import useToast from 'hooks/useToast'; | import useToast from 'hooks/useToast'; | ||||||
| import { IFeatureViewParams } from 'interfaces/params'; | import { IFeatureViewParams } from 'interfaces/params'; | ||||||
| import { | import { | ||||||
| @ -33,7 +32,6 @@ export const FeatureView = () => { | |||||||
|     const { projectId, featureId } = useParams<IFeatureViewParams>(); |     const { projectId, featureId } = useParams<IFeatureViewParams>(); | ||||||
|     const { refetch: projectRefetch } = useProject(projectId); |     const { refetch: projectRefetch } = useProject(projectId); | ||||||
|     const [openTagDialog, setOpenTagDialog] = useState(false); |     const [openTagDialog, setOpenTagDialog] = useState(false); | ||||||
|     const { a11yProps } = useTabs(0); |  | ||||||
|     const { archiveFeatureToggle } = useFeatureApi(); |     const { archiveFeatureToggle } = useFeatureApi(); | ||||||
|     const { setToastData, setToastApiError } = useToast(); |     const { setToastData, setToastApiError } = useToast(); | ||||||
|     const [showDelDialog, setShowDelDialog] = useState(false); |     const [showDelDialog, setShowDelDialog] = useState(false); | ||||||
| @ -102,10 +100,7 @@ export const FeatureView = () => { | |||||||
|                     key={tab.title} |                     key={tab.title} | ||||||
|                     label={tab.title} |                     label={tab.title} | ||||||
|                     value={tab.path} |                     value={tab.path} | ||||||
|                     {...a11yProps(index)} |                     onClick={() => history.push(tab.path)} | ||||||
|                     onClick={() => { |  | ||||||
|                         history.push(tab.path); |  | ||||||
|                     }} |  | ||||||
|                     className={styles.tabButton} |                     className={styles.tabButton} | ||||||
|                 /> |                 /> | ||||||
|             ); |             ); | ||||||
|  | |||||||
| @ -9,14 +9,13 @@ import { Edit } from '@material-ui/icons'; | |||||||
| import useToast from 'hooks/useToast'; | import useToast from 'hooks/useToast'; | ||||||
| import useQueryParams from 'hooks/useQueryParams'; | import useQueryParams from 'hooks/useQueryParams'; | ||||||
| import { useEffect } from 'react'; | import { useEffect } from 'react'; | ||||||
| import useTabs from 'hooks/useTabs'; |  | ||||||
| import TabPanel from 'component/common/TabNav/TabPanel'; |  | ||||||
| import { ProjectAccess } from '../ProjectAccess/ProjectAccess'; | import { ProjectAccess } from '../ProjectAccess/ProjectAccess'; | ||||||
| import ProjectEnvironment from '../ProjectEnvironment/ProjectEnvironment'; | import ProjectEnvironment from '../ProjectEnvironment/ProjectEnvironment'; | ||||||
| import ProjectOverview from './ProjectOverview'; | import ProjectOverview from './ProjectOverview'; | ||||||
| import ProjectHealth from './ProjectHealth/ProjectHealth'; | import ProjectHealth from './ProjectHealth/ProjectHealth'; | ||||||
| import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; | import PermissionIconButton from 'component/common/PermissionIconButton/PermissionIconButton'; | ||||||
| import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions'; | import { UPDATE_PROJECT } from 'component/providers/AccessProvider/permissions'; | ||||||
|  | import { TabPanel } from 'component/common/TabNav/TabPanel/TabPanel'; | ||||||
| 
 | 
 | ||||||
| const Project = () => { | const Project = () => { | ||||||
|     const { id, activeTab } = useParams<{ id: string; activeTab: string }>(); |     const { id, activeTab } = useParams<{ id: string; activeTab: string }>(); | ||||||
| @ -27,8 +26,6 @@ const Project = () => { | |||||||
|     const styles = useStyles(); |     const styles = useStyles(); | ||||||
|     const history = useHistory(); |     const history = useHistory(); | ||||||
| 
 | 
 | ||||||
|     const { a11yProps, activeTabIdx, setActiveTab } = useTabs(0); |  | ||||||
| 
 |  | ||||||
|     const basePath = `/projects/${id}`; |     const basePath = `/projects/${id}`; | ||||||
|     const tabData = [ |     const tabData = [ | ||||||
|         { |         { | ||||||
| @ -57,6 +54,10 @@ const Project = () => { | |||||||
|         }, |         }, | ||||||
|     ]; |     ]; | ||||||
| 
 | 
 | ||||||
|  |     const activeTabIdx = activeTab | ||||||
|  |         ? tabData.findIndex(tab => tab.name === activeTab) | ||||||
|  |         : 0; | ||||||
|  | 
 | ||||||
|     useEffect(() => { |     useEffect(() => { | ||||||
|         const created = params.get('created'); |         const created = params.get('created'); | ||||||
|         const edited = params.get('edited'); |         const edited = params.get('edited'); | ||||||
| @ -75,29 +76,16 @@ const Project = () => { | |||||||
|         /* eslint-disable-next-line */ |         /* eslint-disable-next-line */ | ||||||
|     }, []); |     }, []); | ||||||
| 
 | 
 | ||||||
|     useEffect(() => { |  | ||||||
|         const tabIdx = tabData.findIndex(tab => tab.name === activeTab); |  | ||||||
|         if (tabIdx > 0) { |  | ||||||
|             setActiveTab(tabIdx); |  | ||||||
|         } else { |  | ||||||
|             setActiveTab(0); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /* eslint-disable-next-line */ |  | ||||||
|     }, []); |  | ||||||
| 
 |  | ||||||
|     const renderTabs = () => { |     const renderTabs = () => { | ||||||
|         return tabData.map((tab, index) => { |         return tabData.map((tab, index) => { | ||||||
|             return ( |             return ( | ||||||
|                 <Tab |                 <Tab | ||||||
|                     data-loading |                     data-loading | ||||||
|                     key={tab.title} |                     key={tab.title} | ||||||
|  |                     id={`tab-${index}`} | ||||||
|  |                     aria-controls={`tabpanel-${index}`} | ||||||
|                     label={tab.title} |                     label={tab.title} | ||||||
|                     {...a11yProps(index)} |                     onClick={() => history.push(tab.path)} | ||||||
|                     onClick={() => { |  | ||||||
|                         setActiveTab(index); |  | ||||||
|                         history.push(tab.path); |  | ||||||
|                     }} |  | ||||||
|                     className={styles.tabButton} |                     className={styles.tabButton} | ||||||
|                 /> |                 /> | ||||||
|             ); |             ); | ||||||
| @ -150,9 +138,6 @@ const Project = () => { | |||||||
|                 <div className={styles.tabContainer}> |                 <div className={styles.tabContainer}> | ||||||
|                     <Tabs |                     <Tabs | ||||||
|                         value={activeTabIdx} |                         value={activeTabIdx} | ||||||
|                         onChange={(_, tabId) => { |  | ||||||
|                             setActiveTab(tabId); |  | ||||||
|                         }} |  | ||||||
|                         indicatorColor="primary" |                         indicatorColor="primary" | ||||||
|                         textColor="primary" |                         textColor="primary" | ||||||
|                     > |                     > | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user