UNPKG

@instructure/canvas-rce

Version:

A component wrapping Canvas's usage of Tinymce

112 lines (111 loc) 3.6 kB
/* * Copyright (C) 2019 - present Instructure, Inc. * * This file is part of Canvas. * * Canvas is free software: you can redistribute it and/or modify it under * the terms of the GNU Affero General Public License as published by the Free * Software Foundation, version 3 of the License. * * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more * details. * * You should have received a copy of the GNU Affero General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ import React, { useRef } from 'react'; import { func, shape, string, oneOf } from 'prop-types'; import { contentTrayDocumentShape } from '../../shared/fileShape'; import formatMessage from '../../../../format-message'; import { Text } from '@instructure/ui-text'; import { View } from '@instructure/ui-view'; import Link from './Link'; import { LoadMoreButton, LoadingIndicator, LoadingStatus, useIncrementalLoading } from '../../../../common/incremental-loading'; function hasFiles(documents) { return documents.files.length > 0; } function isEmpty(documents) { return !hasFiles(documents) && !documents.hasMore && !documents.isLoading; } function renderLinks(files, handleClick, lastItemRef) { return files.map((f, index) => { let focusRef = null; if (index === files.length - 1) { focusRef = lastItemRef; } return /*#__PURE__*/React.createElement(Link, Object.assign({ key: f.id }, f, { onClick: handleClick, focusRef: focusRef })); }); } function renderLoadingError(_error) { return /*#__PURE__*/React.createElement(View, { as: "div", role: "alert", margin: "medium" }, /*#__PURE__*/React.createElement(Text, { color: "danger" }, formatMessage('Loading failed.'))); } export default function DocumentsPanel(props) { const { fetchInitialDocs, fetchNextDocs, contextType, sortBy, searchString } = props; const documents = props.documents[contextType]; const { hasMore, isLoading, error, files } = documents; const lastItemRef = useRef(null); const loader = useIncrementalLoading({ hasMore, isLoading, lastItemRef, onLoadInitial: fetchInitialDocs, onLoadMore: fetchNextDocs, records: files, contextType, sortBy, searchString }); const handleDocClick = file => { props.onLinkClick(file); }; return /*#__PURE__*/React.createElement(View, { as: "div", "data-testid": "instructure_links-DocumentsPanel" }, renderLinks(files, handleDocClick, lastItemRef), loader.isLoading && /*#__PURE__*/React.createElement(LoadingIndicator, { loader: loader }), !loader.isLoading && loader.hasMore && /*#__PURE__*/React.createElement(LoadMoreButton, { loader: loader }), /*#__PURE__*/React.createElement(LoadingStatus, { loader: loader }), error && renderLoadingError(error), isEmpty(documents) && /*#__PURE__*/React.createElement(View, { as: "div", role: "alert", padding: "medium" }, formatMessage('No results.'))); } DocumentsPanel.propTypes = { contextType: string.isRequired, fetchInitialDocs: func.isRequired, fetchNextDocs: func.isRequired, onLinkClick: func.isRequired, documents: contentTrayDocumentShape.isRequired, sortBy: shape({ sort: oneOf(['date_added', 'alphabetical']).isRequired, order: oneOf(['asc', 'desc']).isRequired }).isRequired, searchString: string };