/* eslint-disable react/destructuring-assignment */ /* eslint-disable react/prop-types */ import React, { useContext, useEffect, useRef, useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { WaxContext } from 'wax-prosemirror-core'; import { Icon } from 'wax-prosemirror-components'; import { DocumentHelpers } from 'wax-prosemirror-utilities'; import styled from 'styled-components'; import FeedbackComponent from './FeedbackComponent'; import ContainerEditor from './ContainerEditor'; const MatchingWrapper = styled.div` display: flex; flex-direction: column; margin: 0px 38px 15px 38px; margin-top: 10px; `; const MatchingContainer = styled.div` border: 3px solid #f5f5f7; margin-bottom: 30px; padding: 10px; `; const QuestionWrapper = styled.div` display: flex; flex-direction: row; width: 100%; `; const ActionButton = styled.button` background: transparent; border: none; cursor: pointer; height: 24px; padding-left: 0; `; const StyledIconAction = styled(Icon)` height: 24px; width: 24px; `; const CreateOptions = styled.div` display: flex; flex-direction: column; padding-bottom: 10px; `; const OptionArea = styled.div` display: flex; width: 100%; ul { display: flex; flex-direction: row; flex-wrap: wrap; margin: 0; padding: 0; li { list-style-type: none; padding-bottom: 7px; padding-right: 7px; span { background: #535e76; border-radius: 12px; color: white; padding: 3px 3px 3px 10px; } svg { fill: white; height: 16px; width: 16px; } } } `; const AddOption = styled.div` display: flex; input { border: none; border-bottom: 1px solid black; &:focus { outline: none; } ::placeholder { color: rgb(170, 170, 170); font-style: italic; } } button { background: #fff; border: 1px solid #535e76; color: #535e76; cursor: pointer; margin-left: 20px; padding: 4px 8px 4px 8px; &:hover { background: #535e76; border: 1px solid #535e76; color: #fff; cursor: pointer; margin-right: 20px; padding: 4px 8px 4px 8px; } } `; export default ({ node, view, getPos }) => { const context = useContext(WaxContext); const { pmViews: { main }, } = context; const [options, setOptions] = useState(node.attrs.options); const [optionText, setOptionText] = useState(''); const [addingOption, setAddingOption] = useState(false); const addOptionRef = useRef(null); const customProps = main.props.customValues; const isEditable = main.props.editable(editable => { return editable; }); const readOnly = !isEditable; useEffect(() => { const allNodes = getNodes(main); /* TEMP TO SAVE NODE OPTIONS TODO: SAVE IN CONTEXT OPTIONS */ saveInChildOptions(allNodes); if (!addingOption) return; allNodes.forEach(singleNode => { if (singleNode.node.attrs.id === node.attrs.id) { main.dispatch( main.state.tr .setMeta('addToHistory', false) .setNodeMarkup(getPos(), undefined, { ...singleNode.node.attrs, options, }), ); } }); }, [options, JSON.stringify(context.pmViews.main.state)]); const addOption = () => { if (addOptionRef.current.value.trim() === '') return; const obj = { label: addOptionRef.current.value, value: uuidv4() }; setOptions(prevOptions => [...prevOptions, obj]); setAddingOption(true); setTimeout(() => { setAddingOption(false); }); setOptionText(''); addOptionRef.current.focus(); }; const updateOptionText = () => { setOptionText(addOptionRef.current.value); }; const handleKeyDown = event => { if (event.key === 'Enter' || event.which === 13) { addOption(); } }; const removeOption = value => { setOptions(options.filter(option => option.value !== value)); setAddingOption(true); setTimeout(() => { setAddingOption(false); }); }; const saveInChildOptions = allNodes => { allNodes.forEach(singleNode => { if (singleNode.node.attrs.id === node.attrs.id) { singleNode.node.content.content.forEach(parentNodes => { parentNodes.forEach(optionNode => { if (optionNode.type.name === 'matching_option') /* eslint-disable-next-line no-param-reassign */ optionNode.attrs.options = options; }); }); } }); }; const { testMode } = customProps; return ( <MatchingWrapper> <span>Matching</span> <MatchingContainer className="matching"> <QuestionWrapper> <ContainerEditor getPos={getPos} node={node} view={view} /> </QuestionWrapper> {(!readOnly || (readOnly && !customProps.testMode && !customProps.showFeedBack)) && ( <CreateOptions> <OptionArea> {options.length > 0 && ( <ul> <li>Options: </li> {options.map((option, index) => { return ( <li key={option.value}> <span> {option.label} {!readOnly && ( <ActionButton onClick={() => removeOption(option.value)} type="button" > <StyledIconAction name="deleteOutlined" /> </ActionButton> )} </span> </li> ); })} </ul> )} </OptionArea> {!readOnly && ( <AddOption> <input onChange={updateOptionText} onKeyPress={handleKeyDown} placeholder="Type an option ..." ref={addOptionRef} type="text" value={optionText} /> <button onClick={addOption} type="button"> Add Option </button> </AddOption> )} </CreateOptions> )} {!testMode && ( <FeedbackComponent getPos={getPos} node={node} readOnly={readOnly} view={view} /> )} </MatchingContainer> </MatchingWrapper> ); }; const getNodes = view => { const allNodes = DocumentHelpers.findBlockNodes(view.state.doc); const matchingContainerNodes = []; allNodes.forEach(node => { if (node.node.type.name === 'matching_container') { matchingContainerNodes.push(node); } }); return matchingContainerNodes; };