mirror of
https://github.com/Unleash/unleash.git
synced 2025-08-04 13:48:56 +02: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