[FE] Use id field for keys

This commit is contained in:
Azat Mutigullin 2020-11-12 18:21:21 +03:00
parent cba12d4ff4
commit be4b9543ce
8 changed files with 32 additions and 17 deletions

View file

@ -12,6 +12,11 @@ interface Props {
offlineClusters: Cluster[];
}
interface ChunkItem {
id: string;
data: Cluster[];
}
const ClustersWidget: React.FC<Props> = ({
clusters,
onlineClusters,
@ -19,14 +24,17 @@ const ClustersWidget: React.FC<Props> = ({
}) => {
const [showOfflineOnly, setShowOfflineOnly] = React.useState<boolean>(false);
const clusterList: Array<Cluster[]> = React.useMemo(() => {
const clusterList: ChunkItem[] = React.useMemo(() => {
let list = clusters;
if (showOfflineOnly) {
list = offlineClusters;
}
return chunk(list, 2);
return chunk(list, 2).map((data) => ({
id: v4(),
data,
}));
}, [clusters, offlineClusters, showOfflineOnly]);
const handleSwitch = () => setShowOfflineOnly(!showOfflineOnly);
@ -56,8 +64,8 @@ const ClustersWidget: React.FC<Props> = ({
</MetricsWrapper>
{clusterList.map((chunkItem) => (
<div className="columns" key={v4()}>
{chunkItem.map((cluster) => (
<div className="columns" key={chunkItem.id}>
{chunkItem.data.map((cluster) => (
<ClusterWidget cluster={cluster} key={cluster.id} />
))}
</div>

View file

@ -1,5 +1,4 @@
import React from 'react';
import { v4 } from 'uuid';
import { ClusterName, TopicName, TopicConfig } from 'redux/interfaces';
interface Props {
@ -57,7 +56,7 @@ const Sertings: React.FC<Props> = ({
</thead>
<tbody>
{config.map((item) => (
<ConfigListItem key={v4()} config={item} />
<ConfigListItem key={item.id} config={item} />
))}
</tbody>
</table>

View file

@ -1,5 +1,4 @@
import React from 'react';
import { v4 } from 'uuid';
import { TopicWithDetailedInfo, ClusterName } from 'redux/interfaces';
import Breadcrumb from 'components/common/Breadcrumb/Breadcrumb';
import { NavLink } from 'react-router-dom';
@ -60,7 +59,7 @@ const List: React.FC<Props> = ({ clusterName, topics, externalTopics }) => {
</thead>
<tbody>
{items.map((topic) => (
<ListItem key={v4()} topic={topic} />
<ListItem key={topic.id} topic={topic} />
))}
</tbody>
</table>

View file

@ -1,6 +1,5 @@
import React from 'react';
import { NavLink } from 'react-router-dom';
import { v4 } from 'uuid';
interface Link {
label: string;
@ -17,7 +16,7 @@ const Breadcrumb: React.FC<Props> = ({ links, children }) => {
<ul>
{links &&
links.map(({ label, href }) => (
<li key={v4()}>
<li key={href}>
<NavLink to={href}>{label}</NavLink>
</li>
))}

View file

@ -5,7 +5,7 @@ import {
BrokerMetrics,
Cluster,
Topic,
TopicConfig,
InputTopicConfig,
TopicDetails,
TopicMessage,
TopicName,
@ -54,7 +54,7 @@ export const fetchTopicConfigAction = createAsyncAction(
ActionType.GET_TOPIC_CONFIG__REQUEST,
ActionType.GET_TOPIC_CONFIG__SUCCESS,
ActionType.GET_TOPIC_CONFIG__FAILURE
)<undefined, { topicName: TopicName; config: TopicConfig[] }, undefined>();
)<undefined, { topicName: TopicName; config: InputTopicConfig[] }, undefined>();
export const createTopicAction = createAsyncAction(
ActionType.POST_TOPIC__REQUEST,

View file

@ -4,7 +4,7 @@ import {
Topic,
ClusterName,
TopicDetails,
TopicConfig,
InputTopicConfig,
TopicFormData,
TopicFormCustomParam,
TopicFormFormattedParams,
@ -30,7 +30,7 @@ const formatCustomParams = (
export const getTopicConfig = (
clusterName: ClusterName,
topicName: TopicName
): Promise<TopicConfig[]> =>
): Promise<InputTopicConfig[]> =>
fetch(`${BASE_URL}/clusters/${clusterName}/topics/${topicName}/config`, {
...BASE_PARAMS,
}).then((res) => res.json());

View file

@ -5,12 +5,16 @@ export enum CleanupPolicy {
Compact = 'compact',
}
export interface TopicConfig {
export interface InputTopicConfig {
name: string;
value: string;
defaultValue: string;
}
export interface TopicConfig extends InputTopicConfig {
id: string;
}
export interface TopicConfigByName {
byName: {
[paramName: string]: TopicConfig;
@ -89,6 +93,7 @@ export interface TopicFormCustomParams {
export interface TopicWithDetailedInfo extends Topic, TopicDetails {
config?: TopicConfig[];
id: string;
}
export interface TopicsState {

View file

@ -1,3 +1,4 @@
import { v4 } from 'uuid';
import { Action, TopicsState, Topic } from 'redux/interfaces';
import ActionType from 'redux/actionType';
@ -18,6 +19,7 @@ const updateTopicList = (state: TopicsState, payload: Topic[]): TopicsState => {
memo.byName[name] = {
...memo.byName[name],
...topic,
id: v4(),
};
memo.allNames.push(name);
@ -30,7 +32,7 @@ const addToTopicList = (state: TopicsState, payload: Topic): TopicsState => {
...state,
};
newState.allNames.push(payload.name);
newState.byName[payload.name] = payload;
newState.byName[payload.name] = { ...payload, id: v4() };
return newState;
};
@ -61,7 +63,10 @@ const reducer = (state = initialState, action: Action): TopicsState => {
...state.byName,
[action.payload.topicName]: {
...state.byName[action.payload.topicName],
config: action.payload.config,
config: action.payload.config.map((inputConfig) => ({
...inputConfig,
id: v4(),
})),
},
},
};