Skip to content

Commit e0fe939

Browse files
authored
Merge pull request #226 from docker/fix-secret-save
Fix secrets save
2 parents 2f6c2d2 + f78bc01 commit e0fe939

File tree

2 files changed

+76
-31
lines changed

2 files changed

+76
-31
lines changed

src/extension/ui/src/components/tile/ConfigEditor.tsx

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { v1 } from '@docker/extension-api-client-types';
22
import CheckOutlined from '@mui/icons-material/CheckOutlined';
33
import CloseOutlined from '@mui/icons-material/CloseOutlined';
44
import {
5+
ButtonGroup,
56
CircularProgress,
67
IconButton,
78
Stack,
@@ -49,9 +50,9 @@ const ConfigEditor = ({
4950
() =>
5051
configSchema
5152
? deepFlattenObject({
52-
...catalogItem.configTemplate,
53-
...existingConfigForItem,
54-
})
53+
...catalogItem.configTemplate,
54+
...existingConfigForItem,
55+
})
5556
: {},
5657
[catalogItem.configTemplate, existingConfigForItem, configSchema]
5758
);
@@ -88,7 +89,14 @@ const ConfigEditor = ({
8889
const isSaving = savingKeys.has(key);
8990

9091
return (
91-
<Stack key={key} direction="row" spacing={2}>
92+
<Stack
93+
key={key}
94+
direction="row"
95+
spacing={2}
96+
sx={{
97+
alignItems: 'center',
98+
}}
99+
>
92100
<TextField
93101
fullWidth
94102
size="small"
@@ -100,12 +108,13 @@ const ConfigEditor = ({
100108
disabled={isSaving}
101109
/>
102110
{edited && (
103-
<Stack direction="row" spacing={2}>
111+
<>
104112
{isSaving ? (
105113
<CircularProgress size={24} />
106114
) : (
107-
<Stack direction="row" spacing={2}>
115+
<Stack direction="row" spacing={1}>
108116
<IconButton
117+
size="small"
109118
onClick={() =>
110119
updateExistingConfig(
111120
catalogItem.name,
@@ -114,9 +123,13 @@ const ConfigEditor = ({
114123
}
115124
disabled={isSaving}
116125
>
117-
<CheckOutlined sx={{ color: 'success.main' }} />
126+
<CheckOutlined
127+
fontSize="small"
128+
sx={{ color: 'success.main' }}
129+
/>
118130
</IconButton>
119131
<IconButton
132+
size="small"
120133
onClick={() =>
121134
setLocalConfig({
122135
...localConfig,
@@ -125,11 +138,14 @@ const ConfigEditor = ({
125138
}
126139
disabled={isSaving}
127140
>
128-
<CloseOutlined sx={{ color: 'error.main' }} />
141+
<CloseOutlined
142+
fontSize="small"
143+
sx={{ color: 'error.main' }}
144+
/>
129145
</IconButton>
130146
</Stack>
131147
)}
132-
</Stack>
148+
</>
133149
)}
134150
</Stack>
135151
);

src/extension/ui/src/components/tile/Modal.tsx

Lines changed: 51 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { v1 } from '@docker/extension-api-client-types';
22
import CheckOutlined from '@mui/icons-material/CheckOutlined';
33
import Close from '@mui/icons-material/Close';
44
import CloseOutlined from '@mui/icons-material/CloseOutlined';
5-
import DeleteOutlined from '@mui/icons-material/DeleteOutlined';
5+
import EditOutlinedIcon from '@mui/icons-material/EditOutlined';
66
import Launch from '@mui/icons-material/Launch';
77
import {
88
Alert,
@@ -17,7 +17,6 @@ import {
1717
DialogTitle,
1818
IconButton,
1919
Link,
20-
OutlinedInput,
2120
Paper,
2221
Stack,
2322
Switch,
@@ -34,16 +33,20 @@ import {
3433
Typography,
3534
useTheme,
3635
} from '@mui/material';
37-
import { useEffect, useState } from 'react';
36+
import { useEffect, useRef, useState } from 'react';
3837

39-
import { ASSIGNED_SECRET_PLACEHOLDER, getUnsupportedSecretMessage, MCP_POLICY_NAME } from '../../Constants';
38+
import {
39+
ASSIGNED_SECRET_PLACEHOLDER,
40+
getUnsupportedSecretMessage,
41+
MCP_POLICY_NAME,
42+
} from '../../Constants';
43+
import { formatName } from '../../formatName';
4044
import { useCatalogOperations } from '../../queries/useCatalog';
4145
import { useConfig } from '../../queries/useConfig';
46+
import useDDInfo from '../../queries/useDDInfo';
4247
import { useSecrets } from '../../queries/useSecrets';
4348
import { CatalogItemRichened } from '../../types/catalog';
4449
import ConfigEditor from './ConfigEditor';
45-
import { formatName } from '../../formatName';
46-
import useDDInfo from '../../queries/useDDInfo';
4750

4851
interface TabPanelProps {
4952
children?: React.ReactNode;
@@ -86,6 +89,9 @@ const ConfigurationModal = ({
8689
const [localSecrets, setLocalSecrets] = useState<
8790
{ [key: string]: string | undefined } | undefined
8891
>(undefined);
92+
93+
const inputRefs = useRef<HTMLInputElement[]>([]);
94+
8995
const theme = useTheme();
9096

9197
const { isLoading: secretsLoading, mutate: mutateSecret } =
@@ -293,7 +299,13 @@ const ConfigurationModal = ({
293299
</TableCell>
294300
<TableCell>
295301
<Link
296-
onClick={() => client.host.openExternal(`${catalogItem.readme}#tool-${tool.name.replaceAll(' ', '-')}` || '')}
302+
onClick={() =>
303+
client.host.openExternal(
304+
`${
305+
catalogItem.readme
306+
}#tool-${tool.name.replaceAll(' ', '-')}` || ''
307+
)
308+
}
297309
href="#"
298310
target="_blank"
299311
>
@@ -317,7 +329,7 @@ const ConfigurationModal = ({
317329
minHeight: '180px',
318330
}}
319331
>
320-
<Stack direction="column" spacing={2} >
332+
<Stack direction="column" spacing={2}>
321333
<ConfigEditor catalogItem={catalogItem} client={client} />
322334
<Stack>
323335
<Typography variant="subtitle2">Secrets</Typography>
@@ -332,24 +344,30 @@ const ConfigurationModal = ({
332344
</Alert>
333345
)}
334346
{ddInfo?.hasSecretSupport &&
335-
catalogItem.secrets &&
336-
catalogItem.secrets?.length > 0 ? (
337-
catalogItem.secrets.map((secret) => {
347+
catalogItem.secrets &&
348+
catalogItem.secrets?.length > 0 ? (
349+
catalogItem.secrets.map((secret, index) => {
338350
const secretEdited =
339351
(secret.assigned &&
340352
localSecrets[secret.name] !==
341-
ASSIGNED_SECRET_PLACEHOLDER) ||
353+
ASSIGNED_SECRET_PLACEHOLDER) ||
342354
(!secret.assigned &&
343355
localSecrets[secret.name] !== '');
344356
return (
345357
<Stack
346358
key={secret.name}
347359
direction="row"
348360
spacing={2}
349-
alignItems="center"
361+
sx={{
362+
alignItems: 'center',
363+
}}
350364
>
351365
<TextField
352366
size="small"
367+
inputRef={(element) =>
368+
(inputRefs.current[index] = element)
369+
}
370+
disabled={secret.assigned}
353371
key={secret.name}
354372
label={secret.name}
355373
value={localSecrets[secret.name]}
@@ -365,21 +383,28 @@ const ConfigurationModal = ({
365383
{secret.assigned && !secretEdited && (
366384
<IconButton
367385
size="small"
368-
color="error"
369386
onClick={() => {
387+
setLocalSecrets({
388+
...localSecrets,
389+
[secret.name]: '',
390+
});
391+
// We need to enable the input to be able to focus on it
392+
inputRefs.current[index].disabled = false;
393+
inputRefs.current[index].focus();
370394
mutateSecret.mutateAsync({
371395
name: secret.name,
372396
value: undefined,
373397
policies: [MCP_POLICY_NAME],
374398
});
375399
}}
376400
>
377-
<DeleteOutlined />
401+
<EditOutlinedIcon fontSize="small" />
378402
</IconButton>
379403
)}
380404
{secretEdited && (
381-
<ButtonGroup>
405+
<Stack direction="row" spacing={1}>
382406
<IconButton
407+
size="small"
383408
onClick={async () => {
384409
await mutateSecret.mutateAsync({
385410
name: secret.name,
@@ -389,10 +414,12 @@ const ConfigurationModal = ({
389414
}}
390415
>
391416
<CheckOutlined
417+
fontSize="small"
392418
sx={{ color: 'success.main' }}
393419
/>
394420
</IconButton>
395421
<IconButton
422+
size="small"
396423
onClick={async () => {
397424
setLocalSecrets({
398425
...localSecrets,
@@ -402,9 +429,12 @@ const ConfigurationModal = ({
402429
});
403430
}}
404431
>
405-
<CloseOutlined sx={{ color: 'error.main' }} />
432+
<CloseOutlined
433+
fontSize="small"
434+
sx={{ color: 'error.main' }}
435+
/>
406436
</IconButton>
407-
</ButtonGroup>
437+
</Stack>
408438
)}
409439
</Stack>
410440
);
@@ -417,10 +447,9 @@ const ConfigurationModal = ({
417447
</Stack>
418448
</TabPanel>
419449
</>
420-
)
421-
}
422-
</DialogContent >
423-
</Dialog >
450+
)}
451+
</DialogContent>
452+
</Dialog>
424453
);
425454
};
426455

0 commit comments

Comments
 (0)