diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/CustomSectionList/AddQuestionModal.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/CustomSectionList/AddQuestionModal.js deleted file mode 100644 index 542da8f5f..000000000 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/CustomSectionList/AddQuestionModal.js +++ /dev/null @@ -1,430 +0,0 @@ -import React, { useState, useCallback, useEffect } from 'react' - -import { isEmpty } from 'lodash-es' - -import { makeStyles } from '@material-ui/core/styles' -import { - Box, - Typography, - Dialog, - DialogTitle, - DialogContent, - DialogActions, -} from '@material-ui/core' - -import Dropdown from '../../submission/components/section/Dropdown' -import Switch from '../../../../../../../components/generic/Switch' -import TextInput from '../../submission/components/inputs/TextInput' -import Button from 'components/generic/Button' -import Checkbox from '../../submission/components/section/Checkbox' -import EditableOptions from '../../submission/components/EditableOptions' -import { generateSlug } from 'utils/dataModifiers' - -const initialData = { - label: '', - hint: '', - settings: { - options: [], - }, - fieldRequired: false, - fieldType: 'text', -} - -const useStyles = makeStyles(theme => ({ - label: { - fontWeight: 'bold', - }, -})) - -export default ({ - initialValue = initialData, - sectionName, - visible, - onVisibleChange, - reservedNames, - onSubmit, - onEditDone, - onEditCancel, - editing, -}) => { - const classes = useStyles() - const [data, setData] = useState(initialValue) - - useEffect(() => { - if (editing) { - setData(editing) - } - }, [editing]) - - const reset = () => { - setData(initialData) - } - - const validate = () => { - // ! This only apply to the submission form, not the registration form - if (data.fieldType === 'attachment') { - if ( - data.settings.maxSize === undefined || - data.settings.maxSize === null - ) { - return 'Max size is required for attachment type' - } - - if (typeof data.settings.maxSize !== 'number') { - return 'Max size must be a number' - } - - if (!Number.isInteger(data.settings.maxSize)) { - return 'Max size must be an integer' - } - - if (data.settings.maxSize <= 0) { - return 'Max size must be greater than 0' - } - if (data.settings.maxSize > 100) { - return 'Max size must be less than 100' - } - } - // ! ---------------------------------------------------------------- - if (isEmpty(data.label)) { - return 'Label is required' - } - - if (data.label.length > 100) { - return 'Label can be at most 100 characters' - } - - if (isEmpty(data.fieldType)) { - return 'Please choose a question type' - } - - if (!/^[a-z-]*$/.test(data.name)) { - return 'Machine name can only contain lowercase characters and dashes (-)' - } - - if (!editing) { - if (reservedNames.indexOf(data.name) !== -1) { - return `This section already contains a question with the machine name ${data.name}, please use something else` - } - } - - return - } - - const handleAdd = () => { - const error = validate() - if (error) { - window.alert(error) - } else { - onSubmit(data) - onVisibleChange(false) - } - reset() - } - - const handleEdit = () => { - const error = validate() - if (error) { - window.alert(error) - } else { - onEditDone(data) - } - } - - const handleCancel = () => { - if (editing) { - onEditCancel() - } else { - onVisibleChange(false) - } - reset() - } - - const handleChange = useCallback( - (field, value) => { - const newData = { ...data } - - if (field === 'label' && !editing) { - newData.name = generateSlug(value, 'v') - } - - setData({ - ...newData, - [field]: value, - }) - }, - [data], - ) - - const renderPlaceholderInput = () => { - return ( - <> - - Placeholder - - handleChange('placeholder', value)} - /> - - Text to show in the field if it's empty - - - ) - } - - const renderFieldTypeOptions = () => { - switch (data.fieldType) { - case 'multiple-choice': - case 'single-choice': { - return ( - <> - - Options to choose from - - - handleChange('settings', { - ...data.settings, - options: [...data.settings.options, value], - }) - } - handleEdit={(index, value) => { - const updatedOptions = [ - ...data.settings.options, - ] - updatedOptions[index] = value - handleChange('settings', { - ...data.settings, - options: updatedOptions, - }) - }} - handleDelete={index => { - const updatedOptions = [ - ...data.settings.options, - ] - updatedOptions.splice(index, 1) - handleChange('settings', { - ...data.settings, - options: updatedOptions, - }) - }} - /> - - Enter options to choose - - {renderPlaceholderInput()} - - ) - } - case 'checkbox': - case 'boolean': { - return ( - <> - - Default value - - - handleChange('settings', { - ...data.settings, - default: value, - }) - } - checkedText="Yes" - uncheckedText="No" - /> - - Is this field checked/yes by default? - - - ) - } - - // ! This only apply to the submission form, not the registration form - case 'attachment': { - return ( - <> - {/* - Maximum file size - - - handleChange('settings', { - ...data.settings, - maxSize: parseInt(value, 10), // parse value to integer - }) - } - width="tw-w-1/4" - /> - - Maximum file size in megabytes - - - Allowed file types - - - handleChange('settings', { - ...data.settings, - allowedTypes: value, - }) - } - /> - - Allowed file types, select multiple options - */} - - ) - } - // ! ---------------------------------------------------------------- - case 'Link': { - return ( - <> - - Link - - - handleChange('placeholder', value) - } - /> - - Enter the link - - - ) - } - default: - return renderPlaceholderInput() - } - } - - return ( - - - {editing - ? `Edit ${data.label}` - : `Add a new question under ${sectionName}`} - - - - Label - - handleChange('label', value)} - /> -
- - Question type: - - handleChange('fieldType', value)} - placeholder="Choose one" - options={[ - { - value: 'text', - label: 'Short text', - }, - { - value: 'textarea', - label: 'Long text', - }, - { - value: 'link', - label: 'Link', - }, - // { - // value: 'attachment', - // label: 'Attachment', - // }, - { - value: 'boolean', - label: 'Yes / No', - }, - { - value: 'single-choice', - label: 'Single choice', - }, - { - value: 'multiple-choice', - label: 'Multiple choice', - }, - ]} - /> -
- - Choose question type to put in the submission form - - {renderFieldTypeOptions()} - - Hint - - handleChange('hint', value)} - /> - - Add an optional help text to show under the question label - - just like the one you're reading right now - -
- - Required? - - handleChange('fieldRequired', value)} - checkedText="Yes" - uncheckedText="No" - /> -
- - - Users will not be able to submit the form without answering - this question, if it is required. - -
- - - - - -
- ) -} diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/CustomSectionList/AddSectionModal.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/CustomSectionList/AddSectionModal.js deleted file mode 100644 index 5643bfe01..000000000 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/CustomSectionList/AddSectionModal.js +++ /dev/null @@ -1,233 +0,0 @@ -import React, { useState, useCallback, useEffect } from 'react' - -import { - Box, - Typography, - Dialog, - DialogTitle, - DialogContent, - DialogActions, - FormControlLabel, - Switch, -} from '@material-ui/core' -import { makeStyles } from '@material-ui/core/styles' -import MarkdownInput from 'components/inputs/MarkdownInput' -import Button from 'components/generic/Button' -import TextInput from 'components/inputs/TextInput' -import { generateSlug } from 'utils/dataModifiers' - -const useStyles = makeStyles(theme => ({ - label: { - fontWeight: 'bold', - }, -})) - -export default ({ - visible, - onVisibleChange, - onSubmit, - onEditDone, - onEditCancel, - editing, - reservedNames, -}) => { - const classes = useStyles() - const [data, setData] = useState({}) - const [isConditional, setIsConditional] = useState(false) - - useEffect(() => { - if (editing) { - setData(editing) - - setIsConditional(!!editing.conditional) // This prevents the conditional question from toggle to always visible - } - }, [editing]) - - const reset = () => { - setData({}) - - // this prevent the conditional to be reset after saving section or editing - if (!editing) { - setIsConditional(false) - } - } - - const validate = () => { - if (!data.label) { - return 'Please give your section a title' - } - - if (!data.name) { - return 'Please give your section a machine name' - } - - if (!/^[a-z-]*$/.test(data.name)) { - return 'Machine name can only contain lowercase characters and dashes (-)' - } - - if (!editing) { - if (reservedNames.indexOf(data.name) !== -1) { - return `The machine-name ${data.name} is already taken, please use something else` - } - } - - if (isConditional && !data.conditional) { - return 'Please give your section a conditional question, or set it to always visible' - } - } - - const handleAdd = () => { - console.log('After handling add:', data) - const error = validate() - if (error) { - window.alert(error) - } else { - onSubmit({ - ...data, - conditional: isConditional ? data.conditional : undefined, - }) - onVisibleChange(false) - reset() - } - } - - const handleEdit = () => { - const error = validate() - if (error) { - window.alert(error) - } else { - onEditDone({ - ...data, - conditional: isConditional ? data.conditional : undefined, - }) - reset() - } - } - - const handleCancel = () => { - if (editing) { - onEditCancel() - } else { - onVisibleChange(false) - } - } - - const handleChange = useCallback( - (field, value) => { - const newData = { ...data } - - if (field === 'label' && !editing) { - newData.name = generateSlug(value, 's') - } - - setData({ - ...newData, - [field]: value, - }) - }, - [data], - ) - - return ( - - - {editing ? `Edit ${editing.label}` : 'Add a new section'} - - - - Section title - - handleChange('label', value)} - /> - {/* - The displayed name of your section - - - Machine name - - handleChange('name', value)} - /> */} - - A machine-readable name for the section - - - - Description - - handleChange('description', value)} - /> - - - Conditional question - - - - Off: The section will always be visible
- On: The - section will only be visible when the conditional question - is answered with yes/no -
- - setIsConditional(value)} - color="primary" - /> - } - label="Is this a conditional field?" - /> - - {isConditional && ( - <> - - - Conditional question - - - Type here your yes/no question. If yes, the section - question will be shown - - - handleChange('conditional', value) - } - /> - - )} -
- - - - - -
- ) -} diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/index.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/index.js index 60c91068a..57b120099 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/index.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/questions/index.js @@ -8,66 +8,6 @@ import FormControl from 'components/inputs/FormControl' import QuestionSelect from './QuestionSelect' export default () => { - // const buildColumns = useCallback((form, field, fieldValue) => { - // return [ - // { - // Header: 'Name', - // accessor: 'label', - // }, - // { - // Header: 'Category', - // accessor: 'category', - // }, - // { - // Header: 'Enabled?', - // accessor: 'enabled', - // Cell: props => { - // const row = props.row.original - // return ( - // { - // form.setFieldValue(field.name, { - // ...fieldValue, - // [row.key]: { - // ...fieldValue[row.key], - // enable, - // require: !enable ? false : row.require, - // }, - // }) - // }} - // /> - // ) - // }, - // }, - // { - // Header: 'Required?', - // accessor: 'require', - // Cell: props => { - // const row = props.row.original - // return ( - // { - // form.setFieldValue(field.name, { - // ...fieldValue, - // [row.key]: { - // ...fieldValue[row.key], - // require, - // }, - // }) - // }} - // /> - // ) - // }, - // }, - // ] - // }, []) - return ( diff --git a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/submission/components/section/EditableText.js b/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/submission/components/section/EditableText.js index bec009ccc..c625e521f 100644 --- a/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/submission/components/section/EditableText.js +++ b/frontend/src/pages/_dashboard/renderDashboard/organiser/edit/submission/components/section/EditableText.js @@ -1,4 +1,4 @@ -import React from 'react' +import React, { useEffect } from 'react' const typeToClass = { heading: 'tw-text-xl tw-font-bold', @@ -22,7 +22,7 @@ const EditableText = ({ value, save, className = '', type = 'default' }) => { } } - React.useEffect(() => { + useEffect(() => { setCurrentValue(value) }, [value]) @@ -42,7 +42,7 @@ const EditableText = ({ value, save, className = '', type = 'default' }) => { onClick={() => setIsEditable(true)} className={`tw-w-full tw-items-start tw-justify-start tw-text-gray-800 tw-cursor-pointer ${displayClass}`} > - {currentValue} + {currentValue || 'Click to edit'} ) }