Skip to content

Commit fd2d35c

Browse files
authored
Merge pull request #1605 from farodin91/frontend--Add-ingressclass
frontend: Add IngressClass
2 parents a078567 + ec71960 commit fd2d35c

27 files changed

+1262
-18
lines changed

frontend/src/components/App/icons.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,9 @@ const mdiIcons = {
305305
'train-car-container': {
306306
body: '<path fill="currentColor" d="M1 6v11h1a2 2 0 1 0 4 0h12a2 2 0 1 0 4 0h1V6H1m20 9h-2V9h-2v6h-2V9h-2v6h-2V9H9v6H7V9H5v6H3V8h18v7Z"/>',
307307
},
308+
star: {
309+
body: '<path fill="currentColor" d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.62L12 2L9.19 8.62L2 9.24l5.45 4.73L5.82 21z"/>',
310+
},
308311
},
309312
aliases: {
310313
'more-vert': {

frontend/src/components/Sidebar/__snapshots__/Sidebar.stories.storyshot

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,29 @@ exports[`Storyshots Sidebar/Sidebar In Cluster Sidebar Closed 1`] = `
899899
/>
900900
</a>
901901
</li>
902+
<li
903+
class="makeStyles-link makeStyles-link"
904+
>
905+
<a
906+
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-padding MuiListItem-button css-sayhe9-MuiButtonBase-root-MuiListItem-root"
907+
href="/"
908+
role="button"
909+
tabindex="0"
910+
>
911+
<div
912+
class="MuiListItemText-root css-tlelie-MuiListItemText-root"
913+
>
914+
<span
915+
class="MuiTypography-root MuiTypography-body1 MuiListItemText-primary css-nqgwvn-MuiTypography-root"
916+
>
917+
Ingress Classes
918+
</span>
919+
</div>
920+
<span
921+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
922+
/>
923+
</a>
924+
</li>
902925
<li
903926
class="makeStyles-link makeStyles-link"
904927
>
@@ -2027,6 +2050,29 @@ exports[`Storyshots Sidebar/Sidebar In Cluster Sidebar Open 1`] = `
20272050
/>
20282051
</a>
20292052
</li>
2053+
<li
2054+
class="makeStyles-link makeStyles-link"
2055+
>
2056+
<a
2057+
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-padding MuiListItem-button css-sayhe9-MuiButtonBase-root-MuiListItem-root"
2058+
href="/"
2059+
role="button"
2060+
tabindex="0"
2061+
>
2062+
<div
2063+
class="MuiListItemText-root css-tlelie-MuiListItemText-root"
2064+
>
2065+
<span
2066+
class="MuiTypography-root MuiTypography-body1 MuiListItemText-primary css-nqgwvn-MuiTypography-root"
2067+
>
2068+
Ingress Classes
2069+
</span>
2070+
</div>
2071+
<span
2072+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
2073+
/>
2074+
</a>
2075+
</li>
20302076
<li
20312077
class="makeStyles-link makeStyles-link"
20322078
>
@@ -3176,6 +3222,29 @@ exports[`Storyshots Sidebar/Sidebar Selected Item With Sidebar Omitted 1`] = `
31763222
/>
31773223
</a>
31783224
</li>
3225+
<li
3226+
class="makeStyles-link makeStyles-link"
3227+
>
3228+
<a
3229+
class="MuiButtonBase-root MuiListItem-root MuiListItem-gutters MuiListItem-padding MuiListItem-button css-sayhe9-MuiButtonBase-root-MuiListItem-root"
3230+
href="/"
3231+
role="button"
3232+
tabindex="0"
3233+
>
3234+
<div
3235+
class="MuiListItemText-root css-tlelie-MuiListItemText-root"
3236+
>
3237+
<span
3238+
class="MuiTypography-root MuiTypography-body1 MuiListItemText-primary css-nqgwvn-MuiTypography-root"
3239+
>
3240+
Ingress Classes
3241+
</span>
3242+
</div>
3243+
<span
3244+
class="MuiTouchRipple-root css-8je8zh-MuiTouchRipple-root"
3245+
/>
3246+
</a>
3247+
</li>
31793248
<li
31803249
class="makeStyles-link makeStyles-link"
31813250
>

frontend/src/components/Sidebar/prepareRoutes.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,10 @@ function prepareRoutes(
146146
name: 'ingresses',
147147
label: t('glossary|Ingresses'),
148148
},
149+
{
150+
name: 'ingressclasses',
151+
label: t('glossary|Ingress Classes'),
152+
},
149153
{
150154
name: 'portforwards',
151155
label: t('glossary|Port Forwarding'),
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Meta, Story } from '@storybook/react/types-6-0';
2+
import IngressClass, { KubeIngressClass } from '../../lib/k8s/ingressClass';
3+
import { TestContext } from '../../test';
4+
import Details from './ClassDetails';
5+
import { RESOURCE_DEFAULT_INGRESS_CLASS, RESOURCE_INGRESS_CLASS } from './storyHelper';
6+
7+
export default {
8+
title: 'IngressClass/DetailsView',
9+
component: Details,
10+
argTypes: {},
11+
decorators: [
12+
Story => {
13+
return (
14+
<TestContext>
15+
<Story />
16+
</TestContext>
17+
);
18+
},
19+
],
20+
} as Meta;
21+
22+
interface MockerStory {
23+
ingressJson?: KubeIngressClass;
24+
}
25+
26+
const Template: Story = (args: MockerStory) => {
27+
const { ingressJson } = args;
28+
if (!!ingressJson) {
29+
IngressClass.useGet = () => [new IngressClass(ingressJson), null, () => {}, () => {}] as any;
30+
}
31+
return <Details />;
32+
};
33+
34+
export const Basic = Template.bind({});
35+
Basic.args = {
36+
ingressJson: RESOURCE_INGRESS_CLASS,
37+
};
38+
39+
export const WithDefault = Template.bind({});
40+
WithDefault.args = {
41+
ingressJson: RESOURCE_DEFAULT_INGRESS_CLASS,
42+
};
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { useTranslation } from 'react-i18next';
2+
import { useParams } from 'react-router-dom';
3+
import IngressClass from '../../lib/k8s/ingressClass';
4+
import { DetailsGrid } from '../common/Resource';
5+
6+
export default function IngressClassDetails() {
7+
const { name } = useParams<{ name: string }>();
8+
const { t } = useTranslation('glossary');
9+
10+
return (
11+
<DetailsGrid
12+
resourceType={IngressClass}
13+
name={name}
14+
withEvents
15+
extraInfo={item =>
16+
item && [
17+
{
18+
name: t('translation|Default'),
19+
value: item.isDefault ? t('translation|Yes') : t('translation|No'),
20+
},
21+
]
22+
}
23+
/>
24+
);
25+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Meta, Story } from '@storybook/react/types-6-0';
2+
import { KubeObject } from '../../lib/k8s/cluster';
3+
import IngressClass from '../../lib/k8s/ingressClass';
4+
import { TestContext } from '../../test';
5+
import ListView from './ClassList';
6+
import { RESOURCE_DEFAULT_INGRESS_CLASS, RESOURCE_INGRESS_CLASS } from './storyHelper';
7+
8+
IngressClass.useList = () => {
9+
const objList = [RESOURCE_INGRESS_CLASS, RESOURCE_DEFAULT_INGRESS_CLASS].map(
10+
(data: KubeObject) => new IngressClass(data)
11+
);
12+
13+
return [objList, null, () => {}, () => {}] as any;
14+
};
15+
16+
export default {
17+
title: 'IngressClass/ListView',
18+
component: ListView,
19+
argTypes: {},
20+
decorators: [
21+
Story => {
22+
return (
23+
<TestContext>
24+
<Story />
25+
</TestContext>
26+
);
27+
},
28+
],
29+
} as Meta;
30+
31+
const Template: Story = () => {
32+
return <ListView />;
33+
};
34+
35+
export const Items = Template.bind({});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { useTranslation } from 'react-i18next';
2+
import IngressClass from '../../lib/k8s/ingressClass';
3+
import { HoverInfoLabel } from '../common';
4+
import ResourceListView from '../common/Resource/ResourceListView';
5+
6+
export default function IngressClassList() {
7+
const { t } = useTranslation('glossary');
8+
9+
return (
10+
<ResourceListView
11+
title={t('Ingress Classes')}
12+
headerProps={{
13+
noNamespaceFilter: true,
14+
}}
15+
resourceClass={IngressClass}
16+
columns={[
17+
{
18+
id: 'default',
19+
label: '',
20+
gridTemplate: 0.1,
21+
getter: (resource: IngressClass) =>
22+
resource && resource.isDefault ? <DefaultLabel /> : null,
23+
sort: false,
24+
},
25+
'name',
26+
{
27+
id: 'controller',
28+
label: t('Controller'),
29+
getter: (ingressClass: IngressClass) => ingressClass.spec?.controller,
30+
sort: true,
31+
},
32+
'age',
33+
]}
34+
/>
35+
);
36+
}
37+
38+
export function DefaultLabel() {
39+
const { t } = useTranslation('glossary');
40+
return <HoverInfoLabel label="" hoverInfo={t('Default Ingress Class')} icon="mdi:star" />;
41+
}

frontend/src/components/ingress/Details.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { Box, Link, Typography } from '@mui/material';
1+
import { Box, Link as MuiLink, Typography } from '@mui/material';
22
import { useTranslation } from 'react-i18next';
33
import { useParams } from 'react-router-dom';
44
import Ingress, { IngressBackend, IngressRule } from '../../lib/k8s/ingress';
55
import { useSettings } from '../App/Settings/hook';
66
import LabelListItem from '../common/LabelListItem';
7+
import Link from '../common/Link';
78
import { DetailsGrid } from '../common/Resource';
89
import { SectionBox } from '../common/SectionBox';
910
import SimpleTable from '../common/SimpleTable';
@@ -94,18 +95,18 @@ export function LinkStringFormat({ url, item, urlPath }: LinkStringFormatProps)
9495
if (formatURL && urlPath) {
9596
return (
9697
<Box style={{ display: 'flex', marginBottom: '5px' }}>
97-
<Link
98+
<MuiLink
9899
href={`${formatURL.protocol}//${formatURL.hostname}${urlPath}`}
99100
style={{ marginRight: '5px' }}
100101
>
101102
{urlPath}
102-
</Link>
103+
</MuiLink>
103104
{`(${currentPathType})`}
104105
</Box>
105106
);
106107
}
107108

108-
return <Link href={formatURL.toString()}>{`${formatURL.toString()}`}</Link>;
109+
return <MuiLink href={formatURL.toString()}>{`${formatURL.toString()}`}</MuiLink>;
109110
}
110111
}
111112

@@ -213,6 +214,14 @@ export default function IngressDetails() {
213214
/>
214215
),
215216
},
217+
{
218+
name: t('Class Name'),
219+
value: ingress.spec?.ingressClassName ? (
220+
<Link routeName="ingressclass" params={{ name: ingress.spec?.ingressClassName }}>
221+
{ingress.spec?.ingressClassName}
222+
</Link>
223+
) : null,
224+
},
216225
]
217226
}
218227
extraSections={item => [

frontend/src/components/ingress/List.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import { useTranslation } from 'react-i18next';
33
import Ingress from '../../lib/k8s/ingress';
44
import LabelListItem from '../common/LabelListItem';
5+
import Link from '../common/Link';
56
import ResourceListView from '../common/Resource/ResourceListView';
67

78
function RulesDisplay(props: { ingress: Ingress }) {
@@ -45,7 +46,12 @@ export default function IngressList() {
4546
{
4647
id: 'class',
4748
label: t('Class Name'),
48-
getter: (ingress: Ingress) => ingress.spec?.ingressClassName,
49+
getter: (ingress: Ingress) =>
50+
ingress.spec?.ingressClassName ? (
51+
<Link routeName="ingressclass" params={{ name: ingress.spec?.ingressClassName }}>
52+
{ingress.spec?.ingressClassName}
53+
</Link>
54+
) : null,
4955
sort: true,
5056
},
5157
{

0 commit comments

Comments
 (0)