Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - frontend: PluginSettings: Refactor local storage and plugin data #2671

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 67 additions & 1 deletion frontend/src/components/App/PluginSettings/PluginSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { MRT_Row } from 'material-react-table';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useDispatch } from 'react-redux';
import semver from 'semver';
import helpers from '../../../helpers';
import { useFilterFunc } from '../../../lib/util';
import { PluginInfo, reloadPage, setPluginSettings } from '../../../plugin/pluginsSlice';
Expand Down Expand Up @@ -285,9 +286,74 @@ export default function PluginSettings() {

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

const [plugins, setPlugins] = useState<PluginInfo[]>([]);

useEffect(() => {
// to do: this is reused code that needs to be refactored for this specific use, maybe in a different PR as a hook
async function get() {
const pluginPaths = (await fetch(`${helpers.getAppUrl()}plugins`).then(resp =>
resp.json()
)) as string[];
const packageInfosPromise = await Promise.all<PluginInfo>(
pluginPaths.map(path =>
fetch(`${helpers.getAppUrl()}${path}/package.json`).then(resp => {
if (!resp.ok) {
if (resp.status !== 404) {
return Promise.reject(resp);
}
{
console.warn(
'Missing package.json. ' +
`Please upgrade the plugin ${path}` +
' by running "headlamp-plugin extract" again.' +
' Please use headlamp-plugin >= 0.8.0'
);
return {
name: path.split('/').slice(-1)[0],
version: '0.0.0',
author: 'unknown',
description: '',
};
}
}
return resp.json();
})
)
);
const packageInfos = await packageInfosPromise;

const pluginsWithIsEnabled = packageInfos.map(plugin => {
const matchedSetting = pluginSettings.find(p => plugin.name === p.name);
if (matchedSetting) {
// to do: compatible version is also reused code that needs to be refactored for this use
const compatibleVersion = '>=0.8.0-alpha.3';

const isCompatible = semver.satisfies(
semver.coerce(plugin.devDependencies?.['@kinvolk/headlamp-plugin']) || '',
compatibleVersion
);

return {
...plugin,
isEnabled: matchedSetting.isEnabled,
isCompatible: isCompatible,
};
}
return plugin;
});

setPlugins(pluginsWithIsEnabled);
}
get();
}, []);

if (!plugins.length) {
return null;
}

return (
<PluginSettingsPure
plugins={pluginSettings}
plugins={plugins}
onSave={plugins => {
dispatch(setPluginSettings(plugins));
dispatch(reloadPage());
Expand Down
13 changes: 8 additions & 5 deletions frontend/src/plugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,17 +199,20 @@ export function filterSources(
*/
export function updateSettingsPackages(
backendPlugins: PluginInfo[],
settingsPlugins: PluginInfo[]
settingsPlugins: { name: string; isEnabled: boolean }[]
): PluginInfo[] {
if (backendPlugins.length === 0) return [];

const pluginsChanged =
backendPlugins.length !== settingsPlugins.length ||
backendPlugins.map(p => p.name + p.version).join('') !==
settingsPlugins.map(p => p.name + p.version).join('');
backendPlugins.map(p => p.name) !== settingsPlugins.map(p => p.name);

if (!pluginsChanged) {
return settingsPlugins;
const updatedPlugins = backendPlugins.filter(plugin =>
settingsPlugins.some(setting => setting.name === plugin.name)
);

return updatedPlugins;
}

return backendPlugins.map(plugin => {
Expand Down Expand Up @@ -241,7 +244,7 @@ export function updateSettingsPackages(
*
*/
export async function fetchAndExecutePlugins(
settingsPackages: PluginInfo[],
settingsPackages: { name: string; isEnabled: boolean }[],
onSettingsChange: (plugins: PluginInfo[]) => void,
onIncompatible: (plugins: Record<string, PluginInfo>) => void
) {
Expand Down
13 changes: 9 additions & 4 deletions frontend/src/plugin/pluginsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export interface PluginsState {
/** Have plugins finished executing? */
loaded: boolean;
/** Information stored by settings about plugins. */
pluginSettings: PluginInfo[];
pluginSettings: { name: string; isEnabled: boolean }[];
}
const initialState: PluginsState = {
/** Once the plugins have been fetched and executed. */
Expand All @@ -110,9 +110,14 @@ export const pluginsSlice = createSlice({
/**
* Save the plugin settings. To both the store, and localStorage.
*/
setPluginSettings(state, action: PayloadAction<PluginInfo[]>) {
state.pluginSettings = action.payload;
localStorage.setItem('headlampPluginSettings', JSON.stringify(action.payload));
setPluginSettings(state, action: PayloadAction<any[]>) {
const pluginInfo = action.payload.map(p => ({
name: p.name,
isEnabled: p.isEnabled,
}));
state.pluginSettings = pluginInfo;
console.log('LOCAL SAVE', pluginInfo);
localStorage.setItem('headlampPluginSettings', JSON.stringify(pluginInfo));
},
/** Reloads the browser page */
reloadPage() {
Expand Down
Loading