/*! * Copyright (c) 2024 PLANKA Software GmbH * Licensed under the Fair Use License: https://github.com/plankanban/planka/blob/master/LICENSE.md */ import React, { useCallback, useState } from 'react'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import { shallowEqual, useSelector } from 'react-redux'; import { useInView } from 'react-intersection-observer'; import { useTranslation } from 'react-i18next'; import { Button, Icon, Loader } from 'semantic-ui-react'; import { Tooltip } from '../../../lib/custom-ui'; import selectors from '../../../selectors'; import { BoardMembershipRoles } from '../../../constants/Enums'; import Card from '../../cards/Card'; import AddCard from '../../cards/AddCard'; import PlusMathIcon from '../../../assets/images/plus-math-icon.svg?react'; import styles from './ListView.module.scss'; const ListView = React.memo( ({ cardIds, isCardsFetching, isAllCardsFetched, onCardsFetch, onCardCreate, onCardPaste }) => { const clipboard = useSelector(selectors.selectClipboard); const { canAddCard, canPasteCard } = useSelector((state) => { const boardMembership = selectors.selectCurrentUserMembershipForCurrentBoard(state); const isEditor = !!boardMembership && boardMembership.role === BoardMembershipRoles.EDITOR; return { canAddCard: isEditor, canPasteCard: isEditor, }; }, shallowEqual); const [t] = useTranslation(); const [isAddCardOpened, setIsAddCardOpened] = useState(false); const [inViewRef] = useInView({ threshold: 1, onChange: (inView) => { if (inView && onCardsFetch) { onCardsFetch(); } }, }); const handleAddCardClick = useCallback(() => { setIsAddCardOpened(true); }, []); const handleAddCardClose = useCallback(() => { setIsAddCardOpened(false); }, []); return (