diff --git a/superset-frontend/src/components/Pagination/Ellipsis.test.tsx b/superset-frontend/src/components/Pagination/Ellipsis.test.tsx new file mode 100644 index 000000000..430924e1b --- /dev/null +++ b/superset-frontend/src/components/Pagination/Ellipsis.test.tsx @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import { Ellipsis } from './Ellipsis'; + +test('Ellipsis - click when the button is enabled', () => { + const click = jest.fn(); + render(); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(1); +}); + +test('Ellipsis - click when the button is disabled', () => { + const click = jest.fn(); + render(); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(0); +}); diff --git a/superset-frontend/src/components/Pagination/Ellipsis.tsx b/superset-frontend/src/components/Pagination/Ellipsis.tsx new file mode 100644 index 000000000..59267025f --- /dev/null +++ b/superset-frontend/src/components/Pagination/Ellipsis.tsx @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import classNames from 'classnames'; +import { PaginationButtonProps } from './types'; + +export function Ellipsis({ disabled, onClick }: PaginationButtonProps) { + return ( +
  • + { + e.preventDefault(); + if (!disabled) onClick(e); + }} + > + … + +
  • + ); +} diff --git a/superset-frontend/src/components/Pagination/Item.test.tsx b/superset-frontend/src/components/Pagination/Item.test.tsx new file mode 100644 index 000000000..a94227671 --- /dev/null +++ b/superset-frontend/src/components/Pagination/Item.test.tsx @@ -0,0 +1,49 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import { Item } from './Item'; + +test('Item - click when the item is not active', () => { + const click = jest.fn(); + render( + +
    + , + ); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(1); + expect(screen.getByTestId('test')).toBeInTheDocument(); +}); + +test('Item - click when the item is active', () => { + const click = jest.fn(); + render( + +
    + , + ); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(0); + expect(screen.getByTestId('test')).toBeInTheDocument(); +}); diff --git a/superset-frontend/src/components/Pagination/Item.tsx b/superset-frontend/src/components/Pagination/Item.tsx new file mode 100644 index 000000000..78c5abcd2 --- /dev/null +++ b/superset-frontend/src/components/Pagination/Item.tsx @@ -0,0 +1,44 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import classNames from 'classnames'; +import { PaginationButtonProps } from './types'; + +interface PaginationItemButton extends PaginationButtonProps { + active?: boolean; + children: React.ReactNode; +} + +export function Item({ active, children, onClick }: PaginationItemButton) { + return ( +
  • + { + e.preventDefault(); + if (!active) onClick(e); + }} + > + {children} + +
  • + ); +} diff --git a/superset-frontend/src/components/Pagination/Next.test.tsx b/superset-frontend/src/components/Pagination/Next.test.tsx new file mode 100644 index 000000000..9daddec0d --- /dev/null +++ b/superset-frontend/src/components/Pagination/Next.test.tsx @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import { Next } from './Next'; + +test('Next - click when the button is enabled', () => { + const click = jest.fn(); + render(); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(1); +}); + +test('Next - click when the button is disabled', () => { + const click = jest.fn(); + render(); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(0); +}); diff --git a/superset-frontend/src/components/Pagination/Next.tsx b/superset-frontend/src/components/Pagination/Next.tsx new file mode 100644 index 000000000..838f38aa3 --- /dev/null +++ b/superset-frontend/src/components/Pagination/Next.tsx @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import classNames from 'classnames'; +import { PaginationButtonProps } from './types'; + +export function Next({ disabled, onClick }: PaginationButtonProps) { + return ( +
  • + { + e.preventDefault(); + if (!disabled) onClick(e); + }} + > + » + +
  • + ); +} diff --git a/superset-frontend/src/components/Pagination/Pagination.test.tsx b/superset-frontend/src/components/Pagination/Pagination.test.tsx new file mode 100644 index 000000000..192d4de3f --- /dev/null +++ b/superset-frontend/src/components/Pagination/Pagination.test.tsx @@ -0,0 +1,69 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import Pagination from '.'; + +jest.mock('./Next', () => ({ + Next: () =>
    , +})); +jest.mock('./Prev', () => ({ + Prev: () =>
    , +})); +jest.mock('./Item', () => ({ + Item: () =>
    , +})); +jest.mock('./Ellipsis', () => ({ + Ellipsis: () =>
    , +})); + +test('Pagination rendering correctly', () => { + render( + +
  • + , + ); + expect(screen.getByRole('navigation')).toBeInTheDocument(); + expect(screen.getByTestId('test')).toBeInTheDocument(); +}); + +test('Next attribute', () => { + render(); + expect(screen.getByTestId('next')).toBeInTheDocument(); +}); + +test('Prev attribute', () => { + render(); + expect(screen.getByTestId('next')).toBeInTheDocument(); +}); + +test('Item attribute', () => { + render( + + <> + , + ); + expect(screen.getByTestId('item')).toBeInTheDocument(); +}); + +test('Ellipsis attribute', () => { + render(); + expect(screen.getByTestId('ellipsis')).toBeInTheDocument(); +}); diff --git a/superset-frontend/src/components/Pagination/Prev.test.tsx b/superset-frontend/src/components/Pagination/Prev.test.tsx new file mode 100644 index 000000000..924a9e997 --- /dev/null +++ b/superset-frontend/src/components/Pagination/Prev.test.tsx @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import { render, screen } from 'spec/helpers/testing-library'; +import userEvent from '@testing-library/user-event'; +import { Prev } from './Prev'; + +test('Prev - click when the button is enabled', () => { + const click = jest.fn(); + render(); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(1); +}); + +test('Prev - click when the button is disabled', () => { + const click = jest.fn(); + render(); + expect(click).toBeCalledTimes(0); + userEvent.click(screen.getByRole('button')); + expect(click).toBeCalledTimes(0); +}); diff --git a/superset-frontend/src/components/Pagination/Prev.tsx b/superset-frontend/src/components/Pagination/Prev.tsx new file mode 100644 index 000000000..678b49323 --- /dev/null +++ b/superset-frontend/src/components/Pagination/Prev.tsx @@ -0,0 +1,39 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import React from 'react'; +import classNames from 'classnames'; +import { PaginationButtonProps } from './types'; + +export function Prev({ disabled, onClick }: PaginationButtonProps) { + return ( +
  • + { + e.preventDefault(); + if (!disabled) onClick(e); + }} + > + « + +
  • + ); +} diff --git a/superset-frontend/src/components/Pagination.tsx b/superset-frontend/src/components/Pagination/index.tsx similarity index 55% rename from superset-frontend/src/components/Pagination.tsx rename to superset-frontend/src/components/Pagination/index.tsx index 6a9a7466c..cff503da0 100644 --- a/superset-frontend/src/components/Pagination.tsx +++ b/superset-frontend/src/components/Pagination/index.tsx @@ -16,62 +16,16 @@ * specific language governing permissions and limitations * under the License. */ -import React, { PureComponent } from 'react'; -import cx from 'classnames'; + +import React from 'react'; import { styled } from '@superset-ui/core'; - -interface PaginationButton { - disabled?: boolean; - onClick: React.EventHandler>; -} - -interface PaginationItemButton extends PaginationButton { - active: boolean; - children: React.ReactNode; -} - -function Prev({ disabled, onClick }: PaginationButton) { - return ( -
  • - - « - -
  • - ); -} - -function Next({ disabled, onClick }: PaginationButton) { - return ( -
  • - - » - -
  • - ); -} - -function Item({ active, children, onClick }: PaginationItemButton) { - return ( -
  • - - {children} - -
  • - ); -} - -function Ellipsis({ disabled, onClick }: PaginationButton) { - return ( -
  • - - … - -
  • - ); -} +import { Next } from './Next'; +import { Prev } from './Prev'; +import { Item } from './Item'; +import { Ellipsis } from './Ellipsis'; interface PaginationProps { - children: React.ReactNode; + children: JSX.Element | JSX.Element[]; } const PaginationList = styled.ul` @@ -122,16 +76,13 @@ const PaginationList = styled.ul` } `; -export default class Pagination extends PureComponent { - static Next = Next; - - static Prev = Prev; - - static Item = Item; - - static Ellipsis = Ellipsis; - - render() { - return {this.props.children}; - } +function Pagination({ children }: PaginationProps) { + return {children}; } + +Pagination.Next = Next; +Pagination.Prev = Prev; +Pagination.Item = Item; +Pagination.Ellipsis = Ellipsis; + +export default Pagination; diff --git a/superset-frontend/src/components/Pagination/types.ts b/superset-frontend/src/components/Pagination/types.ts new file mode 100644 index 000000000..fb9c97ba0 --- /dev/null +++ b/superset-frontend/src/components/Pagination/types.ts @@ -0,0 +1,23 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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 interface PaginationButtonProps { + disabled?: boolean; + onClick: React.EventHandler>; +}