UNPKG

@instructure/canvas-rce

Version:

A component wrapping Canvas's usage of Tinymce

154 lines (152 loc) 5.5 kB
import _pt from "prop-types"; /* * Copyright (C) 2024 - 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, { useState } from 'react'; import { Flex } from '@instructure/ui-flex'; import ErrorBoundary from '../ErrorBoundary'; import { useFilterSettings } from '../useFilterSettings'; import PanelFilter from './PanelFilter'; import { FILTER_SETTINGS_BY_PLUGIN, DynamicPanel } from '../canvasContentUtils'; import { useStoreProps } from '../StoreContext'; // TODO: Component is only validated for images, need to validate for other content types export default function CanvasContentPanel({ trayProps, canvasOrigin, plugin, setFileUrl }) { const [filterSettings, setFilterSettings] = useFilterSettings(FILTER_SETTINGS_BY_PLUGIN[plugin]); const [link, setLink] = useState(null); const [hasLoaded, setHasLoaded] = useState(false); // storeProps has functions that collide with what we want to do in a block editor setting const baseStoreProps = useStoreProps(); const { onImageEmbed: _, onMediaEmbed: _m, ...storeProps } = baseStoreProps; function handleFilterChange(newFilter, onChangeContext, onChangeSearchString, onChangeSortBy) { const newFilterSettings = { ...newFilter }; if (newFilterSettings.sortValue) { newFilterSettings.sortDir = newFilterSettings.sortValue === 'alphabetical' ? 'asc' : 'desc'; onChangeSortBy({ sort: newFilterSettings.sortValue, dir: newFilterSettings.sortDir }); } if ('searchString' in newFilterSettings && filterSettings.searchString !== newFilterSettings.searchString) { onChangeSearchString(newFilterSettings.searchString); } setFilterSettings(newFilterSettings); if (newFilterSettings.contentType) { let contextType, contextId; switch (newFilterSettings.contentType) { case 'user_files': contextType = 'user'; contextId = trayProps.containingContext.userId; break; case 'group_files': contextType = 'group'; contextId = trayProps.containingContext.contextId; break; case 'course_files': contextType = trayProps.contextType; contextId = trayProps.containingContext.contextId; break; case 'links': contextType = trayProps.containingContext.contextType; contextId = trayProps.containingContext.contextId; } onChangeContext({ contextType, contextId }); // context is only changed on load setHasLoaded(true); } } const handleImageClick = image => { setFileUrl(image.href); }; const handleMediaClick = media => { setFileUrl(`/media_attachments_iframe/${media.id}`); }; return /*#__PURE__*/React.createElement(Flex, { as: "div", direction: "column", tabIndex: -1 }, /*#__PURE__*/React.createElement(Flex.Item, { padding: "medium" }, /*#__PURE__*/React.createElement(PanelFilter, Object.assign({}, filterSettings, { onChange: newFilter => { handleFilterChange(newFilter, storeProps.onChangeContext, storeProps.onChangeSearchString, storeProps.onChangeSortBy); } }))), /*#__PURE__*/React.createElement(Flex.Item, { shouldGrow: true, shouldShrink: true, margin: "xx-small xxx-small 0" }, hasLoaded && /*#__PURE__*/React.createElement(Flex, { justifyItems: "space-between", direction: "column", height: "100%" }, /*#__PURE__*/React.createElement(Flex.Item, { shouldGrow: true, shouldShrink: true }, /*#__PURE__*/React.createElement(ErrorBoundary, null, /*#__PURE__*/React.createElement(DynamicPanel, Object.assign({ contentType: filterSettings.contentType, contentSubtype: filterSettings.contentSubtype, sortBy: { sort: filterSettings.sortValue, order: filterSettings.sortDir }, searchString: filterSettings.searchString, canvasOrigin: canvasOrigin, context: { type: trayProps.contextType, id: trayProps.contextId }, editing: false, onEditClick: setLink, selectedLink: link, onImageEmbed: handleImageClick, onMediaEmbed: handleMediaClick }, storeProps))))))); } CanvasContentPanel.propTypes = { trayProps: _pt.shape({ canUploadFiles: _pt.bool.isRequired, contextId: _pt.string.isRequired, contextType: _pt.string.isRequired, containingContext: _pt.shape({ contextType: _pt.string.isRequired, contextId: _pt.string.isRequired, userId: _pt.string.isRequired }).isRequired, filesTabDisabled: _pt.bool.isRequired, host: _pt.string.isRequired, jwt: _pt.string.isRequired, source: _pt.shape({}).isRequired, themeUrl: _pt.string.isRequired, storeProps: _pt.any.isRequired }).isRequired, canvasOrigin: _pt.string.isRequired, plugin: _pt.any.isRequired, setFileUrl: _pt.func.isRequired };