Skip to content

Commit 6c007d8

Browse files
authored
feat: Add issuerURL and cliendID to context chooser (kyma-project#4069)
* feat: Add issuerURL and cliendID to context chooser * add users to the edit cluster * code organization * remove unnecesary scss * fix translations * UX review * fix onchange * fix no args * fix no args * fix * fix
1 parent e09912c commit 6c007d8

File tree

6 files changed

+117
-63
lines changed

6 files changed

+117
-63
lines changed

public/i18n/en.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ clusters:
109109
list:
110110
no-clusters-found: No clusters found
111111
messages:
112-
choose-cluster: Choose cluster
112+
choose-cluster: Choose Context
113113
wrong-configuration: Cannot apply the configuration
114114
connection-failed: Error connecting to cluster. Check your configuration and make sure the cluster is online.
115115
name_singular: Cluster
@@ -159,8 +159,6 @@ clusters:
159159
incomplete: We couldn't find enough authentication information for {{context}} in your kubeconfig. You can enter it manually.
160160
intro: To connect a cluster, you have to provide the cluster configuration – called “kubeconfig” in the Kubernetes world.
161161
kubeconfig: Provide Kubeconfig
162-
several-context-info: You have more than one cluster in your SAP BTP account.
163-
several-context-question: Which one do you want to open?
164162
not-an-object: kubeconfig is not an object
165163
storage: Privacy
166164
token-info: If you don't know how to get your token, ask your authentication provider.

src/components/App/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ export default function App() {
115115
kubeconfigIdState === 'loading' &&
116116
createPortal(
117117
<ContextChooserMessage
118-
contexts={contextsState?.contexts}
118+
contextState={contextsState}
119119
setValue={(value: string) =>
120120
setContextsState(state => ({
121121
...state,

src/components/Clusters/components/ContextChooser/ContextChooser.js

Lines changed: 93 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ import { useTranslation } from 'react-i18next';
33
import {
44
Title,
55
RadioButton,
6-
FlexBox,
76
MessageBox,
87
Button,
98
Text,
9+
Label,
10+
List,
11+
ListItemCustom,
1012
} from '@ui5/webcomponents-react';
1113
import { ResourceForm } from 'shared/ResourceForm';
14+
import { getUserDetail } from './helpers';
15+
1216
import './ContextChooser.scss';
1317

1418
export function ContextChooser(params) {
@@ -34,6 +38,7 @@ export function ContextChooser(params) {
3438
input={({ setValue }) => (
3539
<ContextButtons
3640
contexts={kubeconfig.contexts}
41+
users={kubeconfig?.users}
3742
setValue={setValue}
3843
chosenContext={params.chosenContext}
3944
setChosenContext={params.setChosenContext}
@@ -45,40 +50,53 @@ export function ContextChooser(params) {
4550
);
4651
}
4752
export function ContextButtons({
53+
users,
4854
contexts,
4955
setValue,
5056
chosenContext,
5157
setChosenContext,
5258
}) {
5359
return (
54-
<FlexBox
55-
direction="Column"
56-
id="context-chooser"
57-
className="sap-margin-top-tiny"
60+
<List
61+
onItemClick={e => {
62+
setValue(e?.detail?.item?.children[0]?.children[0].value);
63+
if (setChosenContext)
64+
setChosenContext(e?.detail?.item?.children[0]?.children[0].value);
65+
}}
5866
>
59-
{contexts.map(context => (
60-
<RadioButton
61-
key={context.name}
62-
name={context.name}
63-
value={context.name}
64-
checked={chosenContext === context.name}
65-
text={context.name}
66-
onChange={() => {
67-
setValue(context.name);
68-
if (setChosenContext) setChosenContext(context.name);
69-
}}
70-
/>
71-
))}
72-
</FlexBox>
67+
{contexts.map(context => {
68+
return (
69+
<ListItemCustom key={context.name} style={{}}>
70+
<div>
71+
<RadioButton
72+
key={context.name}
73+
name={context.name}
74+
value={context.name}
75+
checked={chosenContext === context.name}
76+
text={context.name}
77+
onChange={() => {
78+
setValue(context.name);
79+
if (setChosenContext) setChosenContext(context.name);
80+
}}
81+
/>
82+
{users && (
83+
<AuthContextData contextName={context.name} users={users} />
84+
)}
85+
</div>
86+
</ListItemCustom>
87+
);
88+
})}
89+
</List>
7390
);
7491
}
75-
export function ContextChooserMessage({ contexts, setValue, onCancel }) {
92+
export function ContextChooserMessage({ contextState, setValue, onCancel }) {
7693
const { t } = useTranslation();
7794
const [chosenContext, setChosenContext] = useState('');
7895

79-
if (!Array.isArray(contexts)) {
96+
if (!Array.isArray(contextState?.contexts)) {
8097
return null;
8198
}
99+
82100
return (
83101
<MessageBox
84102
titleText={t('clusters.messages.choose-cluster')}
@@ -98,26 +116,60 @@ export function ContextChooserMessage({ contexts, setValue, onCancel }) {
98116
</Button>,
99117
]}
100118
>
101-
<FlexBox direction="Column" gap={16}>
102-
<Text className="context-chooser-content-text">
103-
{t('clusters.wizard.several-context-info')}
104-
<br />
105-
{t('clusters.wizard.several-context-question')}
106-
</Text>
107-
<FlexBox direction="Column" className="radio-box-container">
108-
{contexts.map(context => (
109-
<RadioButton
110-
id={'context-chooser' + context.name}
111-
key={context.name}
112-
name={context.name}
113-
value={context.name}
114-
checked={chosenContext === context.name}
115-
text={context.name}
116-
onChange={() => setChosenContext(context.name)}
117-
/>
118-
))}
119-
</FlexBox>
120-
</FlexBox>
119+
<List
120+
onItemClick={e => {
121+
setChosenContext(e?.detail?.item?.children[0]?.children[0].value);
122+
}}
123+
>
124+
{contextState.contexts.map(context => (
125+
<ListItemCustom key={context.name} style={{}}>
126+
<div>
127+
<RadioButton
128+
id={'context-chooser' + context.name}
129+
key={context.name}
130+
name={context.name}
131+
value={context.name}
132+
checked={chosenContext === context.name}
133+
text={context.name}
134+
onChange={() => setChosenContext(context.name)}
135+
/>
136+
{contextState?.users && (
137+
<AuthContextData
138+
contextName={context.name}
139+
users={contextState.users}
140+
/>
141+
)}
142+
</div>
143+
</ListItemCustom>
144+
))}
145+
</List>
121146
</MessageBox>
122147
);
123148
}
149+
150+
function AuthContextData({ contextName, users }) {
151+
const { t } = useTranslation();
152+
153+
const issuerUrl = getUserDetail(contextName, '--oidc-issuer-url=', users);
154+
const clientId = getUserDetail(contextName, '--oidc-client-id=', users);
155+
156+
if (issuerUrl === null && clientId === null) return null;
157+
158+
return (
159+
<div className="sap-margin-begin-medium sap-margin-bottom-small">
160+
<Label for="issuer-url" showColon className="sap-margin-bottom-tiny">
161+
{t('clusters.wizard.auth.issuer-url')}
162+
</Label>
163+
<Text id="issuer-url">{issuerUrl}</Text>
164+
165+
<Label
166+
for="client-id"
167+
showColon
168+
className="sap-margin-top-tiny sap-margin-bottom-tiny"
169+
>
170+
{t('clusters.wizard.auth.client-id')}
171+
</Label>
172+
<Text id="client-id">{clientId}</Text>
173+
</div>
174+
);
175+
}
Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
1-
.context-chooser {
2-
display: flex;
3-
justify-content: space-between;
4-
5-
label {
6-
align-self: center;
7-
}
8-
}
9-
101
ui5-dialog.context-chooser-message {
112
width: 478px;
123

134
ui5-icon {
145
display: none;
156
}
7+
}
168

17-
.context-chooser-content-text {
18-
padding-left: 7.5px;
19-
}
20-
21-
.radio-box-container {
22-
* {
23-
margin: -4px 0;
24-
}
25-
}
9+
ui5-dialog.context-chooser-message::part(content) {
10+
padding: 0 !important;
2611
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { EMPTY_TEXT_PLACEHOLDER } from 'shared/constants';
2+
3+
export function getUserDetail(
4+
contextName: string,
5+
parameter: string,
6+
users?: Array<{ name: string; user: { exec: { args?: string[] } } }>,
7+
) {
8+
const user = (users || []).find(user => user.name === contextName);
9+
10+
if (user?.user?.exec?.args === undefined) return null;
11+
12+
const clientIDArg = (user.user.exec.args || []).find(arg =>
13+
arg.startsWith(parameter),
14+
);
15+
return clientIDArg
16+
? clientIDArg.replace(parameter, '')
17+
: EMPTY_TEXT_PLACEHOLDER;
18+
}

src/components/Clusters/views/EditCluster/EditCluster.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ export const ClusterDataForm = ({
208208
}}
209209
input={({ setValue }) => (
210210
<ContextButtons
211+
users={kubeconfig?.users || []}
211212
contexts={kubeconfig?.contexts || []}
212213
setValue={setValue}
213214
chosenContext={chosenContext}

0 commit comments

Comments
 (0)