Skip to content

Commit

Permalink
FE: Remove lodash lib (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mgrdich authored Apr 17, 2024
1 parent 475caa3 commit 94f9ce6
Show file tree
Hide file tree
Showing 18 changed files with 173 additions and 38 deletions.
4 changes: 3 additions & 1 deletion frontend/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@
{
"props": true,
"ignorePropertyModificationsFor": [
"state"
"state",
"acc",
"accumulator"
]
}
],
Expand Down
2 changes: 0 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"classnames": "^2.2.6",
"json-schema-faker": "^0.5.6",
"jsonpath-plus": "^7.2.0",
"lodash": "^4.17.21",
"lossless-json": "^2.0.8",
"pretty-ms": "7.0.1",
"react": "^18.1.0",
Expand Down Expand Up @@ -62,7 +61,6 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/user-event": "^14.4.3",
"@types/eventsource": "^1.1.8",
"@types/lodash": "^4.14.172",
"@types/lossless-json": "^1.0.1",
"@types/node": "^20.11.17",
"@types/react": "^18.0.9",
Expand Down
10 changes: 0 additions & 10 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion frontend/src/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const App: React.FC = () => {
</Suspense>
</ThemeProvider>
</GlobalSettingsProvider>
<ReactQueryDevtools initialIsOpen={false} />
<ReactQueryDevtools initialIsOpen={false} position="bottom-right" />
</QueryClientProvider>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,24 @@ import React from 'react';
import { render, WithRoute } from 'lib/testHelpers';
import { clusterConnectConnectorPath } from 'lib/paths';
import Actions from 'components/Connect/Details/Actions/Actions';
import { ConnectorAction, ConnectorState } from 'generated-sources';
import { Connector, ConnectorAction, ConnectorState } from 'generated-sources';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {
useConnector,
useUpdateConnectorState,
} from 'lib/hooks/api/kafkaConnect';
import { connector } from 'lib/fixtures/kafkaConnect';
import set from 'lodash/set';

function setConnectorStatus(con: Connector, state: ConnectorState) {
return {
...con,
status: {
...con,
state,
},
};
}

const mockHistoryPush = jest.fn();
const deleteConnector = jest.fn();
Expand Down Expand Up @@ -66,7 +75,7 @@ describe('Actions', () => {

it('renders buttons when paused', async () => {
(useConnector as jest.Mock).mockImplementation(() => ({
data: set({ ...connector }, 'status.state', ConnectorState.PAUSED),
data: setConnectorStatus(connector, ConnectorState.PAUSED),
}));
renderComponent();
await afterClickRestartButton();
Expand All @@ -78,7 +87,7 @@ describe('Actions', () => {

it('renders buttons when failed', async () => {
(useConnector as jest.Mock).mockImplementation(() => ({
data: set({ ...connector }, 'status.state', ConnectorState.FAILED),
data: setConnectorStatus(connector, ConnectorState.FAILED),
}));
renderComponent();
await afterClickRestartButton();
Expand All @@ -90,7 +99,7 @@ describe('Actions', () => {

it('renders buttons when unassigned', async () => {
(useConnector as jest.Mock).mockImplementation(() => ({
data: set({ ...connector }, 'status.state', ConnectorState.UNASSIGNED),
data: setConnectorStatus(connector, ConnectorState.UNASSIGNED),
}));
renderComponent();
await afterClickRestartButton();
Expand All @@ -102,7 +111,7 @@ describe('Actions', () => {

it('renders buttons when running connector action', async () => {
(useConnector as jest.Mock).mockImplementation(() => ({
data: set({ ...connector }, 'status.state', ConnectorState.RUNNING),
data: setConnectorStatus(connector, ConnectorState.RUNNING),
}));
renderComponent();
await afterClickRestartButton();
Expand All @@ -115,7 +124,7 @@ describe('Actions', () => {
describe('mutations', () => {
beforeEach(() => {
(useConnector as jest.Mock).mockImplementation(() => ({
data: set({ ...connector }, 'status.state', ConnectorState.RUNNING),
data: setConnectorStatus(connector, ConnectorState.RUNNING),
}));
});

Expand Down Expand Up @@ -185,7 +194,7 @@ describe('Actions', () => {
it('calls resumeConnector when resume button clicked', async () => {
const resumeConnector = jest.fn();
(useConnector as jest.Mock).mockImplementation(() => ({
data: set({ ...connector }, 'status.state', ConnectorState.PAUSED),
data: setConnectorStatus(connector, ConnectorState.PAUSED),
}));
(useUpdateConnectorState as jest.Mock).mockImplementation(() => ({
mutateAsync: resumeConnector,
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/Connect/New/New.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { Button } from 'components/common/Button/Button';
import PageHeading from 'components/common/PageHeading/PageHeading';
import Heading from 'components/common/heading/Heading.styled';
import { useConnects, useCreateConnector } from 'lib/hooks/api/kafkaConnect';
import get from 'lodash/get';
import { Connect } from 'generated-sources';

import * as S from './New.styled';
Expand All @@ -45,7 +44,7 @@ const New: React.FC = () => {
mode: 'all',
resolver: yupResolver(validationSchema),
defaultValues: {
connectName: get(connects, '0.name', ''),
connectName: connects.length > 0 ? connects[0].name : '',
name: '',
config: '',
},
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/components/ConsumerGroups/Details/Details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ClusterContext from 'components/contexts/ClusterContext';
import PageHeading from 'components/common/PageHeading/PageHeading';
import * as Metrics from 'components/common/Metrics';
import { Tag } from 'components/common/Tag/Tag.styled';
import groupBy from 'lodash/groupBy';
import groupBy from 'lib/functions/groupBy';
import { Table } from 'components/common/table/Table/Table.styled';
import getTagColor from 'components/common/Tag/getTagColor';
import { Dropdown } from 'components/common/Dropdown';
Expand Down Expand Up @@ -48,7 +48,10 @@ const Details: React.FC = () => {
navigate(clusterConsumerGroupResetRelativePath);
};

const partitionsByTopic = groupBy(consumerGroup.data?.partitions, 'topic');
const partitionsByTopic = groupBy(
consumerGroup.data?.partitions || [],
'topic'
);
const filteredPartitionsByTopic = Object.keys(partitionsByTopic).filter(
(el) => el.includes(searchValue)
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Partition, PollingMode, SeekType } from 'generated-sources';
import compact from 'lodash/compact';
import { Option } from 'react-multi-select-component';
import compact from 'lib/functions/compact';

export function isModeOptionWithInput(value: PollingMode) {
return (
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/components/Topics/Topic/SendMessage/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
import jsf from 'json-schema-faker';
import Ajv, { DefinedError } from 'ajv/dist/2020';
import addFormats from 'ajv-formats';
import upperFirst from 'lodash/upperFirst';

jsf.option('fillProperties', false);
jsf.option('alwaysFakeOptionals', true);
Expand Down Expand Up @@ -53,6 +52,10 @@ export const getSerdeOptions = (items: SerdeDescription[]) => {
}, []);
};

function upperFirst(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}

export const validateBySchema = (
value: string,
schema: string | undefined,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import updateSortingState from 'components/common/NewTable/utils/updateSortingState';
import { SortingState } from '@tanstack/react-table';
import compact from 'lodash/compact';
import compact from 'lib/functions/compact';

const updater = (previousState: SortingState): SortingState => {
return compact(
Expand Down
34 changes: 34 additions & 0 deletions frontend/src/lib/functions/__tests__/compact.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import compact from 'lib/functions/compact';

describe('compact', () => {
it('should remove falsey values from the array', () => {
const input = [0, 1, false, 2, '', 3, null, undefined, 4, NaN, 5];
const expected = [1, 2, 3, 4, 5];
expect(compact(input)).toEqual(expected);
});

it('should return an empty array if all values are falsey', () => {
const input = [0, false, '', null, undefined, NaN];
const expected: number[] = [];
expect(compact(input)).toEqual(expected);
});

it('should return a new array with only truthy values preserved', () => {
const input = [1, 'hello', true, [], { a: 1 }, 42];
const expected = [1, 'hello', true, [], { a: 1 }, 42];
expect(compact(input)).toEqual(expected);
});

it('should preserve non-falsey values in their original order', () => {
const input = [1, null, 2, undefined, 3, false, 4];
const expected = [1, 2, 3, 4];
expect(compact(input)).toEqual(expected);
});

it('should not modify the original array', () => {
const input = [0, 1, 2, false, '', null, undefined, NaN];
const inputCopy = [...input];
compact(input);
expect(input).toEqual(inputCopy);
});
});
45 changes: 45 additions & 0 deletions frontend/src/lib/functions/__tests__/groupBy.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import groupBy from 'lib/functions/groupBy';

describe('groupBy', () => {
it('should group objects in the array by the specified key', () => {
const input = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Doe' },
{ id: 4, name: 'John' },
];

const result = groupBy(input, 'name');

expect(result).toEqual({
John: [
{ id: 1, name: 'John' },
{ id: 4, name: 'John' },
],
Jane: [{ id: 2, name: 'Jane' }],
Doe: [{ id: 3, name: 'Doe' }],
});
});

it('should return an empty object when the input array is empty', () => {
const result = groupBy([], 'name');

expect(result).toEqual({});
});

it('should handle objects with undefined values for the specified key', () => {
const input = [
{ id: 1, name: 'John' },
{ id: 2, name: undefined },
{ id: 3, name: 'Doe' },
{ id: 4 },
];

const result = groupBy(input, 'name');

expect(result).toEqual({
John: [{ id: 1, name: 'John' }],
Doe: [{ id: 3, name: 'Doe' }],
});
});
});
13 changes: 13 additions & 0 deletions frontend/src/lib/functions/compact.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/**
* @description
* Creates an array with all falsey values removed. The values false, null, 0, "", undefined, and NaN are
* falsey.
*
* @param array The array to compact.
* @return Returns the new array of filtered values.
*/
export default function compact<T>(
array: Array<T | null | undefined | false | '' | 0>
): T[] {
return array.filter(Boolean) as T[];
}
22 changes: 22 additions & 0 deletions frontend/src/lib/functions/groupBy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export default function groupBy<T extends object>(
collections: T[],
key: string
) {
return collections.reduce<Record<string, [T, ...T[]]>>((acc, curr) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const groupByKey = key in curr ? curr[key] : null;

if (typeof groupByKey !== 'string' && typeof groupByKey !== 'number') {
return acc;
}

if (acc[groupByKey]) {
acc[groupByKey].push(curr);
return acc;
}

acc[groupByKey] = [curr];
return acc;
}, {});
}
1 change: 0 additions & 1 deletion frontend/src/lib/functions/keyBy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export function keyBy<A extends object, K extends AvailableKeys<A>>(
return collection.reduce<Record<PropertyKey, A>>((acc, cur) => {
const key = cur[property] as unknown as PropertyKey;

// eslint-disable-next-line no-param-reassign
acc[key] = cur;

return acc;
Expand Down
27 changes: 24 additions & 3 deletions frontend/src/lib/hooks/api/kafkaConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
NewConnector,
} from 'generated-sources';
import { kafkaConnectApiClient as api } from 'lib/api';
import sortBy from 'lodash/sortBy';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { ClusterName } from 'lib/interfaces/cluster';
import { showSuccessAlert } from 'lib/errorHandling';
Expand Down Expand Up @@ -55,7 +54,16 @@ export function useConnectors(clusterName: ClusterName, search?: string) {
connectorsKey(clusterName, search),
() => api.getAllConnectors({ clusterName, search }),
{
select: (data) => sortBy(data, 'name'),
select: (data) =>
[...data].sort((a, b) => {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
}),
}
);
}
Expand All @@ -67,7 +75,20 @@ export function useConnectorTasks(props: UseConnectorProps) {
connectorTasksKey(props),
() => api.getConnectorTasks(props),
{
select: (data) => sortBy(data, 'status.id'),
select: (data) =>
[...data].sort((a, b) => {
const aid = a.status.id;
const bid = b.status.id;

if (aid < bid) {
return -1;
}

if (aid > bid) {
return 1;
}
return 0;
}),
}
);
}
Expand Down
Loading

0 comments on commit 94f9ce6

Please sign in to comment.