Skip to content

Commit

Permalink
Adding custom hook for selection on list component
Browse files Browse the repository at this point in the history
  • Loading branch information
gnehapk committed Jun 17, 2020
1 parent c882a73 commit f5043b5
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
import { ListPage } from '@console/internal/components/factory';
import { NodeModel } from '@console/internal/models';
import { hasLabel, getName } from '@console/shared';
import { useSelectList } from '@console/shared/src/hooks/select-list';
import {
withHandlePromise,
HandlePromiseProps,
Expand All @@ -38,6 +39,7 @@ import { cephStorageLabel } from '../../selectors';
import NodeTable from './node-list';
import { PVsAvailableCapacity } from './pvs-available-capacity';
import { OCS_FLAG, OCS_CONVERGED_FLAG } from '../../features';

import './ocs-install.scss';

const makeLabelNodesRequest = (selectedNodes: NodeKind[]): Promise<NodeKind>[] => {
Expand Down Expand Up @@ -96,11 +98,15 @@ export const CreateOCSServiceForm = withHandlePromise<
params: { appName, ns },
},
} = props;
const [selectedNodes, setSelectedNodes] = React.useState<NodeKind[]>(null);
const [visibleRows, setVisibleRows] = React.useState<NodeKind[]>(null);
const [visibleRows, setVisibleRows] = React.useState<NodeKind[]>([]);
const [osdSize, setOSDSize] = React.useState(defaultRequestSize.NON_BAREMETAL);
const [storageClass, setStorageClass] = React.useState<StorageClassResourceKind>(null);
const dispatch = useDispatch();
const {
onSelect,
selectedRows: selectedNodes,
setSelectedRows: setSelectedNodes,
} = useSelectList<NodeKind>(visibleRows);

const submit = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
Expand Down Expand Up @@ -153,6 +159,7 @@ export const CreateOCSServiceForm = withHandlePromise<
kind={NodeModel.kind}
showTitle={false}
ListComponent={NodeTable}
onSelect={onSelect}
customData={{ selectedNodes, setSelectedNodes, visibleRows, setVisibleRows }}
/>
</FormGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import {
import { humanizeCpuCores, ResourceLink, pluralize } from '@console/internal/components/utils/';
import { NodeKind } from '@console/internal/module/k8s';
import { Table } from '@console/internal/components/factory';
import { IRow, OnSelect } from '@patternfly/react-table';
import { IRow } from '@patternfly/react-table';
import { hasOCSTaint, hasTaints, getConvertedUnits } from '../../utils/install';
import { cephStorageLabel } from '../../selectors';

import './ocs-install.scss';

const tableColumnClasses = [
Expand Down Expand Up @@ -115,39 +116,7 @@ const getRows: GetRows = ({ componentProps, customData }) => {
};

const NodeTable: React.FC<NodeTableProps> = (props) => {
const { selectedNodes, setSelectedNodes, visibleRows } = props.customData;

const onSelect: OnSelect = (_event, isSelected, rowIndex, rowData) => {
const selectedUIDs = selectedNodes?.map((node) => node.metadata.uid) ?? [];
const visibleUIDs = visibleRows?.map((row) => row.metadata.uid);
if (rowIndex === -1) {
if (isSelected) {
const uniqueUIDs = _.uniq([...visibleUIDs, ...selectedUIDs]);
setSelectedNodes(
_.uniqBy(
[...visibleRows, ...selectedNodes].filter((node) =>
uniqueUIDs.includes(node.metadata.uid),
),
(n) => n.metadata.uid,
),
);
} else {
setSelectedNodes(
_.uniqBy(
selectedNodes.filter((node) => !visibleUIDs.includes(node.metadata.uid)),
(n) => n.metadata.uid,
),
);
}
} else {
const uniqueUIDs = _.xor(selectedUIDs, [rowData.props.id]);
const data = _.uniqBy(
[...visibleRows, ...selectedNodes].filter((node) => uniqueUIDs.includes(node.metadata.uid)),
(n) => n.metadata.uid,
);
setSelectedNodes(data);
}
};
const { selectedNodes } = props.customData;

return (
<>
Expand All @@ -159,7 +128,6 @@ const NodeTable: React.FC<NodeTableProps> = (props) => {
Rows={getRows}
Header={getColumns}
virtualize={false}
onSelect={onSelect}
/>
</div>
<p className="control-label help-block" data-test-id="nodes-selected">
Expand Down
1 change: 1 addition & 0 deletions frontend/packages/console-shared/src/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './fullscreen';
export * from './scroll';
export * from './plugins-overview-tab-section';
export * from './debounce';
export * from './select-list';
61 changes: 61 additions & 0 deletions frontend/packages/console-shared/src/hooks/select-list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import * as React from 'react';
import * as _ from 'lodash';
import { K8sResourceCommon } from '@console/internal/module/k8s';
import { IRowData } from '@patternfly/react-table';

export const useSelectList = <R extends K8sResourceCommon>(
visibleRows: R[],
): {
onSelect: (
event: React.MouseEvent,
isSelected: boolean,
rowIndex: number,
rowData: IRowData,
) => void;
selectedRows: R[];
setSelectedRows: React.Dispatch<React.SetStateAction<R[]>>;
} => {
const [selectedRows, setSelectedRows] = React.useState<R[]>([]);

const onSelect = (
_event: React.MouseEvent,
isSelected: boolean,
rowIndex: number,
rowData: IRowData,
) => {
const selectedUIDs = selectedRows?.map((node) => node.metadata.uid) ?? [];
const visibleUIDs = visibleRows?.map((row) => row.metadata.uid);
if (rowIndex === -1) {
if (isSelected) {
const uniqueUIDs = _.uniq([...visibleUIDs, ...selectedUIDs]);
setSelectedRows(
_.uniqBy(
[...visibleRows, ...selectedRows].filter((node) =>
uniqueUIDs.includes(node.metadata.uid),
),
(n) => n.metadata.uid,
),
);
} else {
setSelectedRows(
_.uniqBy(
selectedRows.filter((node) => !visibleUIDs.includes(node.metadata.uid)),
(n) => n.metadata.uid,
),
);
}
} else {
const uniqueUIDs = _.xor(selectedUIDs, [rowData?.props?.id]);
const data = _.uniqBy(
[...visibleRows, ...selectedRows].filter((node) => uniqueUIDs.includes(node.metadata.uid)),
(n) => n.metadata.uid,
);
setSelectedRows(data);
}
};
return {
onSelect,
selectedRows,
setSelectedRows,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,14 @@ import {
} from '@console/internal/components/utils';
import { history } from '@console/internal/components/utils/router';
import { ListPage } from '@console/internal/components/factory';
import { k8sCreate, referenceFor } from '@console/internal/module/k8s';
import { k8sCreate, referenceFor, NodeKind } from '@console/internal/module/k8s';
import { NodeModel } from '@console/internal/models';
import { useSelectList } from '@console/shared/src/hooks/select-list';
import { ClusterServiceVersionModel } from '@console/operator-lifecycle-manager';
import { LocalVolumeSetModel } from '../../models';
import { NodesSelectionList } from './nodes-selection-list';
import {
RowUIDMap,
LocalVolumeSetKind,
DeviceType,
DiskType,
DeviceMechanicalProperty,
} from './types';
import { getSelectedNodeUIDs } from './utils';
import { LocalVolumeSetKind, DeviceType, DiskType, DeviceMechanicalProperty } from './types';
import { getName } from '@console/shared';
import './create-local-volume-set.scss';

const volumeModeDropdownItems = {
Expand All @@ -56,11 +51,15 @@ const CreateLocalVolumeSet: React.FC = withHandlePromise<CreateLocalVolumeSetPro
const [volumeType, setVolumeType] = React.useState<DiskType>(DiskType.SSD);
const [volumeMode, setVolumeMode] = React.useState(volumeModeDropdownItems.Block);
const [maxVolumeLimit, setMaxVolumeLimit] = React.useState('');
const [rows, setRows] = React.useState<RowUIDMap>({});
const [allSelected, setAllSelected] = React.useState<boolean>(null);
const [visibleRows, setVisibleRows] = React.useState<NodeKind[]>([]);

const { ns, appName } = match.params;
const modelName = LocalVolumeSetModel.label;
const {
onSelect,
selectedRows: selectedNodes,
setSelectedRows: setSelectedNodes,
} = useSelectList<NodeKind>(visibleRows);

const toggleShowNodesList = () => {
setShowNodesList(!showNodesList);
Expand All @@ -85,13 +84,12 @@ const CreateLocalVolumeSet: React.FC = withHandlePromise<CreateLocalVolumeSetPro
};

if (showNodesList) {
const selectedNodesUID = getSelectedNodeUIDs(rows);
const selectedNodes = selectedNodesUID.map((uid) => rows[uid].props.data.metadata.name);
const selectedNodesNames = selectedNodes.map((node) => getName(node));
requestData.spec.nodeSelector = {
nodeSelectorTerms: [
{
matchExpressions: [
{ key: 'kubernetes.io/hostname', operator: 'In', values: [...selectedNodes] },
{ key: 'kubernetes.io/hostname', operator: 'In', values: [...selectedNodesNames] },
],
},
],
Expand Down Expand Up @@ -170,10 +168,11 @@ const CreateLocalVolumeSet: React.FC = withHandlePromise<CreateLocalVolumeSetPro
</FormGroup>
{showNodesList && (
<ListPage
customData={{ rows, setRows, allSelected, setAllSelected }}
customData={{ selectedNodes, setSelectedNodes, visibleRows, setVisibleRows }}
showTitle={false}
kind={NodeModel.kind}
ListComponent={NodesSelectionList}
onSelect={onSelect}
/>
)}
<FormGroup label="Volume Type" fieldId="create-lvs--volume-type-dropdown">
Expand Down

0 comments on commit f5043b5

Please sign in to comment.