Skip to content

Commit 935611e

Browse files
committed
Refactor public/ Directory Components to useK8sWatchResource(s)
1 parent 759d8cc commit 935611e

20 files changed

Lines changed: 594 additions & 441 deletions

frontend/packages/console-app/src/actions/hooks/useBindingActions.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ export const useBindingActions = (
4545
const navigate = useNavigate();
4646
const [commonActions] = useCommonActions(model, obj, [CommonActionCreator.Delete] as const);
4747

48-
const { subjectIndex, subjects = [] } = obj;
48+
const { subjectIndex, subjects } = obj ?? {};
4949
const subject = subjects?.[subjectIndex];
5050
const deleteBindingSubject = useWarningModal({
5151
title: t('public~Delete {{label}} subject?', {
52-
label: model.kind,
52+
label: model?.kind,
5353
}),
5454
children: t('public~Are you sure you want to delete subject {{name}} of type {{kind}}?', {
5555
name: subject?.name,
@@ -146,9 +146,9 @@ export const useBindingActions = (
146146
: []),
147147
factory.DuplicateBinding(),
148148
factory.EditBindingSubject(),
149-
...(subjects.length === 1 ? [commonActions.Delete] : [factory.DeleteBindingSubject()]),
149+
...(subjects?.length === 1 ? [commonActions.Delete] : [factory.DeleteBindingSubject()]),
150150
];
151-
}, [memoizedFilterActions, subject?.kind, factory, subjects.length, commonActions.Delete]);
151+
}, [memoizedFilterActions, subject?.kind, factory, subjects?.length, commonActions.Delete]);
152152

153153
return actions;
154154
};

frontend/packages/console-app/src/components/nodes/NodeTerminal.tsx

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import type { ReactNode, FC } from 'react';
22
import { useState, useEffect } from 'react';
33
import { Alert } from '@patternfly/react-core';
44
import { useTranslation, Trans } from 'react-i18next';
5+
import { WatchK8sResource } from '@console/dynamic-plugin-sdk/src/extensions/console-types';
6+
import { useK8sWatchResource } from '@console/dynamic-plugin-sdk/src/utils/k8s/hooks/useK8sWatchResource';
57
import { PodConnectLoader } from '@console/internal/components/pod';
6-
import { Firehose } from '@console/internal/components/utils/firehose';
78
import { LoadingBox } from '@console/internal/components/utils/status-box';
8-
import type { FirehoseResource, FirehoseResult } from '@console/internal/components/utils/types';
99
import { ImageStreamTagModel, NamespaceModel, PodModel } from '@console/internal/models';
1010
import { NodeKind, PodKind, k8sCreate, k8sGet, k8sKillByName } from '@console/internal/module/k8s';
1111
import PaneBody from '@console/shared/src/components/layout/PaneBody';
@@ -15,7 +15,9 @@ type NodeTerminalErrorProps = {
1515
};
1616

1717
type NodeTerminalInnerProps = {
18-
obj?: FirehoseResult<PodKind>;
18+
pod: PodKind | undefined;
19+
loaded: boolean;
20+
loadError: any;
1921
};
2022

2123
type NodeTerminalProps = {
@@ -124,7 +126,7 @@ const NodeTerminalError: FC<NodeTerminalErrorProps> = ({ error }) => {
124126
);
125127
};
126128

127-
const NodeTerminalInner: FC<NodeTerminalInnerProps> = ({ obj }) => {
129+
const NodeTerminalInner: FC<NodeTerminalInnerProps> = ({ pod, loaded, loadError }) => {
128130
const { t } = useTranslation();
129131
const message = (
130132
<Trans t={t} ns="console-app">
@@ -133,32 +135,44 @@ const NodeTerminalInner: FC<NodeTerminalInnerProps> = ({ obj }) => {
133135
</p>
134136
</Trans>
135137
);
136-
switch (obj?.data?.status?.phase) {
138+
139+
if (loadError) {
140+
return <NodeTerminalError error={loadError.message || t('console-app~Failed to load pod')} />;
141+
}
142+
143+
if (!loaded || !pod) {
144+
return <LoadingBox />;
145+
}
146+
147+
switch (pod.status?.phase) {
137148
case 'Failed':
138149
return (
139150
<NodeTerminalError
140151
error={
141152
<>
142153
{t('console-app~The debug pod failed. ')}
143-
{obj?.data?.status?.containerStatuses?.[0]?.state?.terminated?.message ||
144-
obj?.data?.status?.message}
154+
{pod.status?.containerStatuses?.[0]?.state?.terminated?.message ||
155+
pod.status?.message}
145156
</>
146157
}
147158
/>
148159
);
149160
case 'Running':
150-
return <PodConnectLoader obj={obj.data} message={message} attach />;
161+
return <PodConnectLoader obj={pod} message={message} attach />;
151162
default:
152163
return <LoadingBox />;
153164
}
154165
};
155166

156167
const NodeTerminal: FC<NodeTerminalProps> = ({ obj: node }) => {
157-
const [resources, setResources] = useState<FirehoseResource[]>([]);
168+
const [isCreatingPod, setIsCreatingPod] = useState(true);
169+
const [podWatchResource, setPodWatchResource] = useState<WatchK8sResource | null>(null);
158170
const [errorMessage, setErrorMessage] = useState('');
159171
const nodeName = node.metadata.name;
160172
const isWindows = node.status?.nodeInfo?.operatingSystem === 'windows';
161173

174+
const [pod, loaded, loadError] = useK8sWatchResource<PodKind>(podWatchResource);
175+
162176
useEffect(() => {
163177
let namespace;
164178
const name = `${nodeName?.replace(/\./g, '-')}-debug`;
@@ -196,18 +210,17 @@ const NodeTerminal: FC<NodeTerminalProps> = ({ obj: node }) => {
196210
await new Promise((resolve) => setTimeout(resolve, 1000));
197211
const debugPod = await k8sCreate(PodModel, podToCreate);
198212
if (debugPod) {
199-
setResources([
200-
{
201-
isList: false,
202-
kind: 'Pod',
203-
name,
204-
namespace: namespace.metadata.name,
205-
prop: 'obj',
206-
},
207-
]);
213+
setPodWatchResource({
214+
kind: 'Pod',
215+
name,
216+
namespace: namespace.metadata.name,
217+
isList: false,
218+
});
219+
setIsCreatingPod(false);
208220
}
209221
} catch (e) {
210222
setErrorMessage(e.message);
223+
setIsCreatingPod(false);
211224
if (namespace) {
212225
deleteNamespace(namespace.metadata.name);
213226
}
@@ -221,13 +234,15 @@ const NodeTerminal: FC<NodeTerminalProps> = ({ obj: node }) => {
221234
};
222235
}, [nodeName, isWindows]);
223236

224-
return errorMessage ? (
225-
<NodeTerminalError error={errorMessage} />
226-
) : (
227-
<Firehose resources={resources}>
228-
<NodeTerminalInner />
229-
</Firehose>
230-
);
237+
if (errorMessage) {
238+
return <NodeTerminalError error={errorMessage} />;
239+
}
240+
241+
if (isCreatingPod) {
242+
return <LoadingBox />;
243+
}
244+
245+
return <NodeTerminalInner pod={pod} loaded={loaded} loadError={loadError} />;
231246
};
232247

233248
export default NodeTerminal;

frontend/public/components/RBAC/bindings.tsx

Lines changed: 66 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ import { TableColumn } from '@console/internal/module/k8s';
4747
import { GetDataViewRows, ResourceFilters } from '@console/app/src/components/data-view/types';
4848
import { tableFilters } from '../factory/table-filters';
4949
import { ButtonBar } from '../utils/button-bar';
50-
import { Firehose } from '../utils/firehose';
5150
import { getQueryArgument } from '../utils/router';
5251
import { kindObj } from '../utils/inject';
5352
import type { ListDropdownProps } from '../utils/list-dropdown';
@@ -57,7 +56,7 @@ import { ResourceName } from '../utils/resource-icon';
5756
import { StatusBox, LoadingBox } from '../utils/status-box';
5857
import { useAccessReview } from '../utils/rbac';
5958
import { flagPending } from '../../reducers/features';
60-
import { useK8sWatchResources } from '../utils/k8s-watch-hook';
59+
import { useK8sWatchResource, useK8sWatchResources } from '../utils/k8s-watch-hook';
6160

6261
// Split each binding into one row per subject
6362
export const flatten = (resources): BindingKind[] =>
@@ -185,18 +184,19 @@ const bindingType = (binding: BindingKind) => {
185184
if (!binding) {
186185
return undefined;
187186
}
188-
if (binding.roleRef.name.startsWith('system:')) {
187+
if (binding.roleRef?.name?.startsWith('system:')) {
189188
return 'system';
190189
}
191-
return binding.metadata.namespace ? 'namespace' : 'cluster';
190+
return binding.metadata?.namespace ? 'namespace' : 'cluster';
192191
};
193192

194193
const getDataViewRows: GetDataViewRows<BindingKind> = (data, columns) => {
195-
return data.map(({ obj: binding }) => {
194+
return data.map((row) => {
195+
const binding = row.obj;
196196
const rowCells = {
197197
[tableColumnInfo[0].id]: {
198198
cell: <BindingName binding={binding} />,
199-
props: getNameCellProps(binding.metadata.name),
199+
props: getNameCellProps(binding.metadata?.name),
200200
},
201201
[tableColumnInfo[1].id]: {
202202
cell: <RoleLink binding={binding} />,
@@ -208,7 +208,7 @@ const getDataViewRows: GetDataViewRows<BindingKind> = (data, columns) => {
208208
cell: binding.subject.name,
209209
},
210210
[tableColumnInfo[4].id]: {
211-
cell: binding.metadata.namespace ? (
211+
cell: binding.metadata?.namespace ? (
212212
<ResourceLink kind="Namespace" name={binding.metadata.namespace} />
213213
) : (
214214
i18next.t('public~All namespaces')
@@ -784,52 +784,79 @@ const getSubjectIndex = () => {
784784
};
785785

786786
const BindingLoadingWrapper: FC<BindingLoadingWrapperProps> = (props) => {
787+
const { obj, loaded, loadError, fixedKeys } = props;
787788
const [, setActiveNamespace] = useActiveNamespace();
789+
790+
if (!loaded) {
791+
return <LoadingBox />;
792+
}
793+
794+
if (loadError) {
795+
return <StatusBox data={obj} loaded={loaded} loadError={loadError} />;
796+
}
797+
798+
if (!obj || _.isEmpty(obj)) {
799+
return <StatusBox data={obj} loaded={loaded} loadError={loadError} />;
800+
}
801+
788802
const fixed: { [key: string]: any } = {};
789-
_.each(props.fixedKeys, (k) => (fixed[k] = _.get(props.obj.data, k)));
803+
fixedKeys.forEach((k) => (fixed[k] = obj?.[k]));
804+
790805
return (
791-
<StatusBox {...props.obj}>
792-
<BaseEditRoleBinding
793-
{...props}
794-
setActiveNamespace={setActiveNamespace}
795-
fixed={fixed}
796-
obj={props.obj.data}
797-
/>
798-
</StatusBox>
806+
<BaseEditRoleBinding
807+
{...props}
808+
setActiveNamespace={setActiveNamespace}
809+
fixed={fixed}
810+
obj={obj}
811+
/>
799812
);
800813
};
801814

802815
export const EditRoleBinding: FC<EditRoleBindingProps> = ({ kind }) => {
803816
const { t } = useTranslation();
804817
const params = useParams();
818+
819+
const [obj, loaded, loadError] = useK8sWatchResource<RoleBindingKind | ClusterRoleBindingKind>({
820+
kind,
821+
name: params.name,
822+
namespace: params.ns,
823+
isList: false,
824+
});
825+
805826
return (
806-
<Firehose
807-
resources={[{ kind, name: params.name, namespace: params.ns, isList: false, prop: 'obj' }]}
808-
>
809-
<BindingLoadingWrapper
810-
fixedKeys={['kind', 'metadata', 'roleRef']}
811-
subjectIndex={getSubjectIndex()}
812-
titleVerbAndKind={t('public~Edit RoleBinding')}
813-
saveButtonText={t('public~Save')}
814-
/>
815-
</Firehose>
827+
<BindingLoadingWrapper
828+
obj={obj}
829+
loaded={loaded}
830+
loadError={loadError}
831+
fixedKeys={['kind', 'metadata', 'roleRef']}
832+
subjectIndex={getSubjectIndex()}
833+
titleVerbAndKind={t('public~Edit RoleBinding')}
834+
saveButtonText={t('public~Save')}
835+
/>
816836
);
817837
};
818838

819839
export const CopyRoleBinding: FC<EditRoleBindingProps> = ({ kind }) => {
820840
const { t } = useTranslation();
821841
const params = useParams();
842+
843+
const [obj, loaded, loadError] = useK8sWatchResource<RoleBindingKind | ClusterRoleBindingKind>({
844+
kind,
845+
name: params.name,
846+
namespace: params.ns,
847+
isList: false,
848+
});
849+
822850
return (
823-
<Firehose
824-
resources={[{ kind, name: params.name, namespace: params.ns, isList: false, prop: 'obj' }]}
825-
>
826-
<BindingLoadingWrapper
827-
fixedKeys={['kind']}
828-
subjectIndex={getSubjectIndex()}
829-
isCreate={true}
830-
titleVerbAndKind={t('public~Duplicate RoleBinding')}
831-
/>
832-
</Firehose>
851+
<BindingLoadingWrapper
852+
obj={obj}
853+
loaded={loaded}
854+
loadError={loadError}
855+
fixedKeys={['kind']}
856+
subjectIndex={getSubjectIndex()}
857+
isCreate={true}
858+
titleVerbAndKind={t('public~Duplicate RoleBinding')}
859+
/>
833860
);
834861
};
835862

@@ -881,9 +908,9 @@ type BindingLoadingWrapperProps = {
881908
titleVerbAndKind: string;
882909
saveButtonText?: string;
883910
isCreate?: boolean;
884-
obj?: {
885-
data: RoleBindingKind | ClusterRoleBindingKind;
886-
};
911+
obj?: RoleBindingKind | ClusterRoleBindingKind;
912+
loaded: boolean;
913+
loadError: any;
887914
};
888915

889916
type EditRoleBindingProps = {

0 commit comments

Comments
 (0)