UNPKG

@kinvolk/headlamp-plugin

Version:

The needed infrastructure for building Headlamp plugins.

180 lines (179 loc) 7.52 kB
/* * 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)); }; }