Skip to content

Commit 41db9f7

Browse files
committed
frontend: plugin settings: preserve save-button behavior
Pass data/onDataChange props to plugin settings components in both modes, while keeping explicit-save plugins unchanged.\n\nFor plugins registered without the save button, onDataChange now persists immediately through onSave.\n\nAdd tests covering both save-button and no-save-button flows.
1 parent 9a9b3f6 commit 41db9f7

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2025 The Kubernetes Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { ThemeProvider } from '@mui/material/styles';
18+
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
19+
import { PluginInfo, PluginSettingsDetailsProps } from '../../../plugin/pluginsSlice';
20+
import { TestContext } from '../../../test';
21+
import { theme } from '../../TestHelpers/theme';
22+
import { PluginSettingsDetailsPure } from './PluginSettingsDetails';
23+
24+
function TestSettingsComponent(props: PluginSettingsDetailsProps) {
25+
const { data, onDataChange } = props;
26+
27+
return (
28+
<>
29+
<span data-testid="current-value">{data?.value || ''}</span>
30+
<button onClick={() => onDataChange?.({ value: 'updated' })} type="button">
31+
Update Value
32+
</button>
33+
</>
34+
);
35+
}
36+
37+
function makePlugin(displaySaveButton: boolean): PluginInfo {
38+
return {
39+
name: 'test-plugin',
40+
description: 'Test plugin',
41+
homepage: 'https://example.com',
42+
settingsComponent: TestSettingsComponent,
43+
displaySettingsComponentWithSaveButton: displaySaveButton,
44+
};
45+
}
46+
47+
describe('PluginSettingsDetailsPure', () => {
48+
it('passes props and auto-saves changes when save button is disabled', async () => {
49+
const onSave = vi.fn();
50+
51+
render(
52+
<ThemeProvider theme={theme}>
53+
<TestContext>
54+
<PluginSettingsDetailsPure
55+
config={{ value: 'initial' }}
56+
plugin={makePlugin(false)}
57+
onSave={onSave}
58+
onDelete={vi.fn()}
59+
/>
60+
</TestContext>
61+
</ThemeProvider>
62+
);
63+
64+
expect(screen.getByTestId('current-value')).toHaveTextContent('initial');
65+
66+
fireEvent.click(screen.getByRole('button', { name: 'Update Value' }));
67+
68+
await waitFor(() => {
69+
expect(onSave).toHaveBeenCalledWith({ value: 'updated' });
70+
});
71+
});
72+
73+
it('passes props but does not auto-save changes when save button is enabled', () => {
74+
const onSave = vi.fn();
75+
76+
render(
77+
<ThemeProvider theme={theme}>
78+
<TestContext>
79+
<PluginSettingsDetailsPure
80+
config={{ value: 'initial' }}
81+
plugin={makePlugin(true)}
82+
onSave={onSave}
83+
onDelete={vi.fn()}
84+
/>
85+
</TestContext>
86+
</ThemeProvider>
87+
);
88+
89+
expect(screen.getByTestId('current-value')).toHaveTextContent('initial');
90+
91+
fireEvent.click(screen.getByRole('button', { name: 'Update Value' }));
92+
93+
expect(onSave).not.toHaveBeenCalled();
94+
});
95+
});

frontend/src/components/App/PluginSettings/PluginSettingsDetails.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ export function PluginSettingsDetailsPure(props: PluginSettingsDetailsPureProps)
194194

195195
function onDataChange(data: { [key: string]: any }) {
196196
setData(data);
197+
198+
if (!plugin.displaySettingsComponentWithSaveButton && onSave) {
199+
void onSave(data);
200+
}
197201
}
198202

199203
async function handleSave() {

0 commit comments

Comments
 (0)