From ad2966f31b5acf04ee485902bb01980a946ddadc Mon Sep 17 00:00:00 2001 From: Kirill Morozov Date: Wed, 25 May 2022 14:33:05 +0300 Subject: [PATCH] Topics sorted alphabetically (#1999) * Added topics sorting and tests * Sorting topics logic moved to redux, test improved * LocaleCompare replaced with default sort function * Shadow fixed on overview topic page * Code samples fixed in InfoModal * String type removed * Unused import removed * Default JS sort method removed with lodash library sorting method --- .../components/Connect/List/ListContainer.ts | 2 + .../Connect/List/__tests__/ListItem.spec.tsx | 8 ++++ .../Messages/Filters/Filters.styled.ts | 10 +++++ .../Details/Messages/Filters/InfoModal.tsx | 39 +++++++++++-------- .../common/Metrics/Metrics.styled.tsx | 4 +- .../reducers/connect/__test__/fixtures.ts | 8 ++-- .../connect/__test__/selectors.spec.ts | 11 ++++++ .../src/redux/reducers/connect/selectors.ts | 5 +++ 8 files changed, 64 insertions(+), 23 deletions(-) diff --git a/kafka-ui-react-app/src/components/Connect/List/ListContainer.ts b/kafka-ui-react-app/src/components/Connect/List/ListContainer.ts index c3e939a2db..dbd7a71771 100644 --- a/kafka-ui-react-app/src/components/Connect/List/ListContainer.ts +++ b/kafka-ui-react-app/src/components/Connect/List/ListContainer.ts @@ -12,6 +12,7 @@ import { getAreConnectorsFetching, getConnectorSearch, getFailedConnectors, + getSortedTopics, getFailedTasks, } from 'redux/reducers/connect/selectors'; import List from 'components/Connect/List/List'; @@ -21,6 +22,7 @@ const mapStateToProps = (state: RootState) => ({ areConnectorsFetching: getAreConnectorsFetching(state), connects: getConnects(state), failedConnectors: getFailedConnectors(state), + sortedTopics: getSortedTopics(state), failedTasks: getFailedTasks(state), connectors: getConnectors(state), search: getConnectorSearch(state), diff --git a/kafka-ui-react-app/src/components/Connect/List/__tests__/ListItem.spec.tsx b/kafka-ui-react-app/src/components/Connect/List/__tests__/ListItem.spec.tsx index 0956b9ff69..6ecc8a5f18 100644 --- a/kafka-ui-react-app/src/components/Connect/List/__tests__/ListItem.spec.tsx +++ b/kafka-ui-react-app/src/components/Connect/List/__tests__/ListItem.spec.tsx @@ -52,6 +52,14 @@ describe('Connectors ListItem', () => { expect(screen.getAllByRole('cell')[6]).toHaveTextContent('2 of 2'); }); + it('topics tags are sorted', () => { + render(setupWrapper()); + const getLink = screen.getAllByRole('link'); + expect(getLink[1]).toHaveTextContent('a'); + expect(getLink[2]).toHaveTextContent('b'); + expect(getLink[3]).toHaveTextContent('c'); + }); + it('renders item with failed tasks', () => { render( setupWrapper({ diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.styled.ts b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.styled.ts index 7bb48b3768..8ca07c71a3 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.styled.ts +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/Filters.styled.ts @@ -125,6 +125,16 @@ export const InfoParagraph = styled.p` color: ${({ theme }) => theme.table.td.color.normal}; `; +export const InfoCodeSample = styled.pre` + background: #f5f5f5; + padding: 5px; + border: 1px solid #e1e1e1; + border-radius: 5px; + width: fit-content; + margin: 5px 20px; + color: #cc0f35; +`; + export const MessageFilterModal = styled.div` height: auto; width: 560px; diff --git a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/InfoModal.tsx b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/InfoModal.tsx index b86b877606..91a4e5a463 100644 --- a/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/InfoModal.tsx +++ b/kafka-ui-react-app/src/components/Topics/Topic/Details/Messages/Filters/InfoModal.tsx @@ -26,32 +26,37 @@ const InfoModal: React.FC = ({ toggleIsOpen }) => {
    - `keyAsText != null && keyAsText ~"([Gg])roovy"` - regex for - key as a string + keyAsText != null && keyAsText ~"([Gg])roovy" - + regex for key as a string - `value.name == "iS.ListItemax" && value.age > 30` - in - case value is json + + value.name == "iS.ListItemax" && value.age > 30 + {' '} + - in case value is json - `value == null && valueAsText != null` - search for values that are - not nulls and are not json + value == null && valueAsText != null - search for values + that are not nulls and are not json - `headers.sentBy == "some system" && - headers["sentAt"] == "2020-01-01"` + + headers.sentBy == "some system" && + headers["sentAt"] == "2020-01-01" + multiline filters are also allowed: - ``` -
    - def name = value.name -
    - def age = value.age -
    - name == "iliax" && age == 30 -
    - ``` + + + def name = value.name +
    + def age = value.age +
    + name == "iliax" && age == 30 +
    +
    +
diff --git a/kafka-ui-react-app/src/components/common/Metrics/Metrics.styled.tsx b/kafka-ui-react-app/src/components/common/Metrics/Metrics.styled.tsx index 7a3bb44dbe..9924c5ba13 100644 --- a/kafka-ui-react-app/src/components/common/Metrics/Metrics.styled.tsx +++ b/kafka-ui-react-app/src/components/common/Metrics/Metrics.styled.tsx @@ -21,7 +21,6 @@ export const IndicatorWrapper = styled.div` align-items: flex-start; padding: 12px 16px; box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.08); - margin: 0 0 3px 0; flex-grow: 1; `; @@ -36,10 +35,11 @@ export const IndicatorTitle = styled.div` export const IndicatorsWrapper = styled.div` display: flex; - gap: 1px; + gap: 2px; flex-wrap: wrap; border-radius: 8px; overflow: auto; + box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.08); `; export const SectionTitle = styled.h5` diff --git a/kafka-ui-react-app/src/redux/reducers/connect/__test__/fixtures.ts b/kafka-ui-react-app/src/redux/reducers/connect/__test__/fixtures.ts index 2ef1248acf..5fc7cad55d 100644 --- a/kafka-ui-react-app/src/redux/reducers/connect/__test__/fixtures.ts +++ b/kafka-ui-react-app/src/redux/reducers/connect/__test__/fixtures.ts @@ -19,7 +19,7 @@ export const connectorsServerPayload = [ name: 'hdfs-source-connector', connector_class: 'FileStreamSource', type: ConnectorType.SOURCE, - topics: ['test-topic'], + topics: ['a', 'b', 'c'], status: { state: ConnectorTaskStatus.RUNNING, workerId: 1, @@ -48,7 +48,7 @@ export const connectors: FullConnectorInfo[] = [ name: 'hdfs-source-connector', connectorClass: 'FileStreamSource', type: ConnectorType.SOURCE, - topics: ['test-topic'], + topics: ['a', 'b', 'c'], status: { state: ConnectorState.RUNNING, }, @@ -75,7 +75,7 @@ export const failedConnectors: FullConnectorInfo[] = [ name: 'hdfs-source-connector', connectorClass: 'FileStreamSource', type: ConnectorType.SOURCE, - topics: ['test-topic'], + topics: ['a', 'b', 'c'], status: { state: ConnectorState.FAILED, }, @@ -87,7 +87,7 @@ export const failedConnectors: FullConnectorInfo[] = [ name: 'hdfs2-source-connector', connectorClass: 'FileStreamSource', type: ConnectorType.SINK, - topics: ['test-topic'], + topics: ['a', 'b', 'c'], status: { state: ConnectorState.FAILED, }, diff --git a/kafka-ui-react-app/src/redux/reducers/connect/__test__/selectors.spec.ts b/kafka-ui-react-app/src/redux/reducers/connect/__test__/selectors.spec.ts index 0ca9e2fdd0..a1f7162685 100644 --- a/kafka-ui-react-app/src/redux/reducers/connect/__test__/selectors.spec.ts +++ b/kafka-ui-react-app/src/redux/reducers/connect/__test__/selectors.spec.ts @@ -83,6 +83,17 @@ describe('Connect selectors', () => { expect(selectors.getFailedTasks(store.getState())).toEqual(1); }); + it('returns sorted topics', () => { + store.dispatch({ + type: fetchConnectors.fulfilled.type, + payload: { connectors }, + }); + const sortedTopics = selectors.getSortedTopics(store.getState()); + if (sortedTopics[0] && sortedTopics[0].length > 1) { + expect(sortedTopics[0]).toEqual(['a', 'b', 'c']); + } + }); + it('returns connector', () => { store.dispatch({ type: fetchConnector.fulfilled.type, diff --git a/kafka-ui-react-app/src/redux/reducers/connect/selectors.ts b/kafka-ui-react-app/src/redux/reducers/connect/selectors.ts index 2e029a7f9e..c11f7ac2e8 100644 --- a/kafka-ui-react-app/src/redux/reducers/connect/selectors.ts +++ b/kafka-ui-react-app/src/redux/reducers/connect/selectors.ts @@ -6,6 +6,7 @@ import { ConnectorState, FullConnectorInfo, } from 'generated-sources'; +import { sortBy } from 'lodash'; import { deleteConnector, @@ -63,6 +64,10 @@ export const getFailedTasks = createSelector(connectState, ({ connectors }) => { .reduce((acc: number, value: number) => acc + value, 0); }); +export const getSortedTopics = createSelector(connectState, ({ connectors }) => + connectors.map(({ topics }) => sortBy(topics || [])) +); + const getConnectorFetchingStatus = createFetchingSelector( fetchConnector.typePrefix );