Skip to content
Open
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
8 changes: 0 additions & 8 deletions dynamic-demo-plugin/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,6 @@ __metadata:
dependencies:
"@openshift/api-types": "npm:^1.0.0"
"@openshift/dynamic-plugin-sdk": "npm:^9.1.0"
immutable: "npm:^3.8.3"
lodash: "npm:^4.18.1"
reselect: "npm:^5.1.1"
typesafe-actions: "npm:^5.1.0"
Expand Down Expand Up @@ -2381,13 +2380,6 @@ __metadata:
languageName: node
linkType: hard

"immutable@npm:^3.8.3":
version: 3.8.3
resolution: "immutable@npm:3.8.3"
checksum: 10c0/bafa7b8371b7622bc3d128cd9e6bba3a654b968f09a237929629f43ac26f7e974a5879cd38baad0c26f6f0628753968611bf832add7bf0c44d647bf4306a2988
languageName: node
linkType: hard

"import-local@npm:^3.0.2":
version: 3.2.0
resolution: "import-local@npm:3.2.0"
Expand Down
1 change: 0 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@
"i18next-conv": "16.0.0",
"i18next-http-backend": "^4.0.1",
"i18next-v4-format-converter": "^1.1.2",
"immutable": "^3.8.3",
"istextorbinary": "^9.5.0",
"js-base64": "^3.9.2",
"js-yaml": "^3.15.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { Map as ImmutableMap } from 'immutable';
import * as _ from 'lodash';
import type { YAMLTemplate } from '@console/dynamic-plugin-sdk/src/extensions/yaml-templates';
import { isYAMLTemplate } from '@console/dynamic-plugin-sdk/src/extensions/yaml-templates';
Expand All @@ -8,20 +7,11 @@ import { referenceForExtensionModel } from '@console/internal/module/k8s';
import { useExtensions } from '@console/plugin-sdk/src/api/useExtensions';
import { renderHookWithProviders } from '@console/shared/src/test-utils/unit-test-utils';

type TemplateEntry = [GroupVersionKind, ImmutableMap<string, string>];
type TemplateEntry = [GroupVersionKind, Record<string, string>];

const entryToKeys = (entry: TemplateEntry) => {
const keys: string[] = [];

entry[1]
.keySeq()
.toArray()
.forEach((templateName) => {
keys.push(`${entry[0]}_${templateName}`); // e.g. 'apps~v1~ReplicaSet_default'
});

return keys;
};
// e.g. 'apps~v1~ReplicaSet_default'
const entryToKeys = (entry: TemplateEntry) =>
Object.keys(entry[1]).map((templateName) => `${entry[0]}_${templateName}`);

const extensionToKeys = (e: YAMLTemplate) => [
`${referenceForExtensionModel(e.properties.model)}_${e.properties.name || 'default'}`,
Expand All @@ -33,7 +23,7 @@ describe('YAMLTemplate', () => {
it('only one named template per model is allowed', async () => {
const { result } = await renderHookWithProviders(() => useExtensions(isYAMLTemplate));

const baseTemplateEntries = _.values(baseTemplates.entrySeq().toObject()) as TemplateEntry[];
const baseTemplateEntries = Object.entries(baseTemplates) as TemplateEntry[];
const baseTemplateKeys = _.flatMap(baseTemplateEntries.map(entryToKeys));
const pluginTemplateKeys = _.flatMap(
result.current.filter(isYAMLTemplate).map(extensionToKeys),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect } from 'react';
import { AlertVariant } from '@patternfly/react-core';
import type { Map as ImmutableMap } from 'immutable';
import { useTranslation } from 'react-i18next';
import {
getAdmissionWebhookWarnings,
Expand All @@ -15,9 +14,9 @@ import { useToast } from '@console/shared/src/components/toast/useToast';
import { useConsoleDispatch } from '@console/shared/src/hooks/useConsoleDispatch';
import { useConsoleSelector } from '@console/shared/src/hooks/useConsoleSelector';

type UseAdmissionWebhookWarnings = () => ImmutableMap<string, AdmissionWebhookWarning>;
type UseAdmissionWebhookWarnings = () => Record<string, AdmissionWebhookWarning>;
const useAdmissionWebhookWarnings: UseAdmissionWebhookWarnings = () =>
useConsoleSelector<ImmutableMap<string, AdmissionWebhookWarning>>(getAdmissionWebhookWarnings);
useConsoleSelector<Record<string, AdmissionWebhookWarning>>(getAdmissionWebhookWarnings);

export const AdmissionWebhookWarningNotifications = () => {
const { t } = useTranslation('console-app');
Expand All @@ -26,7 +25,7 @@ export const AdmissionWebhookWarningNotifications = () => {
const admissionWebhookWarnings = useAdmissionWebhookWarnings();
useEffect(() => {
const docURL = getDocumentationURL(documentationURLs.admissionWebhookWarning);
admissionWebhookWarnings.forEach((warning, id) => {
Object.entries(admissionWebhookWarnings).forEach(([id, warning]) => {
toastContext.addToast({
variant: AlertVariant.warning,
title: t('Admission Webhook Warning'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import { ConsolePluginCSPStatus } from './ConsolePluginStatus';

const ConsolePluginCSPStatusDetail: FC<DetailsItemComponentProps> = ({ obj }) => {
const pluginName = useMemo(() => obj?.metadata?.name, [obj?.metadata?.name]);
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) =>
UI.get('pluginCSPViolations'),
);
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) => UI.pluginCSPViolations);

return <ConsolePluginCSPStatus hasViolations={cspViolations[pluginName] ?? false} />;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -411,9 +411,7 @@ const ConsolePluginsTable: FC<ConsolePluginsTableProps> = ({

const DevPluginsPage: FC<ConsoleOperatorConfigPageProps> = (props) => {
const pluginInfo = usePluginInfo();
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) =>
UI.get('pluginCSPViolations'),
);
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) => UI.pluginCSPViolations);

const rows = useMemo<ConsolePluginTableRow[]>(
() =>
Expand All @@ -439,9 +437,7 @@ const useConsolePluginRows = (enabledPlugins: string[]) => {
isList: true,
kind: referenceForModel(ConsolePluginModel),
});
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) =>
UI.get('pluginCSPViolations'),
);
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) => UI.pluginCSPViolations);

const rows = useMemo<ConsolePluginTableRow[]>(() => {
if (!consolePluginsLoaded) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { screen } from '@testing-library/react';
import { Map as ImmutableMap } from 'immutable';
import { renderWithProviders } from '@console/shared/src/test-utils/unit-test-utils';
import ConsolePluginCSPStatusDetail from '../ConsolePluginCSPStatusDetail';

Expand All @@ -17,9 +16,9 @@ describe('ConsolePluginCSPStatusDetail', () => {
const renderWithCSPState = (pluginName: string, cspViolations: Record<string, boolean>) => {
renderWithProviders(<ConsolePluginCSPStatusDetail obj={createMockObj(pluginName)} />, {
initialState: {
UI: ImmutableMap({
UI: {
pluginCSPViolations: cspViolations,
}),
},
},
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ import NotLoadedDynamicPlugins from './NotLoadedDynamicPlugins';
const DynamicPluginsPopover: FC<DynamicPluginsPopoverProps> = ({ consolePlugins }) => {
const { t } = useTranslation('console-app');
const pluginInfoEntries = usePluginInfo();
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) =>
UI.get('pluginCSPViolations'),
);
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) => UI.pluginCSPViolations);
const notLoadedDynamicPluginInfo = pluginInfoEntries.filter(
(plugin) => plugin.status !== 'loaded',
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const useFeatureFlagController = () => {
// because handlers are called during render (they use hooks) but dispatches happen after.
useLayoutEffect(() => {
pendingUpdatesRef.current.forEach((enabled, flag) => {
if (flags.get(flag) !== enabled) {
if (flags[flag] !== enabled) {
dispatch(setFlag(flag, enabled));
}
});
Expand Down Expand Up @@ -80,7 +80,7 @@ const useModelFeatureFlagExtensions = () => {
const [resolvedExtensions] = useResolvedExtensions(isModelFeatureFlag);

const dispatch = useConsoleDispatch();
const models = useConsoleSelector(({ k8s }) => k8s.getIn(['RESOURCES', 'models']));
const models = useConsoleSelector(({ k8s }) => k8s.RESOURCES?.models);

// Use a ref to always access the current models value without changing the callback identity
const modelsRef = useRef(models);
Expand All @@ -92,7 +92,7 @@ const useModelFeatureFlagExtensions = () => {
(added, removed) => {
// The feature reducer can't access state from the k8s reducer, so get the
// models here and include them in the action payload.
dispatch(updateModelFlags(added, removed, modelsRef.current));
dispatch(updateModelFlags(added, removed, Object.values(modelsRef.current ?? {})));
},
[dispatch],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,7 @@ const NodeList: FC<NodeListProps> = ({
}) => {
const { t } = useTranslation('console-app');
const { columns, resetAllColumnWidths } = useNodesColumns(vmsEnabled, isOpenShift5);
const nodeMetrics = useConsoleSelector<NodeMetrics>(({ UI }) => UI.getIn(['metrics', 'node']));
const nodeMetrics = useConsoleSelector<NodeMetrics>(({ UI }) => UI.metrics?.node);
const columnManagementID = referenceForModel(NodeModel);
const statusExtensions = useNodeStatusExtensions();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,7 @@ export const useCSPViolationDetector = () => {
const toastContext = useToast();
const fireTelemetryEvent = useTelemetry();
const pluginStore = usePluginStore();
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) =>
UI.get('pluginCSPViolations'),
);
const cspViolations = useConsoleSelector<PluginCSPViolations>(({ UI }) => UI.pluginCSPViolations);
const dispatch = useConsoleDispatch();
const [, cacheEvent] = useLocalStorageCache<PluginCSPViolationEvent>(
LOCAL_STORAGE_CSP_VIOLATIONS_KEY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ For current development version of Console, use `4.x.0-prerelease.n` packages.
For older 1.x plugin SDK packages, refer to "OpenShift Console Versions vs SDK Versions" compatibility
table in [Console dynamic plugins README](./README.md).

## 5.1.0-prerelease.1 - TBD

- Removed `immutable` dependency from the redux store and from the package ([CONSOLE-5001], [#17024])

## 4.23.0-prerelease.6 - TBD

- Add an `onCancel` prop to `ResourceYAMLEditor` to allow overriding the default cancel behavior ([CONSOLE-5438], [#16941])
Expand Down Expand Up @@ -245,6 +249,7 @@ table in [Console dynamic plugins README](./README.md).
[CONSOLE-4951]: https://issues.redhat.com/browse/CONSOLE-4951
[CONSOLE-4954]: https://issues.redhat.com/browse/CONSOLE-4954
[CONSOLE-4990]: https://issues.redhat.com/browse/CONSOLE-4990
[CONSOLE-5001]: https://issues.redhat.com/browse/CONSOLE-5001
[CONSOLE-5039]: https://issues.redhat.com/browse/CONSOLE-5039
[CONSOLE-5050]: https://issues.redhat.com/browse/CONSOLE-5050
[CONSOLE-5063]: https://issues.redhat.com/browse/CONSOLE-5063
Expand Down Expand Up @@ -355,3 +360,4 @@ table in [Console dynamic plugins README](./README.md).
[#16750]: https://github.com/openshift/console/pull/16750
[#16762]: https://github.com/openshift/console/pull/16762
[#16941]: https://github.com/openshift/console/pull/16941
[#17024]: https://github.com/openshift/console/pull/17024
12 changes: 12 additions & 0 deletions frontend/packages/console-dynamic-plugin-sdk/release-notes/5.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# OpenShift Console 5.1 Release Notes

## Changes to the Redux store

> [!NOTE]
> Plugins must not access or read Console-owned Redux state directly. Console exposes the Redux store only so
> that plugins can create and manage their own section of the store.

The Console-owned slices of the Redux store (such as `core`, `features`, `dashboards`, `UI`, `observe`, and `k8s`)
no longer use [Immutable.js](https://immutable-js.com/). These state slices are plain JavaScript objects instead
of `Immutable.Map` and `Immutable.List` instances. Because these slices are plain JavaScript objects, Immutable.js
APIs such as `.get()` and `.getIn()` no longer work on them.
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,7 @@ export const getCorePackage: GetPackageDefinition = (
dependencies: {
...parseDeps(
rootPackage,
[
'@openshift/api-types',
'@openshift/dynamic-plugin-sdk',
'immutable',
'reselect',
'typesafe-actions',
],
['@openshift/api-types', '@openshift/dynamic-plugin-sdk', 'reselect', 'typesafe-actions'],
missingDepCallback,
),
...parseDepsAs(rootPackage, { 'lodash-es': 'lodash' }, missingDepCallback),
Expand Down Expand Up @@ -170,7 +164,7 @@ export const getInternalPackage: GetPackageDefinition = (
main: 'lib/lib-internal.js',
...commonManifestFields,
dependencies: {
...parseDeps(rootPackage, ['@openshift/dynamic-plugin-sdk', 'immutable'], missingDepCallback),
...parseDeps(rootPackage, ['@openshift/dynamic-plugin-sdk'], missingDepCallback),
},
},
filesToCopy: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { QuickStart } from '@patternfly/quickstarts';
import type { OverflowMenuProps } from '@patternfly/react-core';
import type { DataViewTh } from '@patternfly/react-data-view/dist/esm/DataViewTable/DataViewTable';
import type { SortByDirection } from '@patternfly/react-table';
import type { Map as ImmutableMap } from 'immutable';
import type {
HealthState,
K8sResourceCommon,
Expand Down Expand Up @@ -242,14 +241,14 @@ export enum ActionMenuVariant {
}

type Request<R> = {
active: boolean;
timeout: NodeJS.Timer;
inFlight: boolean;
data: R;
error: any;
active?: number;
timeout?: ReturnType<typeof setTimeout>;
inFlight?: boolean;
data?: R;
loadError?: any;
};

export type RequestMap<R> = ImmutableMap<string, Request<R>>;
export type RequestMap<R> = Record<string, Request<R>>;

export type Fetch = (url: string) => Promise<any>;
export type WatchURLProps = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import { Map as ImmutableMap } from 'immutable';
import type { AdmissionWebhookWarning, CoreState } from '../../../redux-types';
import type { CoreState } from '../../../redux-types';
import { setUser, beginImpersonate, endImpersonate } from '../../actions/core';
import { coreReducer } from '../core';
import reducerTest from './utils/reducerTest';

describe('Core Reducer', () => {
const state: CoreState = {
user: {},
admissionWebhookWarnings: ImmutableMap<string, AdmissionWebhookWarning>(),
admissionWebhookWarnings: {},
};
const mockAdmissionWebhookWarnings = ImmutableMap({});
const mockAdmissionWebhookWarnings = {};

it('set user', () => {
const mockUser = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Map as ImmutableMap } from 'immutable';
import type { AdmissionWebhookWarning, CoreState } from '../../redux-types';
import type { CoreState } from '../../redux-types';
import type { CoreAction } from '../actions/core';
import { ActionType } from '../actions/core';

Expand All @@ -16,7 +15,7 @@ export const coreReducer = (
state: CoreState = {
user: {},
userResource: null,
admissionWebhookWarnings: ImmutableMap<string, AdmissionWebhookWarning>(),
admissionWebhookWarnings: {},
},
action: CoreAction = undefined,
): CoreState => {
Expand Down Expand Up @@ -59,16 +58,18 @@ export const coreReducer = (
case ActionType.SetAdmissionWebhookWarning:
return {
...state,
admissionWebhookWarnings: state.admissionWebhookWarnings.set(
action.payload.id,
action.payload.warning,
),
admissionWebhookWarnings: {
...state.admissionWebhookWarnings,
[action.payload.id]: action.payload.warning,
},
};
case ActionType.RemoveAdmissionWebhookWarning:
case ActionType.RemoveAdmissionWebhookWarning: {
const { [action.payload.id]: _, ...remaining } = state.admissionWebhookWarnings;
return {
...state,
admissionWebhookWarnings: state.admissionWebhookWarnings.remove(action.payload.id),
admissionWebhookWarnings: remaining,
};
}
default:
return state;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { Map as ImmutableMap } from 'immutable';
import type { UserInfo, UserKind } from '../../../extensions';
import type { ImpersonateKind, SDKStoreState, AdmissionWebhookWarning } from '../../redux-types';

Expand All @@ -7,7 +6,7 @@ type GetUser = (state: SDKStoreState) => UserInfo;
type GetUserResource = (state: SDKStoreState) => UserKind;
type GetAdmissionWebhookWarnings = (
state: SDKStoreState,
) => ImmutableMap<string, AdmissionWebhookWarning>;
) => Record<string, AdmissionWebhookWarning>;

/**
* It provides impersonation details from the redux store.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import type { Map as ImmutableMap } from 'immutable';

export type FeatureState = ImmutableMap<string, boolean>;
export type FeatureState = Record<string, boolean>;

export type FeatureSubStore = {
FLAGS: FeatureState;
Expand Down
Loading