mirror of
https://github.com/traefik/traefik.git
synced 2026-06-17 19:09:29 +03:00
Add dashboard name configuration
This commit is contained in:
@@ -231,6 +231,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
|||||||
|
|
||||||
if staticConfiguration.API != nil {
|
if staticConfiguration.API != nil {
|
||||||
version.DisableDashboardAd = staticConfiguration.API.DisableDashboardAd
|
version.DisableDashboardAd = staticConfiguration.API.DisableDashboardAd
|
||||||
|
version.DashboardName = staticConfiguration.API.DashboardName
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
|
|||||||
| <a id="opt-api" href="#opt-api" title="#opt-api">api</a> | Enable api/dashboard. | false |
|
| <a id="opt-api" href="#opt-api" title="#opt-api">api</a> | Enable api/dashboard. | false |
|
||||||
| <a id="opt-api-basepath" href="#opt-api-basepath" title="#opt-api-basepath">api.basepath</a> | Defines the base path where the API and Dashboard will be exposed. | / |
|
| <a id="opt-api-basepath" href="#opt-api-basepath" title="#opt-api-basepath">api.basepath</a> | Defines the base path where the API and Dashboard will be exposed. | / |
|
||||||
| <a id="opt-api-dashboard" href="#opt-api-dashboard" title="#opt-api-dashboard">api.dashboard</a> | Activate dashboard. | true |
|
| <a id="opt-api-dashboard" href="#opt-api-dashboard" title="#opt-api-dashboard">api.dashboard</a> | Activate dashboard. | true |
|
||||||
|
| <a id="opt-api-dashboardname" href="#opt-api-dashboardname" title="#opt-api-dashboardname">api.dashboardname</a> | Custom name for the dashboard. | |
|
||||||
| <a id="opt-api-debug" href="#opt-api-debug" title="#opt-api-debug">api.debug</a> | Enable additional endpoints for debugging and profiling. | false |
|
| <a id="opt-api-debug" href="#opt-api-debug" title="#opt-api-debug">api.debug</a> | Enable additional endpoints for debugging and profiling. | false |
|
||||||
| <a id="opt-api-disabledashboardad" href="#opt-api-disabledashboardad" title="#opt-api-disabledashboardad">api.disabledashboardad</a> | Disable ad in the dashboard. | false |
|
| <a id="opt-api-disabledashboardad" href="#opt-api-disabledashboardad" title="#opt-api-disabledashboardad">api.disabledashboardad</a> | Disable ad in the dashboard. | false |
|
||||||
| <a id="opt-api-insecure" href="#opt-api-insecure" title="#opt-api-insecure">api.insecure</a> | Activate API directly on the entryPoint named traefik. | false |
|
| <a id="opt-api-insecure" href="#opt-api-insecure" title="#opt-api-insecure">api.insecure</a> | Activate API directly on the entryPoint named traefik. | false |
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ type API struct {
|
|||||||
Dashboard bool `description:"Activate dashboard." json:"dashboard,omitempty" toml:"dashboard,omitempty" yaml:"dashboard,omitempty" export:"true"`
|
Dashboard bool `description:"Activate dashboard." json:"dashboard,omitempty" toml:"dashboard,omitempty" yaml:"dashboard,omitempty" export:"true"`
|
||||||
Debug bool `description:"Enable additional endpoints for debugging and profiling." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"`
|
Debug bool `description:"Enable additional endpoints for debugging and profiling." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"`
|
||||||
DisableDashboardAd bool `description:"Disable ad in the dashboard." json:"disableDashboardAd,omitempty" toml:"disableDashboardAd,omitempty" yaml:"disableDashboardAd,omitempty" export:"true"`
|
DisableDashboardAd bool `description:"Disable ad in the dashboard." json:"disableDashboardAd,omitempty" toml:"disableDashboardAd,omitempty" yaml:"disableDashboardAd,omitempty" export:"true"`
|
||||||
|
DashboardName string `description:"Custom name for the dashboard." json:"dashboardName,omitempty" toml:"dashboardName,omitempty" yaml:"dashboardName,omitempty" export:"true"`
|
||||||
// TODO: Re-enable statistics
|
// TODO: Re-enable statistics
|
||||||
// Statistics *types.Statistics `description:"Enable more detailed statistics." json:"statistics,omitempty" toml:"statistics,omitempty" yaml:"statistics,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
// Statistics *types.Statistics `description:"Enable more detailed statistics." json:"statistics,omitempty" toml:"statistics,omitempty" yaml:"statistics,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||||
}
|
}
|
||||||
@@ -167,6 +168,7 @@ type API struct {
|
|||||||
func (a *API) SetDefaults() {
|
func (a *API) SetDefaults() {
|
||||||
a.BasePath = "/"
|
a.BasePath = "/"
|
||||||
a.Dashboard = true
|
a.Dashboard = true
|
||||||
|
a.DashboardName = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// RespondingTimeouts contains timeout configurations for incoming requests to the Traefik instance.
|
// RespondingTimeouts contains timeout configurations for incoming requests to the Traefik instance.
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ var (
|
|||||||
StartDate = time.Now()
|
StartDate = time.Now()
|
||||||
// DisableDashboardAd disables ad in the dashboard.
|
// DisableDashboardAd disables ad in the dashboard.
|
||||||
DisableDashboardAd = false
|
DisableDashboardAd = false
|
||||||
|
// DashboardName holds the custom name for the dashboard.
|
||||||
|
DashboardName = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler expose version routes.
|
// Handler expose version routes.
|
||||||
@@ -43,11 +45,13 @@ func (v Handler) Append(router *mux.Router) {
|
|||||||
StartDate time.Time `json:"startDate"`
|
StartDate time.Time `json:"startDate"`
|
||||||
UUID string `json:"uuid,omitempty"`
|
UUID string `json:"uuid,omitempty"`
|
||||||
DisableDashboardAd bool `json:"disableDashboardAd,omitempty"`
|
DisableDashboardAd bool `json:"disableDashboardAd,omitempty"`
|
||||||
|
DashboardName string `json:"dashboardName,omitempty"`
|
||||||
}{
|
}{
|
||||||
Version: Version,
|
Version: Version,
|
||||||
Codename: Codename,
|
Codename: Codename,
|
||||||
StartDate: StartDate,
|
StartDate: StartDate,
|
||||||
DisableDashboardAd: DisableDashboardAd,
|
DisableDashboardAd: DisableDashboardAd,
|
||||||
|
DashboardName: DashboardName,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := templatesRenderer.JSON(response, http.StatusOK, v); err != nil {
|
if err := templatesRenderer.JSON(response, http.StatusOK, v); err != nil {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { Card, Flex, H1, Skeleton, Text } from '@traefiklabs/faency'
|
import { Card, Flex, H1, Skeleton, Text } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
|
|
||||||
import MiddlewareDefinition from './MiddlewareDefinition'
|
import MiddlewareDefinition from './MiddlewareDefinition'
|
||||||
import { RenderUnknownProp } from './RenderUnknownProp'
|
import { RenderUnknownProp } from './RenderUnknownProp'
|
||||||
@@ -8,6 +7,7 @@ import { RenderUnknownProp } from './RenderUnknownProp'
|
|||||||
import { DetailsCardSkeleton } from 'components/resources/DetailsCard'
|
import { DetailsCardSkeleton } from 'components/resources/DetailsCard'
|
||||||
import ResourceErrors, { ResourceErrorsSkeleton } from 'components/resources/ResourceErrors'
|
import ResourceErrors, { ResourceErrorsSkeleton } from 'components/resources/ResourceErrors'
|
||||||
import { UsedByRoutersSection, UsedByRoutersSkeleton } from 'components/resources/UsedByRoutersSection'
|
import { UsedByRoutersSection, UsedByRoutersSkeleton } from 'components/resources/UsedByRoutersSection'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
import { NotFound } from 'pages/NotFound'
|
import { NotFound } from 'pages/NotFound'
|
||||||
|
|
||||||
type MiddlewareDetailProps = {
|
type MiddlewareDetailProps = {
|
||||||
@@ -42,9 +42,7 @@ export const MiddlewareDetail = ({ data, error, name, protocol }: MiddlewareDeta
|
|||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={data?.name || name} />
|
||||||
<title>{name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Text data-testid="error-text">
|
<Text data-testid="error-text">
|
||||||
Sorry, we could not fetch detail information for this Middleware right now. Please, try again later.
|
Sorry, we could not fetch detail information for this Middleware right now. Please, try again later.
|
||||||
</Text>
|
</Text>
|
||||||
@@ -55,9 +53,7 @@ export const MiddlewareDetail = ({ data, error, name, protocol }: MiddlewareDeta
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={name} />
|
||||||
<title>{name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Skeleton css={{ height: '$7', width: '320px', mb: '$7' }} data-testid="skeleton" />
|
<Skeleton css={{ height: '$7', width: '320px', mb: '$7' }} data-testid="skeleton" />
|
||||||
<Flex direction="column" gap={6}>
|
<Flex direction="column" gap={6}>
|
||||||
<DetailsCardSkeleton />
|
<DetailsCardSkeleton />
|
||||||
@@ -74,9 +70,7 @@ export const MiddlewareDetail = ({ data, error, name, protocol }: MiddlewareDeta
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={data.name} />
|
||||||
<title>{data.name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<H1 css={{ mb: '$7' }}>{data.name}</H1>
|
<H1 css={{ mb: '$7' }}>{data.name}</H1>
|
||||||
<Flex direction="column" gap={6}>
|
<Flex direction="column" gap={6}>
|
||||||
<MiddlewareDefinition data={data} testId="middleware-card" />
|
<MiddlewareDefinition data={data} testId="middleware-card" />
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { Flex, H1, Skeleton, Text } from '@traefiklabs/faency'
|
import { Flex, H1, Skeleton, Text } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
|
|
||||||
import { DetailsCardSkeleton } from 'components/resources/DetailsCard'
|
import { DetailsCardSkeleton } from 'components/resources/DetailsCard'
|
||||||
import ResourceErrors, { ResourceErrorsSkeleton } from 'components/resources/ResourceErrors'
|
import ResourceErrors, { ResourceErrorsSkeleton } from 'components/resources/ResourceErrors'
|
||||||
import RouterFlowDiagram, { RouterFlowDiagramSkeleton } from 'components/routers/RouterFlowDiagram'
|
import RouterFlowDiagram, { RouterFlowDiagramSkeleton } from 'components/routers/RouterFlowDiagram'
|
||||||
import TlsSection from 'components/routers/TlsSection'
|
import TlsSection from 'components/routers/TlsSection'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
import { NotFound } from 'pages/NotFound'
|
import { NotFound } from 'pages/NotFound'
|
||||||
|
|
||||||
type RouterDetailProps = {
|
type RouterDetailProps = {
|
||||||
@@ -21,9 +21,7 @@ export const RouterDetail = ({ data, error, name, protocol }: RouterDetailProps)
|
|||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={data?.name || name} />
|
||||||
<title>{name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Text data-testid="error-text">
|
<Text data-testid="error-text">
|
||||||
Sorry, we could not fetch detail information for this Router right now. Please, try again later.
|
Sorry, we could not fetch detail information for this Router right now. Please, try again later.
|
||||||
</Text>
|
</Text>
|
||||||
@@ -34,9 +32,7 @@ export const RouterDetail = ({ data, error, name, protocol }: RouterDetailProps)
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={name} />
|
||||||
<title>{name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Skeleton css={{ height: '$7', width: '320px', mb: '$7' }} data-testid="skeleton" />
|
<Skeleton css={{ height: '$7', width: '320px', mb: '$7' }} data-testid="skeleton" />
|
||||||
<Flex direction="column" gap={6}>
|
<Flex direction="column" gap={6}>
|
||||||
<RouterFlowDiagramSkeleton />
|
<RouterFlowDiagramSkeleton />
|
||||||
@@ -53,9 +49,7 @@ export const RouterDetail = ({ data, error, name, protocol }: RouterDetailProps)
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={data.name} />
|
||||||
<title>{data.name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<H1 css={{ mb: '$7' }}>{data.name}</H1>
|
<H1 css={{ mb: '$7' }}>{data.name}</H1>
|
||||||
<Flex direction="column" gap={6}>
|
<Flex direction="column" gap={6}>
|
||||||
<RouterFlowDiagram data={data} protocol={protocol} />
|
<RouterFlowDiagram data={data} protocol={protocol} />
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { Box, Flex, H1, Skeleton, Text } from '@traefiklabs/faency'
|
import { Box, Flex, H1, Skeleton, Text } from '@traefiklabs/faency'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
|
|
||||||
import MirrorServices from './MirrorServices'
|
import MirrorServices from './MirrorServices'
|
||||||
import Servers from './Servers'
|
import Servers from './Servers'
|
||||||
@@ -10,6 +9,7 @@ import WeightedServices from './WeightedServices'
|
|||||||
import { DetailsCardSkeleton } from 'components/resources/DetailsCard'
|
import { DetailsCardSkeleton } from 'components/resources/DetailsCard'
|
||||||
import { UsedByRoutersSection, UsedByRoutersSkeleton } from 'components/resources/UsedByRoutersSection'
|
import { UsedByRoutersSection, UsedByRoutersSkeleton } from 'components/resources/UsedByRoutersSection'
|
||||||
import AriaTableSkeleton from 'components/tables/AriaTableSkeleton'
|
import AriaTableSkeleton from 'components/tables/AriaTableSkeleton'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
import { NotFound } from 'pages/NotFound'
|
import { NotFound } from 'pages/NotFound'
|
||||||
|
|
||||||
type ServiceDetailProps = {
|
type ServiceDetailProps = {
|
||||||
@@ -23,9 +23,7 @@ export const ServiceDetail = ({ data, error, name, protocol }: ServiceDetailProp
|
|||||||
if (error) {
|
if (error) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={data?.name || name} />
|
||||||
<title>{name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Text data-testid="error-text">
|
<Text data-testid="error-text">
|
||||||
Sorry, we could not fetch detail information for this Service right now. Please, try again later.
|
Sorry, we could not fetch detail information for this Service right now. Please, try again later.
|
||||||
</Text>
|
</Text>
|
||||||
@@ -36,9 +34,7 @@ export const ServiceDetail = ({ data, error, name, protocol }: ServiceDetailProp
|
|||||||
if (!data) {
|
if (!data) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={name} />
|
||||||
<title>{name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Skeleton css={{ height: '$7', width: '320px', mb: '$7' }} data-testid="skeleton" />
|
<Skeleton css={{ height: '$7', width: '320px', mb: '$7' }} data-testid="skeleton" />
|
||||||
<Flex direction="column" gap={4}>
|
<Flex direction="column" gap={4}>
|
||||||
<DetailsCardSkeleton />
|
<DetailsCardSkeleton />
|
||||||
@@ -65,9 +61,7 @@ export const ServiceDetail = ({ data, error, name, protocol }: ServiceDetailProp
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title={data.name} />
|
||||||
<title>{data.name} - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<H1 css={{ mb: '$7' }}>{data.name}</H1>
|
<H1 css={{ mb: '$7' }}>{data.name}</H1>
|
||||||
<Flex direction="column" gap={6}>
|
<Flex direction="column" gap={6}>
|
||||||
<ServiceDefinition data={data} testId="service-details" />
|
<ServiceDefinition data={data} testId="service-details" />
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import { BASE_PATH } from 'libs/utils'
|
|||||||
type VersionContextProps = {
|
type VersionContextProps = {
|
||||||
showHubButton: boolean
|
showHubButton: boolean
|
||||||
version: string
|
version: string
|
||||||
|
dashboardName: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VersionContext = createContext<VersionContextProps>({
|
export const VersionContext = createContext<VersionContextProps>({
|
||||||
showHubButton: false,
|
showHubButton: false,
|
||||||
version: '',
|
version: '',
|
||||||
|
dashboardName: '',
|
||||||
})
|
})
|
||||||
|
|
||||||
type VersionProviderProps = {
|
type VersionProviderProps = {
|
||||||
@@ -19,6 +21,7 @@ type VersionProviderProps = {
|
|||||||
export const VersionProvider = ({ children }: VersionProviderProps) => {
|
export const VersionProvider = ({ children }: VersionProviderProps) => {
|
||||||
const [showHubButton, setShowHubButton] = useState(false)
|
const [showHubButton, setShowHubButton] = useState(false)
|
||||||
const [version, setVersion] = useState('')
|
const [version, setVersion] = useState('')
|
||||||
|
const [dashboardName, setDashboardName] = useState('')
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchVersion = async () => {
|
const fetchVersion = async () => {
|
||||||
@@ -30,6 +33,7 @@ export const VersionProvider = ({ children }: VersionProviderProps) => {
|
|||||||
const data: API.Version = await response.json()
|
const data: API.Version = await response.json()
|
||||||
setShowHubButton(!data.disableDashboardAd)
|
setShowHubButton(!data.disableDashboardAd)
|
||||||
setVersion(data.Version)
|
setVersion(data.Version)
|
||||||
|
setDashboardName(data.dashboardName || '')
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
@@ -38,5 +42,5 @@ export const VersionProvider = ({ children }: VersionProviderProps) => {
|
|||||||
fetchVersion()
|
fetchVersion()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return <VersionContext.Provider value={{ showHubButton, version }}>{children}</VersionContext.Provider>
|
return <VersionContext.Provider value={{ showHubButton, version, dashboardName }}>{children}</VersionContext.Provider>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ const mockVerifySignature = vi.mocked(verifySignature)
|
|||||||
|
|
||||||
const createWrapper = (showHubButton: boolean) => {
|
const createWrapper = (showHubButton: boolean) => {
|
||||||
return ({ children }: { children: ReactNode }) => (
|
return ({ children }: { children: ReactNode }) => (
|
||||||
<VersionContext.Provider value={{ showHubButton, version: '1.0.0' }}>{children}</VersionContext.Provider>
|
<VersionContext.Provider value={{ showHubButton, version: '1.0.0', dashboardName: '' }}>
|
||||||
|
{children}
|
||||||
|
</VersionContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Flex, globalCss, styled } from '@traefiklabs/faency'
|
import { Flex, globalCss, styled } from '@traefiklabs/faency'
|
||||||
import { ReactNode, useMemo, useState } from 'react'
|
import { ReactNode, useMemo, useState } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import { useLocation } from 'react-router-dom'
|
import { useLocation } from 'react-router-dom'
|
||||||
|
|
||||||
import Container from './Container'
|
import Container from './Container'
|
||||||
|
import PageTitle from './PageTitle'
|
||||||
|
|
||||||
import { ToastPool } from 'components/ToastPool'
|
import { ToastPool } from 'components/ToastPool'
|
||||||
import { ToastProvider } from 'contexts/toasts'
|
import { ToastProvider } from 'contexts/toasts'
|
||||||
@@ -64,9 +64,7 @@ const Page = ({ children }: Props) => {
|
|||||||
return (
|
return (
|
||||||
<ToastProvider>
|
<ToastProvider>
|
||||||
{globalStyles()}
|
{globalStyles()}
|
||||||
<Helmet>
|
<PageTitle />
|
||||||
<title>Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Flex>
|
<Flex>
|
||||||
<SideBarPanel isOpen={isSideBarPanelOpen} onOpenChange={setIsSideBarPanelOpen} />
|
<SideBarPanel isOpen={isSideBarPanelOpen} onOpenChange={setIsSideBarPanelOpen} />
|
||||||
<SideNav isExpanded={isSideBarPanelOpen} onSidePanelToggle={() => setIsSideBarPanelOpen(true)} isResponsive />
|
<SideNav isExpanded={isSideBarPanelOpen} onSidePanelToggle={() => setIsSideBarPanelOpen(true)} isResponsive />
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { waitFor } from '@testing-library/react'
|
||||||
|
|
||||||
|
import PageTitle from './PageTitle'
|
||||||
|
|
||||||
|
import { VersionContext } from 'contexts/version'
|
||||||
|
import { renderWithProviders } from 'utils/test'
|
||||||
|
|
||||||
|
describe('<PageTitle />', () => {
|
||||||
|
it('should render default title without page title or dashboard name', async () => {
|
||||||
|
renderWithProviders(<PageTitle />)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(document.title).toBe('Traefik Proxy')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render with page title', async () => {
|
||||||
|
renderWithProviders(<PageTitle title="Dashboard" />)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(document.title).toBe('Dashboard - Traefik Proxy')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render with dashboard name', async () => {
|
||||||
|
renderWithProviders(
|
||||||
|
<VersionContext.Provider value={{ showHubButton: false, version: '', dashboardName: 'MyDashboard' }}>
|
||||||
|
<PageTitle />
|
||||||
|
</VersionContext.Provider>,
|
||||||
|
)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(document.title).toBe('Traefik Proxy [MyDashboard]')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render with page title and dashboard name', async () => {
|
||||||
|
renderWithProviders(
|
||||||
|
<VersionContext.Provider value={{ showHubButton: false, version: '', dashboardName: 'MyDashboard' }}>
|
||||||
|
<PageTitle title="Dashboard" />
|
||||||
|
</VersionContext.Provider>,
|
||||||
|
)
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(document.title).toBe('Dashboard - Traefik Proxy [MyDashboard]')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { useContext, useMemo } from 'react'
|
||||||
|
import { Helmet } from 'react-helmet-async'
|
||||||
|
|
||||||
|
import { VersionContext } from 'contexts/version'
|
||||||
|
|
||||||
|
const PageTitle = ({ title }: { title?: string }) => {
|
||||||
|
const { dashboardName } = useContext(VersionContext)
|
||||||
|
|
||||||
|
const pageTitle = useMemo(
|
||||||
|
() => `${title ? `${title} - ` : ''}Traefik Proxy${dashboardName ? ` [${dashboardName}]` : ''}`,
|
||||||
|
[dashboardName, title],
|
||||||
|
)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Helmet>
|
||||||
|
<title>{pageTitle}</title>
|
||||||
|
</Helmet>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageTitle
|
||||||
@@ -2,5 +2,6 @@
|
|||||||
"Version": "3.6.0",
|
"Version": "3.6.0",
|
||||||
"Codename": "ramequin",
|
"Codename": "ramequin",
|
||||||
"disableDashboardAd": false,
|
"disableDashboardAd": false,
|
||||||
"startDate": "2025-03-28T14:58:25.8937758+01:00"
|
"startDate": "2025-03-28T14:58:25.8937758+01:00",
|
||||||
}
|
"dashboardName": "Pre-prod"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import { Box, Button, Flex, H1, Text } from '@traefiklabs/faency'
|
import { Box, Button, Flex, H1, Text } from '@traefiklabs/faency'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
|
|
||||||
export const NotFound = () => {
|
export const NotFound = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex css={{ flexDirection: 'column', alignItems: 'center', p: '$6' }} data-testid="Not found page">
|
<Flex css={{ flexDirection: 'column', alignItems: 'center', p: '$6' }} data-testid="Not found page">
|
||||||
<Helmet>
|
<PageTitle title="Not found" />
|
||||||
<title>Not found - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<Box>
|
<Box>
|
||||||
<H1 style={{ fontSize: '80px', lineHeight: '120px' }}>404</H1>
|
<H1 style={{ fontSize: '80px', lineHeight: '120px' }}>404</H1>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { Card, CSS, Flex, Grid, H2, Text } from '@traefiklabs/faency'
|
import { Card, CSS, Flex, Grid, H2, Text } from '@traefiklabs/faency'
|
||||||
import { ReactNode, useMemo } from 'react'
|
import { ReactNode, useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useSWR from 'swr'
|
import useSWR from 'swr'
|
||||||
|
|
||||||
import ProviderIcon from 'components/icons/providers'
|
import ProviderIcon from 'components/icons/providers'
|
||||||
import FeatureCard, { FeatureCardSkeleton } from 'components/resources/FeatureCard'
|
import FeatureCard, { FeatureCardSkeleton } from 'components/resources/FeatureCard'
|
||||||
import ResourceCard from 'components/resources/ResourceCard'
|
import ResourceCard from 'components/resources/ResourceCard'
|
||||||
import TraefikResourceStatsCard, { StatsCardSkeleton } from 'components/resources/TraefikResourceStatsCard'
|
import TraefikResourceStatsCard, { StatsCardSkeleton } from 'components/resources/TraefikResourceStatsCard'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
import { capitalizeFirstLetter } from 'utils/string'
|
import { capitalizeFirstLetter } from 'utils/string'
|
||||||
|
|
||||||
const RESOURCES = ['routers', 'services', 'middlewares']
|
const RESOURCES = ['routers', 'services', 'middlewares']
|
||||||
@@ -77,9 +77,7 @@ export const Dashboard = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex direction="column" gap={6}>
|
<Flex direction="column" gap={6}>
|
||||||
<Helmet>
|
<PageTitle title="Dashboard" />
|
||||||
<title>Dashboard - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<SectionContainer title="Entrypoints" css={{ mt: 0 }}>
|
<SectionContainer title="Entrypoints" css={{ mt: 0 }}>
|
||||||
{entrypoints?.map((i, idx) => (
|
{entrypoints?.map((i, idx) => (
|
||||||
<ResourceCard
|
<ResourceCard
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ import { searchParamsToState, TableFilter } from 'components/tables/TableFilter'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
import { parseMiddlewareType } from 'libs/parsers'
|
import { parseMiddlewareType } from 'libs/parsers'
|
||||||
|
|
||||||
export const makeRowRender = (): RenderRowType => {
|
export const makeRowRender = (): RenderRowType => {
|
||||||
@@ -99,9 +99,7 @@ export const HttpMiddlewares = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="HTTP Middlewares" />
|
||||||
<title>HTTP Middlewares - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<HttpMiddlewaresRender
|
<HttpMiddlewaresRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Box, Flex } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Box, Flex } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -17,6 +16,7 @@ import Tooltip from 'components/Tooltip'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
|
|
||||||
export const makeRowRender = (protocol = 'http'): RenderRowType => {
|
export const makeRowRender = (protocol = 'http'): RenderRowType => {
|
||||||
const HttpRoutersRenderRow = (row) => (
|
const HttpRoutersRenderRow = (row) => (
|
||||||
@@ -132,9 +132,7 @@ export const HttpRouters = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="HTTP Routers" />
|
||||||
<title>HTTP Routers - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<HttpRoutersRender
|
<HttpRoutersRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex, Text } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex, Text } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ import { searchParamsToState, TableFilter } from 'components/tables/TableFilter'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
|
|
||||||
export const makeRowRender = (): RenderRowType => {
|
export const makeRowRender = (): RenderRowType => {
|
||||||
const HttpServicesRenderRow = (row) => (
|
const HttpServicesRenderRow = (row) => (
|
||||||
@@ -98,9 +98,7 @@ export const HttpServices = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="HTTP Services" />
|
||||||
<title>HTTP Services - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<HttpServicesRender
|
<HttpServicesRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ import { searchParamsToState, TableFilter } from 'components/tables/TableFilter'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
import { parseMiddlewareType } from 'libs/parsers'
|
import { parseMiddlewareType } from 'libs/parsers'
|
||||||
|
|
||||||
export const makeRowRender = (): RenderRowType => {
|
export const makeRowRender = (): RenderRowType => {
|
||||||
@@ -99,9 +99,7 @@ export const TcpMiddlewares = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="TCP Middlewares" />
|
||||||
<title>TCP Middlewares - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<TcpMiddlewaresRender
|
<TcpMiddlewaresRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Box, Flex } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Box, Flex } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -17,6 +16,7 @@ import Tooltip from 'components/Tooltip'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
|
|
||||||
export const makeRowRender = (): RenderRowType => {
|
export const makeRowRender = (): RenderRowType => {
|
||||||
const TcpRoutersRenderRow = (row) => (
|
const TcpRoutersRenderRow = (row) => (
|
||||||
@@ -117,9 +117,7 @@ export const TcpRouters = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="TCP Routers" />
|
||||||
<title>TCP Routers - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<TcpRoutersRender
|
<TcpRoutersRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex, Text } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex, Text } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ import { searchParamsToState, TableFilter } from 'components/tables/TableFilter'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
|
|
||||||
export const makeRowRender = (): RenderRowType => {
|
export const makeRowRender = (): RenderRowType => {
|
||||||
const TcpServicesRenderRow = (row) => (
|
const TcpServicesRenderRow = (row) => (
|
||||||
@@ -98,9 +98,7 @@ export const TcpServices = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="TCP Services" />
|
||||||
<title>TCP Services - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<TcpServicesRender
|
<TcpServicesRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -15,6 +14,7 @@ import { searchParamsToState, TableFilter } from 'components/tables/TableFilter'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
|
|
||||||
export const makeRowRender = (): RenderRowType => {
|
export const makeRowRender = (): RenderRowType => {
|
||||||
const UdpRoutersRenderRow = (row) => (
|
const UdpRoutersRenderRow = (row) => (
|
||||||
@@ -101,9 +101,7 @@ export const UdpRouters = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="UDP Routers" />
|
||||||
<title>UDP Routers - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<UdpRoutersRender
|
<UdpRoutersRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex, Text } from '@traefiklabs/faency'
|
import { AriaTable, AriaTbody, AriaTd, AriaTfoot, AriaThead, AriaTr, Flex, Text } from '@traefiklabs/faency'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { Helmet } from 'react-helmet-async'
|
|
||||||
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
import useInfiniteScroll from 'react-infinite-scroll-hook'
|
||||||
import { useSearchParams } from 'react-router-dom'
|
import { useSearchParams } from 'react-router-dom'
|
||||||
|
|
||||||
@@ -14,6 +13,7 @@ import { searchParamsToState, TableFilter } from 'components/tables/TableFilter'
|
|||||||
import TooltipText from 'components/TooltipText'
|
import TooltipText from 'components/TooltipText'
|
||||||
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
import useFetchWithPagination, { pagesResponseInterface, RenderRowType } from 'hooks/use-fetch-with-pagination'
|
||||||
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
import { EmptyPlaceholderTd } from 'layout/EmptyPlaceholder'
|
||||||
|
import PageTitle from 'layout/PageTitle'
|
||||||
|
|
||||||
export const makeRowRender = (): RenderRowType => {
|
export const makeRowRender = (): RenderRowType => {
|
||||||
const UdpServicesRenderRow = (row) => (
|
const UdpServicesRenderRow = (row) => (
|
||||||
@@ -98,9 +98,7 @@ export const UdpServices = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
<PageTitle title="UDP Services" />
|
||||||
<title>UDP Services - Traefik Proxy</title>
|
|
||||||
</Helmet>
|
|
||||||
<TableFilter />
|
<TableFilter />
|
||||||
<UdpServicesRender
|
<UdpServicesRender
|
||||||
error={error}
|
error={error}
|
||||||
|
|||||||
Vendored
+1
@@ -4,5 +4,6 @@ namespace API {
|
|||||||
Version: string
|
Version: string
|
||||||
disableDashboardAd: boolean
|
disableDashboardAd: boolean
|
||||||
startDate: string
|
startDate: string
|
||||||
|
dashboardName?: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user