You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.9 KiB
100 lines
3.9 KiB
import { createSlice, createEntityAdapter, Reducer, AnyAction, PayloadAction } from '@reduxjs/toolkit';
|
|
import { fetchAll, fetchDetails, install, uninstall, loadPluginDashboards, panelPluginLoaded } from './actions';
|
|
import { CatalogPlugin, PluginListDisplayMode, ReducerState, RequestStatus } from '../types';
|
|
import { STATE_PREFIX } from '../constants';
|
|
import { PanelPlugin } from '@grafana/data';
|
|
|
|
export const pluginsAdapter = createEntityAdapter<CatalogPlugin>();
|
|
|
|
const isPendingRequest = (action: AnyAction) => new RegExp(`${STATE_PREFIX}\/(.*)\/pending`).test(action.type);
|
|
|
|
const isFulfilledRequest = (action: AnyAction) => new RegExp(`${STATE_PREFIX}\/(.*)\/fulfilled`).test(action.type);
|
|
|
|
const isRejectedRequest = (action: AnyAction) => new RegExp(`${STATE_PREFIX}\/(.*)\/rejected`).test(action.type);
|
|
|
|
// Extract the trailing '/pending', '/rejected', or '/fulfilled'
|
|
const getOriginalActionType = (type: string) => {
|
|
const separator = type.lastIndexOf('/');
|
|
|
|
return type.substring(0, separator);
|
|
};
|
|
|
|
const slice = createSlice({
|
|
name: 'plugins',
|
|
initialState: {
|
|
items: pluginsAdapter.getInitialState(),
|
|
requests: {},
|
|
settings: {
|
|
displayMode: PluginListDisplayMode.Grid,
|
|
},
|
|
// Backwards compatibility
|
|
// (we need to have the following fields in the store as well to be backwards compatible with other parts of Grafana)
|
|
// TODO<remove once the "plugin_admin_enabled" feature flag is removed>
|
|
plugins: [],
|
|
errors: [],
|
|
searchQuery: '',
|
|
hasFetched: false,
|
|
dashboards: [],
|
|
isLoadingPluginDashboards: false,
|
|
panels: {},
|
|
} as ReducerState,
|
|
reducers: {
|
|
setDisplayMode(state, action: PayloadAction<PluginListDisplayMode>) {
|
|
state.settings.displayMode = action.payload;
|
|
},
|
|
},
|
|
extraReducers: (builder) =>
|
|
builder
|
|
// Fetch All
|
|
.addCase(fetchAll.fulfilled, (state, action) => {
|
|
pluginsAdapter.upsertMany(state.items, action.payload);
|
|
})
|
|
// Fetch Details
|
|
.addCase(fetchDetails.fulfilled, (state, action) => {
|
|
pluginsAdapter.updateOne(state.items, action.payload);
|
|
})
|
|
// Install
|
|
.addCase(install.fulfilled, (state, action) => {
|
|
pluginsAdapter.updateOne(state.items, action.payload);
|
|
})
|
|
// Uninstall
|
|
.addCase(uninstall.fulfilled, (state, action) => {
|
|
pluginsAdapter.updateOne(state.items, action.payload);
|
|
})
|
|
// Load a panel plugin (backward-compatibility)
|
|
// TODO<remove once the "plugin_admin_enabled" feature flag is removed>
|
|
.addCase(panelPluginLoaded, (state, action: PayloadAction<PanelPlugin>) => {
|
|
state.panels[action.payload.meta.id] = action.payload;
|
|
})
|
|
// Start loading panel dashboards (backward-compatibility)
|
|
// TODO<remove once the "plugin_admin_enabled" feature flag is removed>
|
|
.addCase(loadPluginDashboards.pending, (state, action) => {
|
|
state.isLoadingPluginDashboards = true;
|
|
state.dashboards = [];
|
|
})
|
|
// Load panel dashboards (backward-compatibility)
|
|
// TODO<remove once the "plugin_admin_enabled" feature flag is removed>
|
|
.addCase(loadPluginDashboards.fulfilled, (state, action) => {
|
|
state.isLoadingPluginDashboards = false;
|
|
state.dashboards = action.payload;
|
|
})
|
|
.addMatcher(isPendingRequest, (state, action) => {
|
|
state.requests[getOriginalActionType(action.type)] = {
|
|
status: RequestStatus.Pending,
|
|
};
|
|
})
|
|
.addMatcher(isFulfilledRequest, (state, action) => {
|
|
state.requests[getOriginalActionType(action.type)] = {
|
|
status: RequestStatus.Fulfilled,
|
|
};
|
|
})
|
|
.addMatcher(isRejectedRequest, (state, action) => {
|
|
state.requests[getOriginalActionType(action.type)] = {
|
|
status: RequestStatus.Rejected,
|
|
error: action.payload,
|
|
};
|
|
}),
|
|
});
|
|
|
|
export const { setDisplayMode } = slice.actions;
|
|
export const reducer: Reducer<ReducerState, AnyAction> = slice.reducer;
|
|
|