diff --git a/cockpit/webpack.config.ts b/cockpit/webpack.config.ts index 882690da9..d152b8e61 100644 --- a/cockpit/webpack.config.ts +++ b/cockpit/webpack.config.ts @@ -2,7 +2,6 @@ const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const webpack = require('webpack'); // Add this line - const [mode, devtool] = process.env.NODE_ENV === 'production' ? ['production', 'source-map'] @@ -31,7 +30,13 @@ module.exports = { resolve: { modules: ['node_modules'], extensions: ['.js', '.jsx', '.ts', '.tsx'], + alias: { + // Use different modules based on the environment + // For example, `api` will resolve to `cloudApi` or `imageBuilderApi` accordingly + api: path.resolve(__dirname, '../../src/store/cockpitApi.ts'), + }, }, + module: { rules: [ { diff --git a/create_symlink.sh b/create_symlink.sh deleted file mode 100755 index 6429fb066..000000000 --- a/create_symlink.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -TARGET_LINK_NAME=image-builder-frontend -LINK_SOURCE="$(pwd)/cockpit/public" - -# List of potential directories -DIRECTORIES=(~/.local/share/cockpit/ /usr/local/share/cockpit/ /usr/share/cockpit/) - -# Loop through the directories and create the link in the first one that exists -for DIR in "${DIRECTORIES[@]}"; do - if [ -d "$DIR" ]; then - ln -s "$LINK_SOURCE" "$DIR$TARGET_LINK_NAME" - echo "Symbolic link created at $DIR$TARGET_LINK_NAME" - exit 0 - fi -done - -echo "No suitable directory found for the symbolic link." diff --git a/package-lock.json b/package-lock.json index daf1c76fb..ad650b740 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,7 +68,7 @@ "history": "5.3.0", "identity-obj-proxy": "3.0.0", "jsdom": "25.0.0", - "mini-css-extract-plugin": "^2.9.1", + "mini-css-extract-plugin": "2.9.1", "moment": "2.30.1", "msw": "2.4.4", "npm-run-all": "4.1.5", diff --git a/package.json b/package.json index b3f816863..f5cf80c45 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "test:watch": "TZ=UTC vitest", "test:coverage": "TZ=UTC vitest run --coverage", "build": "fec build", - "cockpit:build": "webpack --config cockpit/webpack.config.ts && ./create_symlink.sh", + "devel-install": "webpack --config cockpit/webpack.config.ts && mkdir -p ~/.local/share/cockpit\n\tln -s `pwd`/cockpit/public ~/.local/share/cockpit/image-builder-frontend", "api": "npm-run-all api:pull api:generate", "api:generate": "bash api/codegen.sh", "api:pull": "bash api/pull.sh", diff --git a/src/AppCockpit.tsx b/src/AppCockpit.tsx index 50f66fd0e..733ff3263 100644 --- a/src/AppCockpit.tsx +++ b/src/AppCockpit.tsx @@ -6,7 +6,7 @@ import React from 'react'; import NotificationsPortal from '@redhat-cloud-services/frontend-components-notifications/NotificationPortal'; import { createRoot } from 'react-dom/client'; import { Provider } from 'react-redux'; -import { HashRouter } from 'react-router-dom'; +import { BrowserRouter } from 'react-router-dom'; import { Router } from './Router'; import { store } from './store'; @@ -15,9 +15,9 @@ const Application = () => { return ( - + - + ); }; diff --git a/src/store/cockpitApi.ts b/src/store/cockpitApi.ts index 7d062a89f..6bf955b27 100644 --- a/src/store/cockpitApi.ts +++ b/src/store/cockpitApi.ts @@ -1,40 +1,10 @@ import { emptyCockpitApi as api } from './emptyCockpitApi'; +import { + GetBlueprintsApiArg, + GetBlueprintsApiResponse, +} from './imageBuilderApi'; -export type ListResponseMeta = { - count: number; -}; -export type ListResponseLinks = { - first: string; - last: string; -}; -export type BlueprintItem = { - id: string; - version: number; - name: string; - description: string; - last_modified_at: string; -}; - -export type BlueprintsResponse = { - meta: ListResponseMeta; - links: ListResponseLinks; - data: BlueprintItem[]; -}; - -export type GetBlueprintsApiResponse = - /** status 200 a list of blueprints */ BlueprintsResponse; -export type GetBlueprintsApiArg = { - /** fetch blueprint with specific name */ - name?: string; - /** search for blueprints by name or description */ - search?: string; - /** max amount of blueprints, default 100 */ - limit?: number; - /** blueprint page offset, default 0 */ - offset?: number; -}; - -// initialize an empty api service that we'll inject endpoints into later as needed +// Injects API endpoints into the service for querying blueprints export const blueprintsReducer = api.injectEndpoints({ endpoints: (build) => ({ getBlueprints: build.query({ diff --git a/src/store/index.ts b/src/store/index.ts index 37a94f7e4..9140d7c21 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -19,7 +19,9 @@ import wizardSlice, { selectImageTypes, } from './wizardSlice'; -export const reducer = combineReducers({ +import { isOnPremise } from '../constants'; + +export const serviceReducer = combineReducers({ [contentSourcesApi.reducerPath]: contentSourcesApi.reducer, [edgeApi.reducerPath]: edgeApi.reducer, [imageBuilderApi.reducerPath]: imageBuilderApi.reducer, @@ -31,6 +33,14 @@ export const reducer = combineReducers({ blueprints: blueprintsSlice.reducer, }); +export const onPremReducer = combineReducers({ + [imageBuilderApi.reducerPath]: imageBuilderApi.reducer, + [blueprintsReducer.reducerPath]: blueprintsReducer.reducer, + notifications: notificationsReducer, + wizard: wizardSlice, + blueprints: blueprintsSlice.reducer, +}); + startAppListening({ actionCreator: changeArchitecture, effect: (action, listenerApi) => { @@ -88,7 +98,7 @@ startAppListening({ // Listener middleware must be prepended according to RTK docs: // https://redux-toolkit.js.org/api/createListenerMiddleware#basic-usage // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type -export const middleware = (getDefaultMiddleware: Function) => +export const serviceMiddleware = (getDefaultMiddleware: Function) => getDefaultMiddleware() .prepend(listenerMiddleware.middleware) .concat( @@ -100,7 +110,23 @@ export const middleware = (getDefaultMiddleware: Function) => blueprintsReducer.middleware ); -export const store = configureStore({ reducer, middleware }); +// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type +export const onPremMiddleware = (getDefaultMiddleware: Function) => + getDefaultMiddleware() + .prepend(listenerMiddleware.middleware) + .concat( + promiseMiddleware, + imageBuilderApi.middleware, + blueprintsReducer.middleware + ); + +const rootReducer = isOnPremise ? onPremReducer : serviceReducer; +const rootMiddleware = isOnPremise ? onPremMiddleware : serviceMiddleware; + +export const store = configureStore({ + reducer: rootReducer, + middleware: rootMiddleware, +}); // Infer the `RootState` and `AppDispatch` types from the store itself export type RootState = ReturnType;