import React from 'react'; import PropTypes from 'prop-types'; import {connect} from 'react-redux'; import {EditorState} from 'draft-js'; import {getSelectedEntity} from './entityUtils'; import {Dropdown, NavTabs} from 'core/ui/components'; import {AttachmentList} from './AttachmentList'; import {applyLink, hidePopups, createLinkSuggestion, changeLinkSuggestion} from '../../actions'; import {connectPromiseResults} from 'core/helpers/ReactRenderAsync'; import ng from 'core/services/ng'; import {gettext} from 'core/utils'; /** * @ngdoc React * @module superdesk.core.editor3 * @name LinkInput * @param {Object} editorState The editor state object. * @param {string} data The default value for the input. * @description This components holds the input form for entering a new URL. */ const linkTypes = { href: 'href', attachement: 'attachement', }; export class LinkInputComponent extends React.Component { static propTypes: any; static defaultProps: any; entity: any; tabs: any; activeTab: any; inputElement: any; constructor(props) { super(props); // when non-null, holds the entity whos URL is being edited this.entity = null; this.tabs = [ {label: gettext('URL'), render: this.renderURL.bind(this)}, ]; if (props.item) { this.tabs.push( {label: gettext('Attachment'), render: this.renderAttachment.bind(this)}, ); } this.activeTab = 0; let selectedAttachment; if (props.data) { // if a value has been passed, it is safe to assume that it // is coming from the currently selected entity this.entity = getSelectedEntity(props.editorState); if (props.data.attachment) { this.activeTab = 1; selectedAttachment = props.data.attachment; } } const initialValue = 'https://'; this.state = { url: this.props.data ? this.props.data.href || initialValue : initialValue, selected: selectedAttachment, }; this.onSubmit = this.onSubmit.bind(this); this.onKeyUp = this.onKeyUp.bind(this); this.selectAttachment = this.selectAttachment.bind(this); } /** * @ngdoc method * @name LinkInput#onSubmit * @description Callback when submitting the form. */ onSubmit(linkType) { let link; const {suggestingMode, localDomains} = this.props; const _createLinkSuggestion = this.props.createLinkSuggestion; const _applyLink = this.props.applyLink; const _changeLinkSuggestion = this.props.changeLinkSuggestion; if (linkType === linkTypes.href) { const url = this.state.url; const isLocalDomain = (localDomains || []).some((item) => url.includes(item.domain)); link = {href: url}; if (!isLocalDomain && localDomains != null) { link.target = '_blank'; } } else if (linkType === linkTypes.attachement) { link = {attachment: this.state.selected}; } else { throw new Error('link type not recognized'); } if (!link.href && !link.attachment) { return; } if (suggestingMode) { if (this.entity) { _changeLinkSuggestion(link, this.entity); } else { _createLinkSuggestion(link); } } else { _applyLink(link, this.entity); } this.props.hidePopups(); } /** * @ngdoc method * @name LinkInput#onKeyUp * @description Handles key up events in the editor. Cancells input when * Esc is pressed. */ onKeyUp(e) { if (e.key === 'Escape') { this.props.hidePopups(); } } componentDidMount() { if (this.inputElement != null) { this.inputElement.focus(); const savedValue = this.inputElement.value; // re-apply the value so cursor is at the end, not the start // related https://stackoverflow.com/q/511088/1175593 this.inputElement.value = ''; this.inputElement.value = savedValue; } } selectAttachment(file) { this.setState({selected: file._id}); } render() { return ( ); } renderURL() { return (
{ this.onSubmit(linkTypes.href); }} className="link-input" onKeyUp={this.onKeyUp} >
{ this.inputElement = el; }} className="sd-line-input__input" value={this.state.url} onChange={(e) => { this.setState({url: e.target.value}); }} placeholder={gettext('Insert URL')} />
); } renderAttachment() { return (
); } } LinkInputComponent.propTypes = { editorState: PropTypes.instanceOf(EditorState).isRequired, applyLink: PropTypes.func.isRequired, hidePopups: PropTypes.func.isRequired, data: PropTypes.object, item: PropTypes.object, suggestingMode: PropTypes.bool, createLinkSuggestion: PropTypes.func, changeLinkSuggestion: PropTypes.func, localDomains: PropTypes.array, }; const mapStateToProps = (state) => ({ item: state.item, editorState: state.editorState, suggestingMode: state.suggestingMode, }); const LinkInputComponentWithDependenciesLoaded = connectPromiseResults(() => ({ localDomains: ng.get('metadata').initialize() .then(() => ng.get('metadata').values.local_domains), }))(LinkInputComponent); export const LinkInput: any = connect(mapStateToProps, { applyLink, hidePopups, createLinkSuggestion, changeLinkSuggestion, })(LinkInputComponentWithDependenciesLoaded);