@kinvolk/headlamp-plugin
Version:
The needed infrastructure for building Headlamp plugins.
180 lines (179 loc) • 7.52 kB
JavaScript
/*
* Copyright 2025 The Kubernetes Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createAction, createListenerMiddleware, createSlice, } from '@reduxjs/toolkit';
import { useDispatch } from 'react-redux';
/**
* The types of default events that can be tracked.
*/
export var HeadlampEventType;
(function (HeadlampEventType) {
/** Events related to an error boundary. */
HeadlampEventType["ERROR_BOUNDARY"] = "headlamp.error-boundary";
/** Events related to deleting a resource. */
HeadlampEventType["DELETE_RESOURCE"] = "headlamp.delete-resource";
/** Events related to deleting multiple resources. */
HeadlampEventType["DELETE_RESOURCES"] = "headlamp.delete-resources";
/** Events related to creating a resource. */
HeadlampEventType["CREATE_RESOURCE"] = "headlamp.create-resource";
/** Events related to editing a resource. */
HeadlampEventType["EDIT_RESOURCE"] = "headlamp.edit-resource";
/** Events related to scaling a resource. */
HeadlampEventType["SCALE_RESOURCE"] = "headlamp.scale-resource";
/** Events related to restarting a resource. */
HeadlampEventType["RESTART_RESOURCE"] = "headlamp.restart-resource";
/** Events related to restarting multiple resources. */
HeadlampEventType["RESTART_RESOURCES"] = "headlamp.restart-resources";
/** Events related to viewing logs. */
HeadlampEventType["LOGS"] = "headlamp.logs";
/** Events related to opening a terminal. */
HeadlampEventType["TERMINAL"] = "headlamp.terminal";
/** Events related to attaching to a pod. */
HeadlampEventType["POD_ATTACH"] = "headlamp.pod-attach";
/** Events related to loading a plugin. */
HeadlampEventType["PLUGIN_LOADING_ERROR"] = "headlamp.plugin-loading-error";
/** Events related to loading all plugins. */
HeadlampEventType["PLUGINS_LOADED"] = "headlamp.plugins-loaded";
/** Events related to loading a resource in the details view. */
HeadlampEventType["DETAILS_VIEW"] = "headlamp.details-view";
/** Events related to loading a resource in the list view. */
HeadlampEventType["LIST_VIEW"] = "headlamp.list-view";
/** Events related to loading events for a resource. */
HeadlampEventType["OBJECT_EVENTS"] = "headlamp.object-events";
})(HeadlampEventType || (HeadlampEventType = {}));
/**
* The status of an event. This list may grow in the future to accommodate more statuses.
*/
export var EventStatus;
(function (EventStatus) {
/** The status of the event is unknown. */
EventStatus["UNKNOWN"] = "unknown";
/** The event has to do with opening a dialog/action. */
EventStatus["OPENED"] = "open";
/** The event has to do with closing a dialog/action. */
EventStatus["CLOSED"] = "closed";
/** The event has to do with confirming a dialog/action. */
EventStatus["CONFIRMED"] = "confirmed";
/** The event has to do with finishing a dialog/action. */
EventStatus["FINISHED"] = "finished";
})(EventStatus || (EventStatus = {}));
const initialState = {
trackerFuncs: [],
};
export const eventAction = createAction('headlamp/event');
export const listenerMiddleware = createListenerMiddleware();
listenerMiddleware.startListening({
actionCreator: eventAction,
effect: async (action, listernerApi) => {
const trackerFuncs = listernerApi.getState()?.eventCallbackReducer?.trackerFuncs;
for (const trackerFunc of trackerFuncs) {
try {
trackerFunc(action.payload);
}
catch (e) {
console.error(`Error running tracker func ${trackerFunc} with payload ${action.payload}: ${e}`);
}
}
},
});
export const headlampEventSlice = createSlice({
name: 'headlampEvents',
initialState,
reducers: {
addEventCallback(state, action) {
state.trackerFuncs.push(action.payload);
},
},
});
export const { addEventCallback } = headlampEventSlice.actions;
export default headlampEventSlice.reducer;
export function useEventCallback(eventType) {
const dispatch = useDispatch();
function dispatchDataEventFunc(eventType) {
return (data) => {
dispatch(eventAction({
type: eventType,
data,
}));
};
}
switch (eventType) {
case HeadlampEventType.ERROR_BOUNDARY:
return (error) => {
dispatch(eventAction({
type: HeadlampEventType.ERROR_BOUNDARY,
data: error,
}));
};
case HeadlampEventType.DELETE_RESOURCE:
return dispatchDataEventFunc(HeadlampEventType.DELETE_RESOURCE);
case HeadlampEventType.DELETE_RESOURCES:
return dispatchDataEventFunc(HeadlampEventType.DELETE_RESOURCES);
case HeadlampEventType.EDIT_RESOURCE:
return dispatchDataEventFunc(HeadlampEventType.EDIT_RESOURCE);
case HeadlampEventType.SCALE_RESOURCE:
return dispatchDataEventFunc(HeadlampEventType.SCALE_RESOURCE);
case HeadlampEventType.RESTART_RESOURCE:
return dispatchDataEventFunc(HeadlampEventType.RESTART_RESOURCE);
case HeadlampEventType.LOGS:
return dispatchDataEventFunc(HeadlampEventType.LOGS);
case HeadlampEventType.TERMINAL:
return dispatchDataEventFunc(HeadlampEventType.TERMINAL);
case HeadlampEventType.POD_ATTACH:
return dispatchDataEventFunc(HeadlampEventType.POD_ATTACH);
case HeadlampEventType.CREATE_RESOURCE:
return dispatchDataEventFunc(HeadlampEventType.CREATE_RESOURCE);
case HeadlampEventType.PLUGIN_LOADING_ERROR:
return (plugin) => {
dispatch(eventAction({
type: HeadlampEventType.PLUGIN_LOADING_ERROR,
data: plugin,
}));
};
case HeadlampEventType.PLUGINS_LOADED:
return (plugins) => {
dispatch(eventAction({
type: HeadlampEventType.PLUGINS_LOADED,
data: plugins,
}));
};
case HeadlampEventType.DETAILS_VIEW:
return dispatchDataEventFunc(HeadlampEventType.DETAILS_VIEW);
case HeadlampEventType.LIST_VIEW:
return dispatchDataEventFunc(HeadlampEventType.LIST_VIEW);
case HeadlampEventType.OBJECT_EVENTS:
return (events, resource) => {
dispatch(eventAction({
type: HeadlampEventType.OBJECT_EVENTS,
data: {
resource,
events,
},
}));
};
default:
break;
}
return (eventInfo) => {
let event;
if (typeof eventInfo === 'string') {
event = { type: eventInfo };
}
else {
event = eventInfo;
}
dispatch(eventAction(event));
};
}