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