Skip to content

Commit 98c1b58

Browse files
committed
frontend: PluginSettings: Rework local storage settings for plugins
Signed-off-by: Vincent T <vtaylor@microsoft.com>
1 parent de854a6 commit 98c1b58

File tree

3 files changed

+84
-10
lines changed

3 files changed

+84
-10
lines changed

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

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { MRT_Row } from 'material-react-table';
66
import { useEffect, useState } from 'react';
77
import { useTranslation } from 'react-i18next';
88
import { useDispatch } from 'react-redux';
9+
import semver from 'semver';
910
import helpers from '../../../helpers';
1011
import { useFilterFunc } from '../../../lib/util';
1112
import { PluginInfo, reloadPage, setPluginSettings } from '../../../plugin/pluginsSlice';
@@ -285,9 +286,74 @@ export default function PluginSettings() {
285286

286287
const pluginSettings = useTypedSelector(state => state.plugins.pluginSettings);
287288

289+
const [plugins, setPlugins] = useState<PluginInfo[]>([]);
290+
291+
useEffect(() => {
292+
// to do: this is reused code that needs to be refactored for this specific use, maybe in a different PR as a hook
293+
async function get() {
294+
const pluginPaths = (await fetch(`${helpers.getAppUrl()}plugins`).then(resp =>
295+
resp.json()
296+
)) as string[];
297+
const packageInfosPromise = await Promise.all<PluginInfo>(
298+
pluginPaths.map(path =>
299+
fetch(`${helpers.getAppUrl()}${path}/package.json`).then(resp => {
300+
if (!resp.ok) {
301+
if (resp.status !== 404) {
302+
return Promise.reject(resp);
303+
}
304+
{
305+
console.warn(
306+
'Missing package.json. ' +
307+
`Please upgrade the plugin ${path}` +
308+
' by running "headlamp-plugin extract" again.' +
309+
' Please use headlamp-plugin >= 0.8.0'
310+
);
311+
return {
312+
name: path.split('/').slice(-1)[0],
313+
version: '0.0.0',
314+
author: 'unknown',
315+
description: '',
316+
};
317+
}
318+
}
319+
return resp.json();
320+
})
321+
)
322+
);
323+
const packageInfos = await packageInfosPromise;
324+
325+
const pluginsWithIsEnabled = packageInfos.map(plugin => {
326+
const matchedSetting = pluginSettings.find(p => plugin.name === p.name);
327+
if (matchedSetting) {
328+
// to do: compatible version is also reused code that needs to be refactored for this use
329+
const compatibleVersion = '>=0.8.0-alpha.3';
330+
331+
const isCompatible = semver.satisfies(
332+
semver.coerce(plugin.devDependencies?.['@kinvolk/headlamp-plugin']) || '',
333+
compatibleVersion
334+
);
335+
336+
return {
337+
...plugin,
338+
isEnabled: matchedSetting.isEnabled,
339+
isCompatible: isCompatible,
340+
};
341+
}
342+
return plugin;
343+
});
344+
345+
setPlugins(pluginsWithIsEnabled);
346+
}
347+
get();
348+
}, []);
349+
350+
if (!plugins.length) {
351+
return null;
352+
}
353+
288354
return (
289355
<PluginSettingsPure
290-
plugins={pluginSettings}
356+
plugins={plugins}
291357
onSave={plugins => {
292358
dispatch(setPluginSettings(plugins));
293359
dispatch(reloadPage());

frontend/src/plugin/index.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -199,17 +199,20 @@ export function filterSources(
199199
*/
200200
export function updateSettingsPackages(
201201
backendPlugins: PluginInfo[],
202-
settingsPlugins: PluginInfo[]
202+
settingsPlugins: { name: string; isEnabled: boolean }[]
203203
): PluginInfo[] {
204204
if (backendPlugins.length === 0) return [];
205205

206206
const pluginsChanged =
207207
backendPlugins.length !== settingsPlugins.length ||
208-
backendPlugins.map(p => p.name + p.version).join('') !==
209-
settingsPlugins.map(p => p.name + p.version).join('');
208+
backendPlugins.map(p => p.name) !== settingsPlugins.map(p => p.name);
210209

211210
if (!pluginsChanged) {
212-
return settingsPlugins;
211+
const updatedPlugins = backendPlugins.filter(plugin =>
212+
settingsPlugins.some(setting => setting.name === plugin.name)
213+
);
214+
215+
return updatedPlugins;
213216
}
214217

215218
return backendPlugins.map(plugin => {
@@ -241,7 +244,7 @@ export function updateSettingsPackages(
241244
*
242245
*/
243246
export async function fetchAndExecutePlugins(
244-
settingsPackages: PluginInfo[],
247+
settingsPackages: { name: string; isEnabled: boolean }[],
245248
onSettingsChange: (plugins: PluginInfo[]) => void,
246249
onIncompatible: (plugins: Record<string, PluginInfo>) => void
247250
) {

frontend/src/plugin/pluginsSlice.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export interface PluginsState {
9191
/** Have plugins finished executing? */
9292
loaded: boolean;
9393
/** Information stored by settings about plugins. */
94-
pluginSettings: PluginInfo[];
94+
pluginSettings: { name: string; isEnabled: boolean }[];
9595
}
9696
const initialState: PluginsState = {
9797
/** Once the plugins have been fetched and executed. */
@@ -110,9 +110,14 @@ export const pluginsSlice = createSlice({
110110
/**
111111
* Save the plugin settings. To both the store, and localStorage.
112112
*/
113-
setPluginSettings(state, action: PayloadAction<PluginInfo[]>) {
114-
state.pluginSettings = action.payload;
115-
localStorage.setItem('headlampPluginSettings', JSON.stringify(action.payload));
113+
setPluginSettings(state, action: PayloadAction<any[]>) {
114+
const pluginInfo = action.payload.map(p => ({
115+
name: p.name,
116+
isEnabled: p.isEnabled,
117+
}));
118+
state.pluginSettings = pluginInfo;
119+
console.log('LOCAL SAVE', pluginInfo);
120+
localStorage.setItem('headlampPluginSettings', JSON.stringify(pluginInfo));
116121
},
117122
/** Reloads the browser page */
118123
reloadPage() {

0 commit comments

Comments
 (0)