From d459f5a99860550aba38fc215bfaa791bbad8def Mon Sep 17 00:00:00 2001 From: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> Date: Wed, 4 Jan 2023 18:52:12 +0530 Subject: [PATCH] chore(ui): remove react-slick and use AntD carousel (#9586) --- .../src/main/resources/ui/package.json | 2 - .../FeaturesCarousel.interface.ts | 23 ++++++ .../Modals/WhatsNewModal/FeaturesCarousel.tsx | 78 +++++++++---------- .../ui/src/constants/Login.constants.ts | 14 ++-- .../ui/src/locale/languages/en-us.json | 2 +- .../ui/src/pages/login/LoginCarousel.test.tsx | 58 ++++++++------ .../ui/src/pages/login/LoginCarousel.tsx | 8 +- .../src/main/resources/ui/yarn.lock | 25 +----- 8 files changed, 106 insertions(+), 104 deletions(-) create mode 100644 openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.interface.ts diff --git a/openmetadata-ui/src/main/resources/ui/package.json b/openmetadata-ui/src/main/resources/ui/package.json index 1259be084f1..37043574da1 100644 --- a/openmetadata-ui/src/main/resources/ui/package.json +++ b/openmetadata-ui/src/main/resources/ui/package.json @@ -82,7 +82,6 @@ "react-oidc": "^1.0.3", "react-quill": "^2.0.0", "react-router-dom": "^5.2.0", - "react-slick": "^0.28.1", "react-tippy": "^1.4.0", "react-toastify": "^8.2.0", "reactflow": "^11.1.1", @@ -163,7 +162,6 @@ "@types/react-dom": "^17.0.11", "@types/react-lazylog": "^4.5.1", "@types/react-router-dom": "^5.1.7", - "@types/react-slick": "^0.23.5", "@types/react-test-renderer": "^17.0.0", "@types/reactjs-localstorage": "^1.0.0", "@types/recharts": "^1.8.23", diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.interface.ts b/openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.interface.ts new file mode 100644 index 00000000000..8ec77f210b1 --- /dev/null +++ b/openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.interface.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2022 Collate. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export type CarousalData = { + title: string; + description: string; + isImage: boolean; + path: string; +}; + +export type FeaturesCarouselProps = { + data: CarousalData[]; +}; diff --git a/openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.tsx b/openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.tsx index 58ad2a8a7cd..534293ce8d5 100644 --- a/openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/components/Modals/WhatsNewModal/FeaturesCarousel.tsx @@ -11,58 +11,52 @@ * limitations under the License. */ -/* eslint-disable max-len */ - +import { Carousel } from 'antd'; +import { CarouselProps, CarouselRef } from 'antd/lib/carousel'; import { uniqueId } from 'lodash'; -import React, { useEffect, useRef, useState } from 'react'; -import Slider from 'react-slick'; +import React, { useEffect, useMemo, useRef, useState } from 'react'; import RichTextEditorPreviewer from '../../common/rich-text-editor/RichTextEditorPreviewer'; +import { FeaturesCarouselProps } from './FeaturesCarousel.interface'; -type CarousalData = { - title: string; - description: string; - isImage: boolean; - path: string; -}; - -type Props = { - data: CarousalData[]; -}; - -const FeaturesCarousel = ({ data }: Props) => { +const FeaturesCarousel = ({ data }: FeaturesCarouselProps) => { const [isDataChange, setIsDataChange] = useState(false); - const sliderRef = useRef(null); + const sliderRef = useRef(null); - const settings = { - dots: true, - dotsClass: 'slick-dots testid-dots-button', - arrows: false, - infinite: true, - speed: 500, - slidesToShow: 1, - slidesToScroll: 1, - beforeChange: (current: number) => { - if (current >= data.length) { - setIsDataChange(true); - } else { - setIsDataChange(false); - } - }, - onReInit: () => { - if (isDataChange) { - setTimeout(() => { - sliderRef?.current?.slickGoTo(0); - }, 200); - } - }, - }; + const FEATURES_CAROUSEL_SETTINGS = useMemo( + () => + ({ + dots: { + className: 'carousel-dots testid-dots-button', + }, + autoplay: true, + prefixCls: 'features-carousel', + infinite: true, + slidesToShow: 1, + slidesToScroll: 1, + beforeChange: (current: number) => { + if (current >= data.length) { + setIsDataChange(true); + } else { + setIsDataChange(false); + } + }, + onReInit: () => { + if (isDataChange) { + setTimeout(() => { + sliderRef?.current?.goTo(0); + }, 200); + } + }, + } as CarouselProps), + [sliderRef, setIsDataChange, data, isDataChange] + ); useEffect(() => { setIsDataChange(true); }, [data]); return ( - + {data.map((d) => (

{d.title}

@@ -89,7 +83,7 @@ const FeaturesCarousel = ({ data }: Props) => {
))} -
+ ); }; diff --git a/openmetadata-ui/src/main/resources/ui/src/constants/Login.constants.ts b/openmetadata-ui/src/main/resources/ui/src/constants/Login.constants.ts index 2cfb025cb9f..6dde88b363b 100644 --- a/openmetadata-ui/src/main/resources/ui/src/constants/Login.constants.ts +++ b/openmetadata-ui/src/main/resources/ui/src/constants/Login.constants.ts @@ -11,6 +11,7 @@ * limitations under the License. */ +import { CarouselProps } from 'antd'; import lineage from '../assets/img/lineage.png'; import screenShot2 from '../assets/img/screenShot1.png'; import screenShot1 from '../assets/img/screenShot2.png'; @@ -40,13 +41,12 @@ export const LOGIN_SLIDE = [ }, ]; -export const LOGIN_SLIDER_SETTINGS = { - arrows: false, +export const LOGIN_CAROUSEL_SETTINGS = { autoplay: true, - dots: true, - dotsClass: 'login-slider slick-dots', - infinite: true, + prefixCls: 'login-carousel', + dots: { + className: 'carousel-dots', + }, slidesToShow: 1, slidesToScroll: 1, - speed: 500, -}; +} as CarouselProps; diff --git a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json index 9ac9a9cf93d..353d899c4b8 100644 --- a/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json +++ b/openmetadata-ui/src/main/resources/ui/src/locale/languages/en-us.json @@ -302,7 +302,7 @@ "owner": "Owner", "owner-plural": "Owners", "page-views-by-data-asset-plural": "Page views by data assets", - "partitions": "Partitions", + "partition-plural": "Partitions", "passed": "Passed", "password": "Password", "password-not-match": "Password doesn't match", diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.test.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.test.tsx index 7060e568d8f..b6ad32e03d9 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.test.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.test.tsx @@ -12,43 +12,53 @@ */ import { act, render, screen } from '@testing-library/react'; -import React, { ReactNode } from 'react'; +import React from 'react'; import { MemoryRouter } from 'react-router-dom'; import { LOGIN_SLIDE } from '../../constants/Login.constants'; import LoginCarousel from './LoginCarousel'; -jest.mock('react-slick', () => { - return jest - .fn() - .mockImplementation(({ children }: { children: ReactNode }) => ( -
{children}
- )); -}); - -jest.mock('i18next', () => ({ - t: jest.fn().mockImplementation((key) => key), -})); - describe('Test LoginCarousel component', () => { - it('LoginCarousel component should render properly', async () => { + it('renders the carousel container', () => { + render(); + + expect(screen.getByTestId('carousel-container')).toBeInTheDocument(); + }); + + it('renders a carousel with the correct number of slides', async () => { await act(async () => { render(, { wrapper: MemoryRouter, }); }); - const reactSlick = await screen.findByTestId('react-slick'); - const carouselContainer = await screen.findByTestId('carousel-container'); - const sliderContainer = await screen.findAllByTestId('slider-container'); - const descriptions = await screen.findAllByTestId( - 'carousel-slide-description' + const sliderContainers = await screen.findAllByTestId('slider-container'); + + const slides = sliderContainers.map( + (slider) => slider.parentElement?.parentElement as HTMLElement ); - expect(reactSlick).toBeInTheDocument(); - expect(carouselContainer).toBeInTheDocument(); - expect(sliderContainer).toHaveLength(LOGIN_SLIDE.length); - expect(descriptions.map((d) => d.textContent)).toEqual( - LOGIN_SLIDE.map((d) => `message.${d.descriptionKey}`) + const slackList = slides.filter( + (slide) => !slide.classList.contains('slick-cloned') ); + + expect(slackList).toHaveLength(LOGIN_SLIDE.length); + }); + + it('renders the correct slide description for each slide', async () => { + await act(async () => { + render(, { + wrapper: MemoryRouter, + }); + }); + + const slideDescriptions = await screen.findAllByTestId( + 'carousel-slide-description' + ); + const descriptions = LOGIN_SLIDE.map((d) => `message.${d.descriptionKey}`); + slideDescriptions.forEach((description) => { + expect( + descriptions.includes(description.textContent as string) + ).toBeTruthy(); + }); }); }); diff --git a/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.tsx b/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.tsx index dbe52b1ba93..eb6aa4fd12a 100644 --- a/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.tsx +++ b/openmetadata-ui/src/main/resources/ui/src/pages/login/LoginCarousel.tsx @@ -11,19 +11,19 @@ * limitations under the License. */ +import { Carousel } from 'antd'; import { t } from 'i18next'; import { uniqueId } from 'lodash'; import React from 'react'; -import Slider from 'react-slick'; import { + LOGIN_CAROUSEL_SETTINGS, LOGIN_SLIDE, - LOGIN_SLIDER_SETTINGS, } from '../../constants/Login.constants'; const LoginCarousel = () => { return (
- + {LOGIN_SLIDE.map((data) => (
@@ -43,7 +43,7 @@ const LoginCarousel = () => {
))} -
+
); }; diff --git a/openmetadata-ui/src/main/resources/ui/yarn.lock b/openmetadata-ui/src/main/resources/ui/yarn.lock index d9a9fcc3db8..f7ce440b15d 100644 --- a/openmetadata-ui/src/main/resources/ui/yarn.lock +++ b/openmetadata-ui/src/main/resources/ui/yarn.lock @@ -3776,13 +3776,6 @@ "@types/history" "*" "@types/react" "*" -"@types/react-slick@^0.23.5": - version "0.23.5" - resolved "https://registry.yarnpkg.com/@types/react-slick/-/react-slick-0.23.5.tgz#e55fdc79bf19022ef77a6f22e9d64fd0f7463cc4" - integrity sha512-dQ/HwsLpnWXD5d+52WwXIQTfNCRpgd+0CKb+aA8g2CaIpA9T9COdjVYb9KI40Osb4rIgqR7u2AqtL2/HGbBMpg== - dependencies: - "@types/react" "*" - "@types/react-test-renderer@>=16.9.0", "@types/react-test-renderer@^17.0.0": version "17.0.1" resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b" @@ -6772,11 +6765,6 @@ enhanced-resolve@^5.9.2: graceful-fs "^4.2.4" tapable "^2.2.0" -enquire.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/enquire.js/-/enquire.js-2.1.6.tgz#3e8780c9b8b835084c3f60e166dbc3c2a3c89814" - integrity sha1-PoeAybi4NQhMP2DhZtvDwqPImBQ= - enquirer@^2.3.5, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -12248,17 +12236,6 @@ react-router@5.2.0: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-slick@^0.28.1: - version "0.28.1" - resolved "https://registry.yarnpkg.com/react-slick/-/react-slick-0.28.1.tgz#12c18d991b59432df9c3757ba540a227b3fb85b9" - integrity sha512-JwRQXoWGJRbUTE7eZI1rGIHaXX/4YuwX6gn7ulfvUZ4vFDVQAA25HcsHSYaUiRCduTr6rskyIuyPMpuG6bbluw== - dependencies: - classnames "^2.2.5" - enquire.js "^2.1.6" - json2mq "^0.2.0" - lodash.debounce "^4.0.8" - resize-observer-polyfill "^1.5.0" - react-smooth@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.1.tgz#74c7309916d6ccca182c4b30c8992f179e6c5a05" @@ -12671,7 +12648,7 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== -resize-observer-polyfill@^1.5.0, resize-observer-polyfill@^1.5.1: +resize-observer-polyfill@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==