2019-07-09 06:57:10 +08:00
|
|
|
import React, { Component } from 'react';
|
2018-10-16 03:58:07 +08:00
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { defineMessages, injectIntl } from 'react-intl';
|
2022-02-15 23:54:55 +08:00
|
|
|
import { withModalMounter } from '/imports/ui/components/common/modal/service';
|
2018-10-16 03:58:07 +08:00
|
|
|
import _ from 'lodash';
|
2018-10-18 22:31:17 +08:00
|
|
|
import { Session } from 'meteor/session';
|
2022-02-15 03:26:19 +08:00
|
|
|
import Checkbox from '/imports/ui/components/common/checkbox/component';
|
2022-02-15 23:58:28 +08:00
|
|
|
import Toggle from '/imports/ui/components/common/switch/component';
|
2018-10-29 23:27:50 +08:00
|
|
|
import LiveResult from './live-result/component';
|
2021-11-04 22:19:38 +08:00
|
|
|
import Styled from './styles';
|
2021-05-18 04:25:07 +08:00
|
|
|
import { PANELS, ACTIONS } from '../layout/enums';
|
2021-02-08 20:06:15 +08:00
|
|
|
import DragAndDrop from './dragAndDrop/component';
|
2021-09-13 08:03:03 +08:00
|
|
|
import { alertScreenReader } from '/imports/utils/dom-utils';
|
2018-09-15 01:50:18 +08:00
|
|
|
|
2018-09-24 06:57:03 +08:00
|
|
|
const intlMessages = defineMessages({
|
|
|
|
pollPaneTitle: {
|
|
|
|
id: 'app.poll.pollPaneTitle',
|
|
|
|
description: 'heading label for the poll menu',
|
|
|
|
},
|
2018-10-30 23:57:10 +08:00
|
|
|
closeLabel: {
|
|
|
|
id: 'app.poll.closeLabel',
|
|
|
|
description: 'label for poll pane close button',
|
|
|
|
},
|
2018-09-24 06:57:03 +08:00
|
|
|
hidePollDesc: {
|
|
|
|
id: 'app.poll.hidePollDesc',
|
|
|
|
description: 'aria label description for hide poll button',
|
|
|
|
},
|
|
|
|
quickPollInstruction: {
|
|
|
|
id: 'app.poll.quickPollInstruction',
|
|
|
|
description: 'instructions for using pre configured polls',
|
|
|
|
},
|
2018-09-25 06:43:54 +08:00
|
|
|
activePollInstruction: {
|
|
|
|
id: 'app.poll.activePollInstruction',
|
|
|
|
description: 'instructions displayed when a poll is active',
|
|
|
|
},
|
2021-02-08 20:06:15 +08:00
|
|
|
dragDropPollInstruction: {
|
|
|
|
id: 'app.poll.dragDropPollInstruction',
|
|
|
|
description: 'instructions for upload poll options via drag and drop',
|
|
|
|
},
|
2019-02-02 11:56:15 +08:00
|
|
|
ariaInputCount: {
|
|
|
|
id: 'app.poll.ariaInputCount',
|
|
|
|
description: 'aria label for custom poll input field',
|
|
|
|
},
|
2018-09-24 06:57:03 +08:00
|
|
|
customPlaceholder: {
|
|
|
|
id: 'app.poll.customPlaceholder',
|
|
|
|
description: 'custom poll input field placeholder text',
|
|
|
|
},
|
2019-03-09 04:46:25 +08:00
|
|
|
noPresentationSelected: {
|
|
|
|
id: 'app.poll.noPresentationSelected',
|
|
|
|
description: 'no presentation label',
|
|
|
|
},
|
|
|
|
clickHereToSelect: {
|
|
|
|
id: 'app.poll.clickHereToSelect',
|
|
|
|
description: 'open uploader modal button label',
|
|
|
|
},
|
2020-09-22 06:52:38 +08:00
|
|
|
questionErr: {
|
|
|
|
id: 'app.poll.questionErr',
|
|
|
|
description: 'question text area error label',
|
|
|
|
},
|
2022-03-22 01:58:11 +08:00
|
|
|
questionAndOptionsPlaceholder: {
|
|
|
|
id: 'app.poll.questionAndoptions.label',
|
|
|
|
description: 'poll input questions and options label',
|
|
|
|
},
|
|
|
|
autoOptionToggleLabel: {
|
|
|
|
id: 'app.poll.autoOption.label',
|
|
|
|
description: 'poll auto optioning toogle button label',
|
|
|
|
},
|
|
|
|
autoOptionInstructionsLabel: {
|
|
|
|
id: 'app.poll.autoOptionInstructions.label',
|
|
|
|
description: 'poll auto optioning instructions label',
|
|
|
|
},
|
2022-03-22 03:44:21 +08:00
|
|
|
maxOptionsWarning: {
|
|
|
|
id: 'app.poll.maxOptionsWarning.label',
|
2022-03-22 01:58:11 +08:00
|
|
|
description: 'poll max options error',
|
|
|
|
},
|
2020-09-22 06:52:38 +08:00
|
|
|
optionErr: {
|
|
|
|
id: 'app.poll.optionErr',
|
|
|
|
description: 'poll input error label',
|
|
|
|
},
|
2018-10-03 11:24:34 +08:00
|
|
|
tf: {
|
|
|
|
id: 'app.poll.tf',
|
2018-09-24 06:57:03 +08:00
|
|
|
description: 'label for true / false poll',
|
|
|
|
},
|
2018-10-03 11:24:34 +08:00
|
|
|
a4: {
|
|
|
|
id: 'app.poll.a4',
|
2018-09-24 06:57:03 +08:00
|
|
|
description: 'label for A / B / C / D poll',
|
|
|
|
},
|
2020-09-21 20:07:36 +08:00
|
|
|
delete: {
|
|
|
|
id: 'app.poll.optionDelete.label',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
questionLabel: {
|
|
|
|
id: 'app.poll.question.label',
|
|
|
|
description: '',
|
|
|
|
},
|
2021-10-01 02:55:46 +08:00
|
|
|
optionalQuestionLabel: {
|
|
|
|
id: 'app.poll.optionalQuestion.label',
|
|
|
|
description: '',
|
|
|
|
},
|
2020-09-21 20:07:36 +08:00
|
|
|
userResponse: {
|
|
|
|
id: 'app.poll.userResponse.label',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
responseChoices: {
|
|
|
|
id: 'app.poll.responseChoices.label',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
typedResponseDesc: {
|
|
|
|
id: 'app.poll.typedResponse.desc',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
responseTypesLabel: {
|
|
|
|
id: 'app.poll.responseTypes.label',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
addOptionLabel: {
|
|
|
|
id: 'app.poll.addItem.label',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
startPollLabel: {
|
|
|
|
id: 'app.poll.start.label',
|
|
|
|
description: '',
|
|
|
|
},
|
2021-04-29 23:10:18 +08:00
|
|
|
secretPollLabel: {
|
|
|
|
id: 'app.poll.secretPoll.label',
|
|
|
|
description: '',
|
|
|
|
},
|
2021-05-26 19:34:48 +08:00
|
|
|
isSecretPollLabel: {
|
2021-06-17 21:25:03 +08:00
|
|
|
id: 'app.poll.secretPoll.isSecretLabel',
|
2021-05-26 19:34:48 +08:00
|
|
|
description: '',
|
|
|
|
},
|
2020-09-21 20:07:36 +08:00
|
|
|
true: {
|
|
|
|
id: 'app.poll.answer.true',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
false: {
|
|
|
|
id: 'app.poll.answer.false',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
a: {
|
|
|
|
id: 'app.poll.answer.a',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
b: {
|
|
|
|
id: 'app.poll.answer.b',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
c: {
|
|
|
|
id: 'app.poll.answer.c',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
d: {
|
|
|
|
id: 'app.poll.answer.d',
|
|
|
|
description: '',
|
2018-09-24 06:57:03 +08:00
|
|
|
},
|
2022-03-22 01:58:11 +08:00
|
|
|
e: {
|
|
|
|
id: 'app.poll.answer.e',
|
|
|
|
description: '',
|
|
|
|
},
|
2021-02-19 00:06:21 +08:00
|
|
|
yna: {
|
|
|
|
id: 'app.poll.yna',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
yes: {
|
|
|
|
id: 'app.poll.y',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
no: {
|
|
|
|
id: 'app.poll.n',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
abstention: {
|
|
|
|
id: 'app.poll.abstention',
|
|
|
|
description: '',
|
|
|
|
},
|
2021-02-08 17:57:39 +08:00
|
|
|
enableMultipleResponseLabel: {
|
|
|
|
id: 'app.poll.enableMultipleResponseLabel',
|
2021-02-04 21:59:16 +08:00
|
|
|
description: 'label for checkbox to enable multiple choice',
|
2021-02-08 17:57:39 +08:00
|
|
|
},
|
2021-08-11 12:10:41 +08:00
|
|
|
startPollDesc: {
|
|
|
|
id: 'app.poll.startPollDesc',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
showRespDesc: {
|
|
|
|
id: 'app.poll.showRespDesc',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
addRespDesc: {
|
|
|
|
id: 'app.poll.addRespDesc',
|
|
|
|
description: '',
|
|
|
|
},
|
|
|
|
deleteRespDesc: {
|
|
|
|
id: 'app.poll.deleteRespDesc',
|
|
|
|
description: '',
|
|
|
|
},
|
2021-08-19 04:02:46 +08:00
|
|
|
on: {
|
|
|
|
id: 'app.switch.onLabel',
|
|
|
|
description: 'label for toggle switch on state',
|
|
|
|
},
|
|
|
|
off: {
|
|
|
|
id: 'app.switch.offLabel',
|
|
|
|
description: 'label for toggle switch off state',
|
|
|
|
},
|
2021-09-13 08:03:03 +08:00
|
|
|
removePollOpt: {
|
|
|
|
id: 'app.poll.removePollOpt',
|
|
|
|
description: 'screen reader alert for removed poll option',
|
|
|
|
},
|
2021-09-13 08:11:45 +08:00
|
|
|
emptyPollOpt: {
|
|
|
|
id: 'app.poll.emptyPollOpt',
|
|
|
|
description: 'screen reader for blank poll option',
|
|
|
|
},
|
2018-09-24 06:57:03 +08:00
|
|
|
});
|
|
|
|
|
2021-04-30 00:54:39 +08:00
|
|
|
const POLL_SETTINGS = Meteor.settings.public.poll;
|
|
|
|
|
2021-06-18 22:02:09 +08:00
|
|
|
const MAX_CUSTOM_FIELDS = POLL_SETTINGS.maxCustom;
|
2021-04-30 00:54:39 +08:00
|
|
|
const MAX_INPUT_CHARS = POLL_SETTINGS.maxTypedAnswerLength;
|
2022-03-22 01:58:11 +08:00
|
|
|
const QUESTION_MAX_INPUT_CHARS = 1200;
|
2021-04-30 00:54:39 +08:00
|
|
|
const FILE_DRAG_AND_DROP_ENABLED = POLL_SETTINGS.allowDragAndDropFile;
|
2022-03-22 01:58:11 +08:00
|
|
|
const AUTO_OPTIONING = POLL_SETTINGS.autoOptioning;
|
|
|
|
const POLL_OPTIONS_PLACEHOLDERS = [
|
|
|
|
{ val: intlMessages.a },
|
|
|
|
{ val: intlMessages.b },
|
|
|
|
{ val: intlMessages.c },
|
|
|
|
{ val: intlMessages.d },
|
|
|
|
{ val: intlMessages.e },
|
|
|
|
];
|
|
|
|
const MIN_OPTIONS_LENGTH = 2;
|
2018-10-03 07:59:45 +08:00
|
|
|
|
2020-09-22 00:00:05 +08:00
|
|
|
const validateInput = (i) => {
|
|
|
|
let _input = i;
|
2022-01-15 05:05:16 +08:00
|
|
|
while (/^\s/.test(_input)) _input = _input.substring(1);
|
2020-09-22 00:00:05 +08:00
|
|
|
return _input;
|
|
|
|
};
|
|
|
|
|
2022-03-22 01:58:11 +08:00
|
|
|
const removeEmptyLineSpaces = (inputText) => {
|
|
|
|
const filteredInput = inputText.split('\n').filter((val) => val.trim() !== '');
|
|
|
|
return filteredInput;
|
|
|
|
};
|
|
|
|
|
|
|
|
const getSplittedQuestionAndOptions = (questionAndOptions) => {
|
|
|
|
const inputList = Array.isArray(questionAndOptions)
|
|
|
|
? questionAndOptions : questionAndOptions.split('\n');
|
|
|
|
const splittedQuestion = inputList.length > 0 ? inputList[0] : questionAndOptions;
|
|
|
|
const optionsList = inputList.slice(1);
|
|
|
|
optionsList.forEach((val, i) => { optionsList[i] = { val }; });
|
|
|
|
return {
|
|
|
|
splittedQuestion,
|
|
|
|
optionsList,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2019-07-09 06:57:10 +08:00
|
|
|
class Poll extends Component {
|
2018-09-15 01:50:18 +08:00
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = {
|
2018-09-25 06:43:54 +08:00
|
|
|
isPolling: false,
|
2020-09-21 20:07:36 +08:00
|
|
|
question: '',
|
2022-03-22 01:58:11 +08:00
|
|
|
questionAndOptions: '',
|
2020-09-21 20:07:36 +08:00
|
|
|
optList: [],
|
2020-09-22 06:52:38 +08:00
|
|
|
error: null,
|
2021-02-08 17:57:39 +08:00
|
|
|
isMultipleResponse: false,
|
2021-04-29 23:10:18 +08:00
|
|
|
secretPoll: false,
|
2022-03-22 01:58:11 +08:00
|
|
|
autoOptioning: false,
|
|
|
|
warning: null,
|
|
|
|
isPasting: false,
|
|
|
|
type: null,
|
2018-09-15 01:50:18 +08:00
|
|
|
};
|
|
|
|
|
2018-10-30 21:17:40 +08:00
|
|
|
this.handleBackClick = this.handleBackClick.bind(this);
|
2020-09-21 20:07:36 +08:00
|
|
|
this.handleAddOption = this.handleAddOption.bind(this);
|
|
|
|
this.handleRemoveOption = this.handleRemoveOption.bind(this);
|
|
|
|
this.handleTextareaChange = this.handleTextareaChange.bind(this);
|
|
|
|
this.handleInputChange = this.handleInputChange.bind(this);
|
2021-03-07 22:12:49 +08:00
|
|
|
this.toggleIsMultipleResponse = this.toggleIsMultipleResponse.bind(this);
|
2021-08-19 04:02:46 +08:00
|
|
|
this.displayToggleStatus = this.displayToggleStatus.bind(this);
|
2022-03-22 01:58:11 +08:00
|
|
|
this.displayAutoOptionToggleStatus = this.displayAutoOptionToggleStatus.bind(this);
|
2018-09-24 06:57:03 +08:00
|
|
|
}
|
|
|
|
|
2019-05-07 04:18:23 +08:00
|
|
|
componentDidMount() {
|
2019-07-09 06:57:10 +08:00
|
|
|
const { props } = this.hideBtn;
|
|
|
|
const { className } = props;
|
|
|
|
|
|
|
|
const hideBtn = document.getElementsByClassName(`${className}`);
|
|
|
|
if (hideBtn[0]) hideBtn[0].focus();
|
2019-05-07 04:18:23 +08:00
|
|
|
}
|
|
|
|
|
2018-11-23 12:08:48 +08:00
|
|
|
componentDidUpdate() {
|
2022-04-18 17:06:05 +08:00
|
|
|
const { amIPresenter, layoutContextDispatch, sidebarContentPanel } = this.props;
|
2021-07-08 04:15:07 +08:00
|
|
|
|
2019-03-28 23:58:10 +08:00
|
|
|
if (Session.equals('resetPollPanel', true)) {
|
2019-03-15 03:34:53 +08:00
|
|
|
this.handleBackClick();
|
|
|
|
}
|
2021-07-08 04:15:07 +08:00
|
|
|
|
2022-04-18 17:06:05 +08:00
|
|
|
if (!amIPresenter && sidebarContentPanel === PANELS.POLL) {
|
2021-08-05 19:03:24 +08:00
|
|
|
layoutContextDispatch({
|
2021-07-08 04:15:07 +08:00
|
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
|
|
|
|
value: false,
|
|
|
|
});
|
2021-08-05 19:03:24 +08:00
|
|
|
layoutContextDispatch({
|
2021-07-08 04:15:07 +08:00
|
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL,
|
|
|
|
value: PANELS.NONE,
|
|
|
|
});
|
|
|
|
}
|
2018-11-23 12:08:48 +08:00
|
|
|
}
|
|
|
|
|
2021-12-09 00:49:43 +08:00
|
|
|
componentWillUnmount() {
|
|
|
|
Session.set('secretPoll', false);
|
|
|
|
}
|
|
|
|
|
2018-12-18 23:15:51 +08:00
|
|
|
handleBackClick() {
|
|
|
|
const { stopPoll } = this.props;
|
|
|
|
this.setState({
|
|
|
|
isPolling: false,
|
2020-09-22 06:52:38 +08:00
|
|
|
error: null,
|
2020-09-21 20:07:36 +08:00
|
|
|
}, () => {
|
|
|
|
stopPoll();
|
|
|
|
Session.set('resetPollPanel', false);
|
|
|
|
document.activeElement.blur();
|
|
|
|
});
|
2018-09-24 06:57:03 +08:00
|
|
|
}
|
|
|
|
|
2021-02-08 20:06:15 +08:00
|
|
|
handleInputTextChange(index, text) {
|
2022-04-18 17:06:05 +08:00
|
|
|
const { optList, type } = this.state;
|
|
|
|
const { pollTypes } = this.props;
|
2021-02-08 20:06:15 +08:00
|
|
|
// This regex will replace any instance of 2 or more consecutive white spaces
|
|
|
|
// with a single white space character.
|
|
|
|
const option = text.replace(/\s{2,}/g, ' ').trim();
|
|
|
|
|
2021-03-05 03:43:43 +08:00
|
|
|
if (index < optList.length) optList[index].val = option === '' ? '' : option;
|
2021-02-08 20:06:15 +08:00
|
|
|
|
2022-04-18 17:06:05 +08:00
|
|
|
this.setState({ optList, type: type || pollTypes.Letter });
|
2021-02-08 20:06:15 +08:00
|
|
|
}
|
|
|
|
|
2020-09-21 20:07:36 +08:00
|
|
|
handleInputChange(e, index) {
|
2022-03-22 01:58:11 +08:00
|
|
|
const {
|
|
|
|
optList, type, error, questionAndOptions,
|
|
|
|
} = this.state;
|
2021-05-27 01:52:55 +08:00
|
|
|
const { pollTypes } = this.props;
|
2020-09-21 20:07:36 +08:00
|
|
|
const list = [...optList];
|
2020-09-22 06:52:38 +08:00
|
|
|
const validatedVal = validateInput(e.target.value).replace(/\s{2,}/g, ' ');
|
2022-01-15 05:05:16 +08:00
|
|
|
const charsRemovedCount = e.target.value.length - validatedVal.length;
|
2021-05-27 01:52:55 +08:00
|
|
|
const clearError = validatedVal.length > 0 && type !== pollTypes.Response;
|
2022-01-15 05:05:16 +08:00
|
|
|
const input = e.target;
|
|
|
|
const caretStart = e.target.selectionStart;
|
|
|
|
const caretEnd = e.target.selectionEnd;
|
2020-09-22 06:52:38 +08:00
|
|
|
list[index] = { val: validatedVal };
|
2022-03-22 01:58:11 +08:00
|
|
|
let questionAndOptionsList = [];
|
|
|
|
if (questionAndOptions.length > 0) {
|
|
|
|
questionAndOptionsList = questionAndOptions.split('\n');
|
|
|
|
questionAndOptionsList[index + 1] = validatedVal;
|
|
|
|
}
|
|
|
|
this.setState({
|
|
|
|
optList: list,
|
|
|
|
questionAndOptions: questionAndOptionsList.length > 0
|
|
|
|
? questionAndOptionsList.join('\n') : '',
|
|
|
|
error: clearError ? null : error,
|
|
|
|
},
|
|
|
|
() => {
|
|
|
|
input.focus();
|
|
|
|
input.selectionStart = caretStart - charsRemovedCount;
|
|
|
|
input.selectionEnd = caretEnd - charsRemovedCount;
|
|
|
|
});
|
2021-02-04 21:59:16 +08:00
|
|
|
}
|
|
|
|
|
2020-09-21 20:07:36 +08:00
|
|
|
handleTextareaChange(e) {
|
2022-03-22 01:58:11 +08:00
|
|
|
const {
|
|
|
|
type, error, autoOptioning, isPasting,
|
|
|
|
} = this.state;
|
|
|
|
const { pollTypes, intl } = this.props;
|
|
|
|
const validatedInput = validateInput(e.target.value);
|
|
|
|
const clearError = validatedInput.length > 0 && type === pollTypes.Response;
|
|
|
|
if (!autoOptioning) {
|
|
|
|
this.setState({
|
|
|
|
question: validatedInput,
|
|
|
|
error: clearError ? null : error,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
const { warning, optList } = this.state;
|
2022-03-22 03:44:21 +08:00
|
|
|
let maxOptionsWarning = warning;
|
2022-03-22 01:58:11 +08:00
|
|
|
const { splittedQuestion, optionsList } = getSplittedQuestionAndOptions(validatedInput);
|
|
|
|
const optionsListLength = optionsList.length;
|
2022-03-22 03:44:21 +08:00
|
|
|
const clearWarning = maxOptionsWarning && optionsListLength <= MAX_CUSTOM_FIELDS;
|
2022-03-22 01:58:11 +08:00
|
|
|
if ((optionsListLength) > MAX_CUSTOM_FIELDS && optList[MAX_CUSTOM_FIELDS] === undefined) {
|
2022-03-22 03:44:21 +08:00
|
|
|
this.setState({ warning: intl.formatMessage(intlMessages.maxOptionsWarning) });
|
2022-03-22 01:58:11 +08:00
|
|
|
if (!isPasting) { return null; }
|
2022-03-22 03:44:21 +08:00
|
|
|
maxOptionsWarning = intl.formatMessage(intlMessages.maxOptionsWarning);
|
2022-03-22 01:58:11 +08:00
|
|
|
this.setState({ isPasting: false });
|
|
|
|
}
|
|
|
|
this.setState({
|
|
|
|
questionAndOptions: validatedInput,
|
|
|
|
optList: optionsList,
|
|
|
|
question: splittedQuestion,
|
|
|
|
error: clearError ? null : error,
|
2022-03-22 03:44:21 +08:00
|
|
|
warning: clearWarning ? null : maxOptionsWarning,
|
2022-03-22 01:58:11 +08:00
|
|
|
});
|
|
|
|
}
|
|
|
|
return null;
|
2020-09-21 20:07:36 +08:00
|
|
|
}
|
2018-09-24 06:57:03 +08:00
|
|
|
|
2021-04-27 07:04:34 +08:00
|
|
|
handlePollValuesText(text) {
|
|
|
|
if (text && text.length > 0) {
|
|
|
|
this.pushToCustomPollValues(text);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handleRemoveOption(index) {
|
2021-09-13 08:03:03 +08:00
|
|
|
const { intl } = this.props;
|
2022-03-22 01:58:11 +08:00
|
|
|
const {
|
|
|
|
optList, questionAndOptions, autoOptioning, warning,
|
|
|
|
} = this.state;
|
2021-04-27 07:04:34 +08:00
|
|
|
const list = [...optList];
|
2021-09-13 08:03:03 +08:00
|
|
|
const removed = list[index];
|
2021-04-27 07:04:34 +08:00
|
|
|
list.splice(index, 1);
|
2022-03-22 01:58:11 +08:00
|
|
|
// if autoOptioning then removing text from input field
|
|
|
|
let questionAndOptionsList = [];
|
|
|
|
let clearWarning = false;
|
|
|
|
if (autoOptioning) {
|
|
|
|
questionAndOptionsList = questionAndOptions.split('\n');
|
|
|
|
delete questionAndOptionsList[index + 1];
|
|
|
|
questionAndOptionsList = questionAndOptionsList.filter((val) => val !== undefined);
|
|
|
|
clearWarning = warning && list.length <= MAX_CUSTOM_FIELDS;
|
|
|
|
}
|
|
|
|
this.setState({
|
|
|
|
optList: list,
|
|
|
|
questionAndOptions: questionAndOptionsList.length > 0
|
|
|
|
? questionAndOptionsList.join('\n') : [],
|
|
|
|
warning: clearWarning ? null : warning,
|
|
|
|
}, () => {
|
2021-09-13 08:11:45 +08:00
|
|
|
alertScreenReader(`${intl.formatMessage(intlMessages.removePollOpt,
|
|
|
|
{ 0: removed.val || intl.formatMessage(intlMessages.emptyPollOpt) })}`);
|
2021-09-13 08:03:03 +08:00
|
|
|
});
|
2021-04-27 07:04:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
handleAddOption() {
|
|
|
|
const { optList } = this.state;
|
|
|
|
this.setState({ optList: [...optList, { val: '' }] });
|
|
|
|
}
|
|
|
|
|
2021-04-29 23:10:18 +08:00
|
|
|
handleToggle() {
|
2021-07-03 03:58:33 +08:00
|
|
|
const { secretPoll } = this.state;
|
|
|
|
const toggledValue = !secretPoll;
|
|
|
|
Session.set('secretPoll', toggledValue);
|
|
|
|
this.setState({ secretPoll: toggledValue });
|
2021-04-29 23:10:18 +08:00
|
|
|
}
|
|
|
|
|
2022-03-22 01:58:11 +08:00
|
|
|
handleAutoOptionToogle() {
|
|
|
|
const { autoOptioning, questionAndOptions, question } = this.state;
|
|
|
|
const { intl } = this.props;
|
|
|
|
const toggledValue = !autoOptioning;
|
|
|
|
if (autoOptioning === true && toggledValue === false) {
|
|
|
|
const questionAndOptionsList = removeEmptyLineSpaces(questionAndOptions);
|
|
|
|
this.setState({
|
|
|
|
question: questionAndOptionsList.join('\n'),
|
|
|
|
autoOptioning: toggledValue,
|
|
|
|
optList: [],
|
|
|
|
type: null,
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.handlePollLetterOptions();
|
|
|
|
const inputList = removeEmptyLineSpaces(question);
|
|
|
|
const { splittedQuestion, optionsList } = getSplittedQuestionAndOptions(inputList);
|
|
|
|
const clearWarning = optionsList.length > MAX_CUSTOM_FIELDS
|
2022-03-22 03:44:21 +08:00
|
|
|
? intl.formatMessage(intlMessages.maxOptionsWarning) : null;
|
2022-03-22 01:58:11 +08:00
|
|
|
this.setState({
|
|
|
|
questionAndOptions: inputList.join('\n'),
|
|
|
|
optList: optionsList,
|
|
|
|
autoOptioning: toggledValue,
|
|
|
|
question: splittedQuestion,
|
|
|
|
warning: clearWarning,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
handlePollLetterOptions() {
|
|
|
|
const { pollTypes } = this.props;
|
|
|
|
const { optList } = this.state;
|
|
|
|
if (optList.length === 0) {
|
|
|
|
this.setState({
|
|
|
|
type: pollTypes.Letter,
|
|
|
|
optList: [
|
|
|
|
{ val: '' },
|
|
|
|
{ val: '' },
|
|
|
|
{ val: '' },
|
|
|
|
{ val: '' },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-30 22:33:57 +08:00
|
|
|
setOptListLength(len) {
|
|
|
|
const { optList } = this.state;
|
2021-04-27 07:04:34 +08:00
|
|
|
let diff = len > MAX_CUSTOM_FIELDS
|
|
|
|
? MAX_CUSTOM_FIELDS - optList.length
|
|
|
|
: len - optList.length;
|
|
|
|
if (diff > 0) {
|
|
|
|
while (diff > 0) {
|
2021-04-12 08:40:46 +08:00
|
|
|
this.handleAddOption();
|
2021-04-27 07:04:34 +08:00
|
|
|
diff -= 1;
|
2021-04-12 08:40:46 +08:00
|
|
|
}
|
2021-03-30 22:33:57 +08:00
|
|
|
} else {
|
2021-04-27 07:04:34 +08:00
|
|
|
while (diff < 0) {
|
2021-04-12 08:40:46 +08:00
|
|
|
this.handleRemoveOption();
|
2021-04-27 07:04:34 +08:00
|
|
|
diff += 1;
|
2021-04-12 08:40:46 +08:00
|
|
|
}
|
2021-03-30 22:33:57 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-03-22 01:58:11 +08:00
|
|
|
toggleIsMultipleResponse() {
|
|
|
|
const { isMultipleResponse } = this.state;
|
|
|
|
return this.setState({ isMultipleResponse: !isMultipleResponse });
|
|
|
|
}
|
|
|
|
|
2021-08-19 04:02:46 +08:00
|
|
|
displayToggleStatus(status) {
|
|
|
|
const { intl } = this.props;
|
|
|
|
|
|
|
|
return (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.ToggleLabel>
|
2021-08-19 04:02:46 +08:00
|
|
|
{status ? intl.formatMessage(intlMessages.on)
|
|
|
|
: intl.formatMessage(intlMessages.off)}
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.ToggleLabel>
|
2021-08-19 04:02:46 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-03-22 01:58:11 +08:00
|
|
|
displayAutoOptionToggleStatus(status) {
|
|
|
|
const { intl } = this.props;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Styled.ToggleLabel>
|
|
|
|
{status ? intl.formatMessage(intlMessages.on)
|
|
|
|
: intl.formatMessage(intlMessages.off)}
|
|
|
|
</Styled.ToggleLabel>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2021-02-08 20:06:15 +08:00
|
|
|
pushToCustomPollValues(text) {
|
|
|
|
const lines = text.split('\n');
|
2021-03-30 22:33:57 +08:00
|
|
|
this.setOptListLength(lines.length);
|
2021-02-08 20:06:15 +08:00
|
|
|
for (let i = 0; i < MAX_CUSTOM_FIELDS; i += 1) {
|
|
|
|
let line = '';
|
|
|
|
if (i < lines.length) {
|
|
|
|
line = lines[i];
|
|
|
|
line = line.length > MAX_INPUT_CHARS ? line.substring(0, MAX_INPUT_CHARS) : line;
|
|
|
|
}
|
|
|
|
this.handleInputTextChange(i, line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-21 20:07:36 +08:00
|
|
|
renderInputs() {
|
2021-05-27 01:52:55 +08:00
|
|
|
const { intl, pollTypes } = this.props;
|
2020-09-22 06:52:38 +08:00
|
|
|
const { optList, type, error } = this.state;
|
|
|
|
let hasVal = false;
|
2022-03-22 01:58:11 +08:00
|
|
|
return optList.slice(0, MAX_CUSTOM_FIELDS).map((o, i) => {
|
|
|
|
if (o.val && o.val.length > 0) hasVal = true;
|
2020-09-21 20:07:36 +08:00
|
|
|
const pollOptionKey = `poll-option-${i}`;
|
2018-12-18 23:15:51 +08:00
|
|
|
return (
|
2021-04-09 02:42:06 +08:00
|
|
|
<span key={pollOptionKey}>
|
2020-09-22 06:52:38 +08:00
|
|
|
<div
|
|
|
|
style={{
|
|
|
|
display: 'flex',
|
|
|
|
justifyContent: 'spaceBetween',
|
|
|
|
}}
|
|
|
|
>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.PollOptionInput
|
2020-09-22 06:52:38 +08:00
|
|
|
type="text"
|
|
|
|
value={o.val}
|
2022-03-22 01:58:11 +08:00
|
|
|
placeholder={`${i < MAX_CUSTOM_FIELDS ? `${intl.formatMessage(POLL_OPTIONS_PLACEHOLDERS[i].val)}. ` : ''}
|
|
|
|
${intl.formatMessage(intlMessages.customPlaceholder)}`}
|
2021-03-08 07:53:58 +08:00
|
|
|
data-test="pollOptionItem"
|
2021-04-27 07:04:34 +08:00
|
|
|
onChange={(e) => this.handleInputChange(e, i)}
|
2020-09-22 06:52:38 +08:00
|
|
|
maxLength={MAX_INPUT_CHARS}
|
|
|
|
/>
|
2022-03-22 01:58:11 +08:00
|
|
|
{
|
|
|
|
optList.length > MIN_OPTIONS_LENGTH && (
|
|
|
|
<Styled.DeletePollOptionButton
|
|
|
|
label={intl.formatMessage(intlMessages.delete)}
|
|
|
|
aria-describedby={`option-${i}`}
|
|
|
|
icon="delete"
|
|
|
|
data-test="deletePollOption"
|
|
|
|
hideLabel
|
|
|
|
circle
|
|
|
|
color="default"
|
|
|
|
onClick={() => {
|
|
|
|
this.handleRemoveOption(i);
|
|
|
|
}}
|
|
|
|
/>
|
2021-04-27 07:04:34 +08:00
|
|
|
)
|
2022-03-22 01:58:11 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
<span className="sr-only" id={`option-${i}`}>
|
|
|
|
{intl.formatMessage(intlMessages.deleteRespDesc,
|
|
|
|
{ 0: (o.val || intl.formatMessage(intlMessages.emptyPollOpt)) })}
|
|
|
|
</span>
|
2020-09-22 06:52:38 +08:00
|
|
|
</div>
|
2021-05-27 01:52:55 +08:00
|
|
|
{!hasVal && type !== pollTypes.Response && error ? (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.InputError>{error}</Styled.InputError>
|
2020-09-22 06:52:38 +08:00
|
|
|
) : (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.ErrorSpacer> </Styled.ErrorSpacer>
|
2020-09-22 06:52:38 +08:00
|
|
|
)}
|
|
|
|
</span>
|
2018-12-18 23:15:51 +08:00
|
|
|
);
|
|
|
|
});
|
2018-10-24 22:17:13 +08:00
|
|
|
}
|
|
|
|
|
2018-09-25 06:43:54 +08:00
|
|
|
renderActivePollOptions() {
|
|
|
|
const {
|
2019-05-23 02:00:44 +08:00
|
|
|
intl,
|
2019-06-28 00:46:14 +08:00
|
|
|
isMeteorConnected,
|
2019-05-23 02:00:44 +08:00
|
|
|
stopPoll,
|
|
|
|
currentPoll,
|
|
|
|
pollAnswerIds,
|
2021-04-19 21:58:33 +08:00
|
|
|
usernames,
|
2021-06-12 00:55:53 +08:00
|
|
|
isDefaultPoll,
|
2018-09-25 06:43:54 +08:00
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.Instructions>
|
2018-10-11 02:25:35 +08:00
|
|
|
{intl.formatMessage(intlMessages.activePollInstruction)}
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.Instructions>
|
2018-10-29 23:27:50 +08:00
|
|
|
<LiveResult
|
|
|
|
{...{
|
2019-06-28 00:46:14 +08:00
|
|
|
isMeteorConnected,
|
2018-10-29 23:27:50 +08:00
|
|
|
stopPoll,
|
|
|
|
currentPoll,
|
2019-05-23 02:00:44 +08:00
|
|
|
pollAnswerIds,
|
2021-04-19 21:58:33 +08:00
|
|
|
usernames,
|
2021-06-12 00:55:53 +08:00
|
|
|
isDefaultPoll,
|
2018-10-29 23:27:50 +08:00
|
|
|
}}
|
2018-10-30 21:17:40 +08:00
|
|
|
handleBackClick={this.handleBackClick}
|
2018-10-29 23:27:50 +08:00
|
|
|
/>
|
2018-09-25 06:43:54 +08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
renderPollOptions() {
|
2020-09-22 06:52:38 +08:00
|
|
|
const {
|
2022-03-22 01:58:11 +08:00
|
|
|
type, secretPoll, optList, questionAndOptions, error,
|
|
|
|
isMultipleResponse, question, autoOptioning, warning,
|
2020-09-22 06:52:38 +08:00
|
|
|
} = this.state;
|
2021-07-03 03:58:33 +08:00
|
|
|
const {
|
|
|
|
startPoll,
|
|
|
|
startCustomPoll,
|
|
|
|
intl,
|
|
|
|
pollTypes,
|
|
|
|
isDefaultPoll,
|
|
|
|
checkPollType,
|
2021-10-02 04:12:55 +08:00
|
|
|
smallSidebar,
|
2021-07-03 03:58:33 +08:00
|
|
|
} = this.props;
|
2021-05-27 01:52:55 +08:00
|
|
|
const defaultPoll = isDefaultPoll(type);
|
2021-10-01 02:55:46 +08:00
|
|
|
const questionPlaceholder = (type === pollTypes.Response)
|
|
|
|
? intlMessages.questionLabel
|
|
|
|
: intlMessages.optionalQuestionLabel;
|
2022-03-22 01:58:11 +08:00
|
|
|
const questionsAndOptionsPlaceholder = intlMessages.questionAndOptionsPlaceholder;
|
|
|
|
const hasQuestionError = (type === pollTypes.Response
|
|
|
|
&& questionAndOptions.length === 0 && error);
|
|
|
|
const hasOptionError = (autoOptioning && optList.length === 0 && error);
|
|
|
|
const hasWarning = (autoOptioning && warning);
|
2018-09-15 01:50:18 +08:00
|
|
|
return (
|
2018-09-24 06:20:20 +08:00
|
|
|
<div>
|
2022-03-22 01:58:11 +08:00
|
|
|
|
|
|
|
{AUTO_OPTIONING
|
|
|
|
&& (
|
2022-04-18 17:06:05 +08:00
|
|
|
<Styled.AutoOptioningRow>
|
|
|
|
<Styled.Col aria-hidden="true">
|
|
|
|
<Styled.SectionHeading>
|
|
|
|
{intl.formatMessage(intlMessages.autoOptionToggleLabel)}
|
|
|
|
</Styled.SectionHeading>
|
|
|
|
</Styled.Col>
|
|
|
|
<Styled.Col>
|
|
|
|
<Styled.Toggle>
|
|
|
|
{this.displayAutoOptionToggleStatus(autoOptioning)}
|
|
|
|
<Toggle
|
|
|
|
icons={false}
|
|
|
|
disabled={FILE_DRAG_AND_DROP_ENABLED}
|
|
|
|
defaultChecked={autoOptioning}
|
|
|
|
onChange={() => this.handleAutoOptionToogle()}
|
|
|
|
ariaLabel={intl.formatMessage(intlMessages.autoOptionToggleLabel)}
|
|
|
|
showToggleLabel={false}
|
|
|
|
data-test="autoOptioningPollBtn"
|
|
|
|
/>
|
|
|
|
</Styled.Toggle>
|
|
|
|
</Styled.Col>
|
|
|
|
</Styled.AutoOptioningRow>
|
2022-03-22 01:58:11 +08:00
|
|
|
)}
|
|
|
|
|
|
|
|
{autoOptioning
|
|
|
|
&& (
|
|
|
|
<Styled.PollParagraph style={{ marginBottom: '0.9rem' }}>
|
|
|
|
{intl.formatMessage(intlMessages.autoOptionInstructionsLabel)}
|
|
|
|
</Styled.PollParagraph>
|
|
|
|
)}
|
|
|
|
|
2020-09-21 20:07:36 +08:00
|
|
|
<div>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.PollQuestionArea
|
2022-03-22 01:58:11 +08:00
|
|
|
hasError={hasQuestionError || hasOptionError}
|
2021-03-08 07:53:58 +08:00
|
|
|
data-test="pollQuestionArea"
|
2022-03-22 01:58:11 +08:00
|
|
|
value={autoOptioning ? questionAndOptions : question}
|
2021-04-27 07:04:34 +08:00
|
|
|
onChange={(e) => this.handleTextareaChange(e)}
|
2022-03-22 01:58:11 +08:00
|
|
|
onPaste={() => this.setState({ isPasting: true })}
|
|
|
|
onKeyPress={(event) => {
|
|
|
|
if (event.key === 'Enter' && autoOptioning) {
|
|
|
|
this.handlePollLetterOptions();
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
rows="5"
|
2020-09-21 20:07:36 +08:00
|
|
|
cols="35"
|
2021-04-24 03:10:43 +08:00
|
|
|
maxLength={QUESTION_MAX_INPUT_CHARS}
|
2022-03-22 01:58:11 +08:00
|
|
|
aria-label={intl.formatMessage(autoOptioning ? questionsAndOptionsPlaceholder
|
|
|
|
: questionPlaceholder)}
|
|
|
|
placeholder={intl.formatMessage(autoOptioning ? questionsAndOptionsPlaceholder
|
|
|
|
: questionPlaceholder)}
|
2020-09-21 20:07:36 +08:00
|
|
|
/>
|
2022-03-22 01:58:11 +08:00
|
|
|
{hasQuestionError || hasOptionError ? (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.InputError>{error}</Styled.InputError>
|
2020-09-22 06:52:38 +08:00
|
|
|
) : (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.ErrorSpacer> </Styled.ErrorSpacer>
|
2020-09-22 06:52:38 +08:00
|
|
|
)}
|
2022-03-22 01:58:11 +08:00
|
|
|
{hasWarning ? (
|
|
|
|
<Styled.Warning>{warning}</Styled.Warning>
|
|
|
|
) : null}
|
2018-09-24 06:57:03 +08:00
|
|
|
</div>
|
2022-03-22 01:58:11 +08:00
|
|
|
{!autoOptioning
|
|
|
|
&& (
|
|
|
|
<div data-test="responseTypes">
|
|
|
|
<Styled.SectionHeading>
|
|
|
|
{intl.formatMessage(intlMessages.responseTypesLabel)}
|
|
|
|
</Styled.SectionHeading>
|
|
|
|
<Styled.ResponseType>
|
|
|
|
<Styled.PollConfigButton
|
|
|
|
selected={type === pollTypes.TrueFalse}
|
|
|
|
small={!smallSidebar}
|
|
|
|
label={intl.formatMessage(intlMessages.tf)}
|
|
|
|
aria-describedby="poll-config-button"
|
|
|
|
color="default"
|
|
|
|
onClick={() => {
|
|
|
|
this.setState({
|
|
|
|
type: pollTypes.TrueFalse,
|
|
|
|
optList: [
|
|
|
|
{ val: intl.formatMessage(intlMessages.true) },
|
|
|
|
{ val: intl.formatMessage(intlMessages.false) },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<Styled.PollConfigButton
|
|
|
|
selected={type === pollTypes.Letter}
|
|
|
|
small={!smallSidebar}
|
|
|
|
label={intl.formatMessage(intlMessages.a4)}
|
|
|
|
aria-describedby="poll-config-button"
|
|
|
|
data-test="pollLetterAlternatives"
|
|
|
|
color="default"
|
|
|
|
onClick={() => {
|
|
|
|
if (!autoOptioning) {
|
|
|
|
this.setState({
|
|
|
|
type: pollTypes.Letter,
|
|
|
|
optList: [
|
|
|
|
{ val: intl.formatMessage(intlMessages.a) },
|
|
|
|
{ val: intl.formatMessage(intlMessages.b) },
|
|
|
|
{ val: intl.formatMessage(intlMessages.c) },
|
|
|
|
{ val: intl.formatMessage(intlMessages.d) },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<Styled.PollConfigButton
|
|
|
|
selected={type === pollTypes.YesNoAbstention}
|
|
|
|
small={false}
|
|
|
|
full
|
|
|
|
label={intl.formatMessage(intlMessages.yna)}
|
|
|
|
aria-describedby="poll-config-button"
|
|
|
|
data-test="pollYesNoAbstentionBtn"
|
|
|
|
color="default"
|
|
|
|
onClick={() => {
|
|
|
|
this.setState({
|
|
|
|
type: pollTypes.YesNoAbstention,
|
|
|
|
optList: [
|
|
|
|
{ val: intl.formatMessage(intlMessages.yes) },
|
|
|
|
{ val: intl.formatMessage(intlMessages.no) },
|
|
|
|
{ val: intl.formatMessage(intlMessages.abstention) },
|
|
|
|
],
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
<Styled.PollConfigButton
|
|
|
|
selected={type === pollTypes.Response}
|
|
|
|
small={false}
|
|
|
|
full
|
|
|
|
label={intl.formatMessage(intlMessages.userResponse)}
|
|
|
|
aria-describedby="poll-config-button"
|
|
|
|
data-test="userResponseBtn"
|
|
|
|
color="default"
|
|
|
|
onClick={() => { this.setState({ type: pollTypes.Response }); }}
|
|
|
|
/>
|
|
|
|
</Styled.ResponseType>
|
|
|
|
</div>
|
|
|
|
)}
|
|
|
|
{((!autoOptioning && type) || (questionAndOptions && autoOptioning))
|
2021-04-27 07:04:34 +08:00
|
|
|
&& (
|
|
|
|
<div data-test="responseChoices">
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.SectionHeading>
|
|
|
|
{intl.formatMessage(intlMessages.responseChoices)}
|
|
|
|
</Styled.SectionHeading>
|
2021-04-27 07:04:34 +08:00
|
|
|
{
|
2021-05-27 01:52:55 +08:00
|
|
|
type === pollTypes.Response
|
2021-04-27 07:04:34 +08:00
|
|
|
&& (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.PollParagraph>
|
2021-04-27 07:04:34 +08:00
|
|
|
<span>{intl.formatMessage(intlMessages.typedResponseDesc)}</span>
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.PollParagraph>
|
2021-04-27 07:04:34 +08:00
|
|
|
)
|
|
|
|
}
|
2022-03-22 01:58:11 +08:00
|
|
|
{
|
|
|
|
(defaultPoll || type === pollTypes.Response)
|
|
|
|
&& (
|
|
|
|
<div style={{
|
|
|
|
display: 'flex',
|
|
|
|
flexFlow: 'wrap',
|
|
|
|
flexDirection: 'column',
|
|
|
|
}}
|
|
|
|
>
|
|
|
|
{defaultPoll
|
|
|
|
&& (
|
2021-03-07 22:12:49 +08:00
|
|
|
<div>
|
2021-11-06 01:29:46 +08:00
|
|
|
<Styled.PollCheckbox>
|
|
|
|
<Checkbox
|
|
|
|
onChange={this.toggleIsMultipleResponse}
|
|
|
|
checked={isMultipleResponse}
|
|
|
|
ariaLabelledBy="multipleResponseCheckboxLabel"
|
|
|
|
/>
|
|
|
|
</Styled.PollCheckbox>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.InstructionsLabel id="multipleResponseCheckboxLabel">
|
2021-03-07 22:12:49 +08:00
|
|
|
{intl.formatMessage(intlMessages.enableMultipleResponseLabel)}
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.InstructionsLabel>
|
2021-03-07 22:12:49 +08:00
|
|
|
</div>
|
2022-03-22 01:58:11 +08:00
|
|
|
)}
|
|
|
|
{defaultPoll && this.renderInputs()}
|
|
|
|
{defaultPoll
|
|
|
|
&& (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.AddItemButton
|
2021-10-25 23:01:40 +08:00
|
|
|
data-test="addPollItem"
|
2020-09-21 20:07:36 +08:00
|
|
|
label={intl.formatMessage(intlMessages.addOptionLabel)}
|
2021-08-11 12:10:41 +08:00
|
|
|
aria-describedby="add-item-button"
|
2020-09-21 20:07:36 +08:00
|
|
|
color="default"
|
|
|
|
icon="add"
|
2021-06-18 22:02:09 +08:00
|
|
|
disabled={optList.length >= MAX_CUSTOM_FIELDS}
|
2020-09-21 20:07:36 +08:00
|
|
|
onClick={() => this.handleAddOption()}
|
|
|
|
/>
|
2021-04-27 07:04:34 +08:00
|
|
|
)}
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.Row>
|
|
|
|
<Styled.Col aria-hidden="true">
|
|
|
|
<Styled.SectionHeading>
|
2021-08-09 22:24:02 +08:00
|
|
|
{intl.formatMessage(intlMessages.secretPollLabel)}
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.SectionHeading>
|
|
|
|
</Styled.Col>
|
|
|
|
<Styled.Col>
|
2021-08-09 22:24:02 +08:00
|
|
|
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.Toggle>
|
2021-08-19 04:02:46 +08:00
|
|
|
{this.displayToggleStatus(secretPoll)}
|
2021-04-29 23:10:18 +08:00
|
|
|
<Toggle
|
|
|
|
icons={false}
|
|
|
|
defaultChecked={secretPoll}
|
|
|
|
onChange={() => this.handleToggle()}
|
|
|
|
ariaLabel={intl.formatMessage(intlMessages.secretPollLabel)}
|
2021-08-19 04:02:46 +08:00
|
|
|
showToggleLabel={false}
|
2022-01-20 21:03:18 +08:00
|
|
|
data-test="anonymousPollBtn"
|
2021-04-29 23:10:18 +08:00
|
|
|
/>
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.Toggle>
|
|
|
|
</Styled.Col>
|
|
|
|
</Styled.Row>
|
2021-10-02 01:50:48 +08:00
|
|
|
{secretPoll
|
|
|
|
&& (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.PollParagraph>
|
2022-03-22 01:58:11 +08:00
|
|
|
{intl.formatMessage(intlMessages.isSecretPollLabel)}
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.PollParagraph>
|
2021-10-02 01:50:48 +08:00
|
|
|
)}
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.StartPollBtn
|
2021-04-27 07:04:34 +08:00
|
|
|
data-test="startPoll"
|
|
|
|
label={intl.formatMessage(intlMessages.startPollLabel)}
|
|
|
|
color="primary"
|
|
|
|
onClick={() => {
|
2022-03-22 01:58:11 +08:00
|
|
|
const optionsList = optList.slice(0, MAX_CUSTOM_FIELDS);
|
2021-04-27 07:04:34 +08:00
|
|
|
let hasVal = false;
|
2022-03-22 01:58:11 +08:00
|
|
|
optionsList.forEach((o) => {
|
|
|
|
if (o.val.trim().length > 0) hasVal = true;
|
2021-04-27 07:04:34 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
let err = null;
|
2021-08-09 22:24:02 +08:00
|
|
|
if (type === pollTypes.Response && question.length === 0) {
|
|
|
|
err = intl.formatMessage(intlMessages.questionErr);
|
|
|
|
}
|
|
|
|
if (!hasVal && type !== pollTypes.Response) {
|
|
|
|
err = intl.formatMessage(intlMessages.optionErr);
|
|
|
|
}
|
2021-04-27 07:04:34 +08:00
|
|
|
if (err) return this.setState({ error: err });
|
|
|
|
|
|
|
|
return this.setState({ isPolling: true }, () => {
|
2021-05-27 01:52:55 +08:00
|
|
|
const verifiedPollType = checkPollType(
|
|
|
|
type,
|
2022-03-22 01:58:11 +08:00
|
|
|
optionsList,
|
2021-05-27 01:52:55 +08:00
|
|
|
intl.formatMessage(intlMessages.yes),
|
|
|
|
intl.formatMessage(intlMessages.no),
|
|
|
|
intl.formatMessage(intlMessages.abstention),
|
|
|
|
intl.formatMessage(intlMessages.true),
|
2021-08-09 22:24:02 +08:00
|
|
|
intl.formatMessage(intlMessages.false),
|
2021-05-27 01:52:55 +08:00
|
|
|
);
|
2022-03-22 01:58:11 +08:00
|
|
|
const verifiedOptions = optionsList.map((o) => {
|
|
|
|
if (o.val.trim().length > 0) return o.val;
|
2021-04-27 07:04:34 +08:00
|
|
|
return null;
|
2020-09-22 06:52:38 +08:00
|
|
|
});
|
2021-05-27 01:52:55 +08:00
|
|
|
if (verifiedPollType === pollTypes.Custom) {
|
2021-04-27 07:04:34 +08:00
|
|
|
startCustomPoll(
|
|
|
|
verifiedPollType,
|
2021-04-29 23:10:18 +08:00
|
|
|
secretPoll,
|
2021-04-27 07:04:34 +08:00
|
|
|
question,
|
2021-09-17 20:12:43 +08:00
|
|
|
isMultipleResponse,
|
2021-04-27 07:04:34 +08:00
|
|
|
_.compact(verifiedOptions),
|
|
|
|
);
|
|
|
|
} else {
|
2021-09-17 20:12:43 +08:00
|
|
|
startPoll(verifiedPollType, secretPoll, question, isMultipleResponse);
|
2021-04-27 07:04:34 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
)
|
2020-09-21 20:07:36 +08:00
|
|
|
}
|
2021-04-27 07:04:34 +08:00
|
|
|
</div>
|
|
|
|
)}
|
2022-04-18 17:06:05 +08:00
|
|
|
{
|
|
|
|
FILE_DRAG_AND_DROP_ENABLED
|
|
|
|
&& type !== pollTypes.Response
|
|
|
|
&& this.renderDragDrop()
|
|
|
|
}
|
2018-09-15 01:50:18 +08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2018-09-25 06:43:54 +08:00
|
|
|
|
2019-03-15 03:34:53 +08:00
|
|
|
renderNoSlidePanel() {
|
2021-05-11 01:34:23 +08:00
|
|
|
const { intl } = this.props;
|
2019-03-09 04:46:25 +08:00
|
|
|
return (
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.NoSlidePanelContainer>
|
|
|
|
<Styled.SectionHeading>
|
|
|
|
{intl.formatMessage(intlMessages.noPresentationSelected)}
|
|
|
|
</Styled.SectionHeading>
|
|
|
|
<Styled.PollButton
|
2019-03-09 04:46:25 +08:00
|
|
|
label={intl.formatMessage(intlMessages.clickHereToSelect)}
|
|
|
|
color="primary"
|
2021-05-11 01:34:23 +08:00
|
|
|
onClick={() => Session.set('showUploadPresentationView', true)}
|
2019-03-09 04:46:25 +08:00
|
|
|
/>
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.NoSlidePanelContainer>
|
2019-03-09 04:46:25 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-03-15 03:34:53 +08:00
|
|
|
renderPollPanel() {
|
2019-03-09 04:46:25 +08:00
|
|
|
const { isPolling } = this.state;
|
2018-09-25 06:43:54 +08:00
|
|
|
const {
|
2019-03-09 04:46:25 +08:00
|
|
|
currentPoll,
|
|
|
|
currentSlide,
|
2018-09-25 06:43:54 +08:00
|
|
|
} = this.props;
|
|
|
|
|
2021-05-11 01:34:23 +08:00
|
|
|
if (!currentSlide) return this.renderNoSlidePanel();
|
2021-08-27 21:47:58 +08:00
|
|
|
if (isPolling || currentPoll) {
|
2019-03-09 04:46:25 +08:00
|
|
|
return this.renderActivePollOptions();
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.renderPollOptions();
|
|
|
|
}
|
|
|
|
|
2021-02-08 20:06:15 +08:00
|
|
|
renderDragDrop() {
|
|
|
|
const { intl } = this.props;
|
|
|
|
return (
|
|
|
|
<div>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.Instructions>
|
2021-02-08 20:06:15 +08:00
|
|
|
{intl.formatMessage(intlMessages.dragDropPollInstruction)}
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.Instructions>
|
2021-02-08 20:06:15 +08:00
|
|
|
<DragAndDrop
|
|
|
|
{...{ intl, MAX_INPUT_CHARS }}
|
2021-04-27 07:04:34 +08:00
|
|
|
handlePollValuesText={(e) => this.handlePollValuesText(e)}
|
2021-02-08 20:06:15 +08:00
|
|
|
>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.DragAndDropPollContainer />
|
2021-02-08 20:06:15 +08:00
|
|
|
</DragAndDrop>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-03-09 04:46:25 +08:00
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
intl,
|
|
|
|
stopPoll,
|
|
|
|
currentPoll,
|
2021-08-05 19:03:24 +08:00
|
|
|
layoutContextDispatch,
|
2019-03-09 04:46:25 +08:00
|
|
|
} = this.props;
|
2018-12-18 23:15:51 +08:00
|
|
|
|
2018-09-25 06:43:54 +08:00
|
|
|
return (
|
|
|
|
<div>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.Header>
|
|
|
|
<Styled.PollHideButton
|
2019-05-07 04:18:23 +08:00
|
|
|
ref={(node) => { this.hideBtn = node; }}
|
2020-03-20 22:42:04 +08:00
|
|
|
data-test="hidePollDesc"
|
2018-10-18 22:31:17 +08:00
|
|
|
tabIndex={0}
|
2018-10-26 00:07:24 +08:00
|
|
|
label={intl.formatMessage(intlMessages.pollPaneTitle)}
|
|
|
|
icon="left_arrow"
|
2018-09-25 06:43:54 +08:00
|
|
|
aria-label={intl.formatMessage(intlMessages.hidePollDesc)}
|
2021-04-27 07:04:34 +08:00
|
|
|
onClick={() => {
|
2021-08-05 19:03:24 +08:00
|
|
|
layoutContextDispatch({
|
2021-05-18 04:25:07 +08:00
|
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
|
|
|
|
value: false,
|
|
|
|
});
|
2021-08-05 19:03:24 +08:00
|
|
|
layoutContextDispatch({
|
2021-05-18 04:25:07 +08:00
|
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL,
|
|
|
|
value: PANELS.NONE,
|
|
|
|
});
|
2021-04-27 07:04:34 +08:00
|
|
|
}}
|
2018-10-26 00:07:24 +08:00
|
|
|
/>
|
2021-11-04 22:19:38 +08:00
|
|
|
<Styled.PollCloseButton
|
2018-10-30 23:57:10 +08:00
|
|
|
label={intl.formatMessage(intlMessages.closeLabel)}
|
2019-06-26 11:03:08 +08:00
|
|
|
aria-label={`${intl.formatMessage(intlMessages.closeLabel)} ${intl.formatMessage(intlMessages.pollPaneTitle)}`}
|
2018-10-24 22:17:13 +08:00
|
|
|
onClick={() => {
|
2020-09-21 20:07:36 +08:00
|
|
|
if (currentPoll) stopPoll();
|
2021-08-05 19:03:24 +08:00
|
|
|
layoutContextDispatch({
|
2021-05-18 04:25:07 +08:00
|
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_IS_OPEN,
|
|
|
|
value: false,
|
|
|
|
});
|
2021-08-05 19:03:24 +08:00
|
|
|
layoutContextDispatch({
|
2021-05-18 04:25:07 +08:00
|
|
|
type: ACTIONS.SET_SIDEBAR_CONTENT_PANEL,
|
|
|
|
value: PANELS.NONE,
|
|
|
|
});
|
2018-12-18 23:15:51 +08:00
|
|
|
Session.set('forcePollOpen', false);
|
2020-01-30 02:36:17 +08:00
|
|
|
Session.set('pollInitiated', false);
|
2018-12-18 23:15:51 +08:00
|
|
|
}}
|
2018-10-30 00:14:05 +08:00
|
|
|
icon="close"
|
|
|
|
size="sm"
|
2018-10-30 23:57:10 +08:00
|
|
|
hideLabel
|
2022-01-20 21:03:18 +08:00
|
|
|
data-test="closePolling"
|
2018-10-24 22:17:13 +08:00
|
|
|
/>
|
2021-11-04 22:19:38 +08:00
|
|
|
</Styled.Header>
|
2020-09-21 20:07:36 +08:00
|
|
|
{this.renderPollPanel()}
|
2021-08-11 12:10:41 +08:00
|
|
|
<span className="sr-only" id="poll-config-button">{intl.formatMessage(intlMessages.showRespDesc)}</span>
|
|
|
|
<span className="sr-only" id="add-item-button">{intl.formatMessage(intlMessages.addRespDesc)}</span>
|
|
|
|
<span className="sr-only" id="start-poll-button">{intl.formatMessage(intlMessages.startPollDesc)}</span>
|
2018-09-25 06:43:54 +08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2018-09-15 01:50:18 +08:00
|
|
|
}
|
|
|
|
|
2019-03-09 04:46:25 +08:00
|
|
|
export default withModalMounter(injectIntl(Poll));
|
2018-10-16 03:58:07 +08:00
|
|
|
|
|
|
|
Poll.propTypes = {
|
|
|
|
intl: PropTypes.shape({
|
|
|
|
formatMessage: PropTypes.func.isRequired,
|
|
|
|
}).isRequired,
|
2019-08-30 00:26:07 +08:00
|
|
|
amIPresenter: PropTypes.bool.isRequired,
|
2021-05-27 01:52:55 +08:00
|
|
|
pollTypes: PropTypes.instanceOf(Object).isRequired,
|
2018-10-16 03:58:07 +08:00
|
|
|
startPoll: PropTypes.func.isRequired,
|
|
|
|
startCustomPoll: PropTypes.func.isRequired,
|
|
|
|
stopPoll: PropTypes.func.isRequired,
|
|
|
|
};
|