diff --git a/Survey/src/components/SurveyQuestions.tsx b/Survey/src/components/SurveyQuestions.tsx
index 582c8c6a..27344f12 100644
--- a/Survey/src/components/SurveyQuestions.tsx
+++ b/Survey/src/components/SurveyQuestions.tsx
@@ -38,6 +38,7 @@ import {
IconButton,
TableRow,
TableCell,
+ TableHead
} from "@material-ui/core"
import classnames from "classnames"
import i18n from "../i18n"
@@ -76,7 +77,7 @@ const BorderLinearProgress = withStyles((theme: Theme) =>
const useStyles = makeStyles((theme) => ({
textCenter: {
- textAlign : "center"
+ textAlign: "center"
},
root: {
width: "100%",
@@ -110,7 +111,7 @@ const useStyles = makeStyles((theme) => ({
color: "white",
textAlign: "center",
"& p": {
- margin : "0",
+ margin: "0",
}
},
marginBottom40: {
@@ -204,35 +205,43 @@ const useStyles = makeStyles((theme) => ({
"0px 2px 4px -1px rgba(0,0,0,0.2), 0px 4px 5px 0px rgba(0,0,0,0.14), 0px 1px 10px 0px rgba(0,0,0,0.12)",
},
},
- formLabelMatrix : { alignItems: "center", margin : "0 auto" },
- timeMatrix:{
- "& div":{
+ formLabelMatrix: { alignItems: "center", margin: "0 auto" },
+ timeMatrix: {
+ "& div": {
marginTop: "0px"
},
},
- firstTr : {
+ firstTr: {
fontWeight: "bold",
+ position: "sticky",
+ top: 0,
"& td": {
padding: 0,
verticalAlign: "top",
border: 0,
- }
+ }
},
secondTr: {
+ position: "sticky",
+ top: 0,
+ zIndex: 2,
+ background: "#fff",
+ boxShadow: "0 0 6px rgba(0,0,0,0.25)",
"& td": {
padding: "5px 0",
- }
+ zIndex: 2
+ }
},
- matrix : {
- "& td" :{
- paddingLeft : "3px !important",
- paddingRight : "3px !important",
- width: "3%"
+ matrix: {
+ "& td": {
+ paddingLeft: "3px !important",
+ paddingRight: "3px !important",
+ width: "3%"
},
- "& tr" : {
- padding:"25px 0",
+ "& tr": {
+ padding: "25px 0",
},
- "& p" : {marginTop : "0px !important", marginBottom : "3px !important"},
+ "& p": { marginTop: "0px !important", marginBottom: "3px !important" },
"& tr td:first-child": {
position: "sticky",
left: 0,
@@ -290,7 +299,7 @@ const useStyles = makeStyles((theme) => ({
fontSize: "14px",
color: "#2F9D7E",
fontWeight: "normal",
- margin: "-10px 0 50px 0",
+ margin: "-10px 0 20px 0",
},
radioGroup: {
// marginLeft: -15,
@@ -310,9 +319,9 @@ const useStyles = makeStyles((theme) => ({
borderRadius: "10px",
"& fieldset": { borderWidth: 0 },
},
- required : {
- "& span" : { color: "red"},
- "& sup" : { color: "red"}
+ required: {
+ "& span": { color: "red" },
+ "& sup": { color: "red" }
},
sliderResponse: {
marginTop: "60px",
@@ -329,6 +338,8 @@ const useStyles = makeStyles((theme) => ({
},
},
questionhead: {
+ textAlign: "center",
+ padding: "8px",
"& h5": { fontSize: 18, fontWeight: 600 },
"& span": {
marginTop: 15,
@@ -337,9 +348,9 @@ const useStyles = makeStyles((theme) => ({
lineHeight: "16px !important",
},
},
- checkP:{
+ checkP: {
maxWidth: 65,
- display:"block"
+ display: "block"
},
timeHours: {
padding: 0,
@@ -352,7 +363,7 @@ const useStyles = makeStyles((theme) => ({
centerBar: { height: 4, background: "#BCEFDD" },
customTrack: { width: 4, height: 4, borderRadius: "50%", background: "#65DEB4" },
customThumb: { width: 24, height: 24, marginTop: -10, marginLeft: -10 },
- noInitialVal: {display:"none"},
+ noInitialVal: { display: "none" },
menuPaper: {
background: "#F5F5F5",
boxShadow: "none",
@@ -381,14 +392,14 @@ const useStyles = makeStyles((theme) => ({
listSelected: {
background: "#E7F8F2 !important",
},
- surveyQuestionNav: { textAlign: "center", position: "fixed", width: "100%", bottom: 75,
+ surveyQuestionNav: {
+ textAlign: "center", position: "fixed", width: "100%", bottom: 50,
[`${theme.breakpoints.down('md')} and (orientation: landscape)`]: {
position: "relative",
bottom: 30,
}
- },
+ },
surveyQuestionAlign: {
- textAlign: "center",
"& blockquote": { borderLeft: "5px solid #ccc", margin: "1.5em 10px", padding: "0.5em 10px" },
"& code": {
padding: ".2rem .5rem",
@@ -397,9 +408,9 @@ const useStyles = makeStyles((theme) => ({
whiteSpace: "noWrap",
background: "#F1F1F1",
border: "1px solid #E1E1E1",
- borderRadius: "4px",
+ borderRadius: "4px",
},
- "& ol":{
+ "& ol": {
display: "inline-block",
},
[theme.breakpoints.down("xs")]: {
@@ -420,8 +431,9 @@ const useStyles = makeStyles((theme) => ({
chatDrawerCustom: { minWidth: 411 },
questionScroll: {
- marginTop: 30,
- overflow: "auto",
+ textAlign: "center",
+ maxHeight: "60vh",
+ overflow: "auto",
[theme.breakpoints.down("xs")]: {
overflow: "auto",
},
@@ -447,6 +459,12 @@ const useStyles = makeStyles((theme) => ({
mrgBtm: { marginBottom: 15 },
countlabel: { left: "calc(-50% - -8px)" },
+ thStick: {
+ position: "sticky",
+ left: 0,
+ background: "#fff",
+ zIndex:2,
+ },
}))
function range(start, stop, step = 1) {
@@ -462,17 +480,19 @@ function RateAnswer({ checked, onChange, value }) {
return (
onChange(value)} className={checked ? classes.checkedContainer : classes.uncheckContainer}>
{checked &&
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
}
)
}
-function LinkRenderer(data:any) {
+function LinkRenderer(data: any) {
return {data.children}
}
@@ -519,18 +539,22 @@ function RadioOption({ onChange, options, value, ...props }) {
variant="body2"
style={{ color: selectedValue === `${x.value}` ? "black" : "rgba(0, 0, 0, 0.7)" }}
>
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
}
@@ -550,17 +574,17 @@ function TimeSelection({ onChange, options, value, ...props }) {
const [anchorE3, setAnchorE3] = React.useState(null)
const currentValue = !!value ? value?.split(":") : ""
const [hourSelectedIndex, setHourSelectedIndex] = React.useState(!!value ? currentValue[0] : "01")
- const [minuteSelectedIndex, setMinuteSelectedIndex] = React.useState(!!value ? currentValue[1].substr(0,2) : "00")
- const [ampmSelectedIndex, setAmPmSelectedIndex] = React.useState(!!value ? (currentValue[1].substr(2,3) ?? "") : "AM")
+ const [minuteSelectedIndex, setMinuteSelectedIndex] = React.useState(!!value ? currentValue[1].substr(0, 2) : "00")
+ const [ampmSelectedIndex, setAmPmSelectedIndex] = React.useState(!!value ? (currentValue[1].substr(2, 3) ?? "") : "AM")
const { t } = useTranslation()
useEffect(() => {
- onChange((hourSelectedIndex.length === 1 ? "0" + hourSelectedIndex : hourSelectedIndex ) + ":" +
- (minuteSelectedIndex.length === 1 ? "0" + minuteSelectedIndex : minuteSelectedIndex ) +
- ((!!options?.timePattern && options?.timePattern === "standard") ||
- (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard") ? ampmSelectedIndex : ""))
- }, [hourSelectedIndex, minuteSelectedIndex, ampmSelectedIndex])
-
+ onChange((hourSelectedIndex.length === 1 ? "0" + hourSelectedIndex : hourSelectedIndex) + ":" +
+ (minuteSelectedIndex.length === 1 ? "0" + minuteSelectedIndex : minuteSelectedIndex) +
+ ((!!options?.timePattern && options?.timePattern === "standard") ||
+ (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard") ? ampmSelectedIndex : ""))
+ }, [hourSelectedIndex, minuteSelectedIndex, ampmSelectedIndex])
+
const handleClickHours = (event: React.MouseEvent) => {
setAnchorEl(event.currentTarget)
}
@@ -588,9 +612,9 @@ function TimeSelection({ onChange, options, value, ...props }) {
break
}
onChange((hourSelectedIndex.length === 1 ? "0" + hourSelectedIndex : hourSelectedIndex) +
- ":" + (minuteSelectedIndex.length === 1 ? "0" + minuteSelectedIndex : minuteSelectedIndex) +
- ((!!options?.timePattern && options?.timePattern === "standard") ||
- (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard") ? ampmSelectedIndex : ""))
+ ":" + (minuteSelectedIndex.length === 1 ? "0" + minuteSelectedIndex : minuteSelectedIndex) +
+ ((!!options?.timePattern && options?.timePattern === "standard") ||
+ (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard") ? ampmSelectedIndex : ""))
}
const handleHoursClose = () => {
setAnchorEl(null)
@@ -604,10 +628,10 @@ function TimeSelection({ onChange, options, value, ...props }) {
const ampm = []
const hourvalues = (!!options?.timePattern && options?.timePattern === "standard") ||
- (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard")? range(1,13): range(0, 24)
+ (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard") ? range(1, 13) : range(0, 24)
const minutevalues = ["00", "15", "30", "45"]
- if((!!options?.timePattern && options?.timePattern === "standard") ||
- (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard")) {
+ if ((!!options?.timePattern && options?.timePattern === "standard") ||
+ (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard")) {
ampm.push(
))}
@@ -681,29 +705,29 @@ function TimeSelection({ onChange, options, value, ...props }) {
onClick={(event) => handleMenuItemClick(event, option, 1)}
classes={{ selected: classes.listSelected }}
>
- {option.length === 1 ? "0" + option : option }
+ {option.length === 1 ? "0" + option : option}
))}
{((!!options?.timePattern && options?.timePattern === "standard") ||
- (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard")) && (
-
-
-
-
-
-
- )}
+ (Array.isArray(options) && !!options[0] && !!options[0]?.value && options[0]?.value === "standard")) && (
+
+
+
+
+
+
+ )}
)
@@ -798,13 +822,15 @@ function RadioRating({ onChange, options, value, mtValue, type, ...props }) {
/>
{type !== "matrix" && (
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}}/>
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
- )}
+ )}
))}
@@ -816,7 +842,7 @@ function Rating({ onChange, options, value, ...props }) {
const classes = useStyles()
const getText = (val) => {
let sliderValue = null
- // !!options[0].description && options[0].description.trim().length > 0 ? options[0].description : options[0].value
+ // !!options[0].description && options[0].description.trim().length > 0 ? options[0].description : options[0].value
options.map((mark) => {
if (mark.value === val) {
sliderValue = !!mark.description && mark.description.trim().length > 0 ? mark.description : mark.value
@@ -831,9 +857,9 @@ function Rating({ onChange, options, value, ...props }) {
!!value
? getText(value)
: null
- // : !!options[0].description && options[0].description.trim().length > 0
- // ? options[0].description
- // : options[0].value
+ // : !!options[0].description && options[0].description.trim().length > 0
+ // ? options[0].description
+ // : options[0].value
)
const [sliderValue, setSliderValue] = useState(!!value ? value : null)
@@ -846,7 +872,7 @@ function Rating({ onChange, options, value, ...props }) {
}
const getSliderValue = (val) => {
let sliderValue = null
- // !!options[0].description && options[0].description.trim().length > 0 ? options[0].description : options[0].value
+ // !!options[0].description && options[0].description.trim().length > 0 ? options[0].description : options[0].value
const slValue = val
options.map((mark) => {
if (parseInt(mark.value, 10) === slValue) {
@@ -870,8 +896,8 @@ function Rating({ onChange, options, value, ...props }) {
parseInt(options[0].value, 10) < 0 && parseInt(options[1]?.value, 10 ?? 0) < 0
? Math.abs(parseInt(options[0].value, 10)) + parseInt(options[1]?.value ?? 0, 10)
: parseInt(options[0].value, 10) < 0 && parseInt(options[1].value ?? 0, 10) > 0
- ? Math.abs(parseInt(options[0].value, 10)) - parseInt(options[1]?.value ?? 0, 10)
- : parseInt(options[1]?.value ?? 0, 10) - parseInt(options[0].value, 10)
+ ? Math.abs(parseInt(options[0].value, 10)) - parseInt(options[1]?.value ?? 0, 10)
+ : parseInt(options[1]?.value ?? 0, 10) - parseInt(options[0].value, 10)
}
marks={options}
min={parseInt(options[0].value, 10)}
@@ -881,7 +907,7 @@ function Rating({ onChange, options, value, ...props }) {
root: classes.slider,
rail: classes.centerBar,
mark: classes.customTrack,
- thumb: classes.customThumb + (sliderValue !== null ? "" : " " + classes.noInitialVal),
+ thumb: classes.customThumb + (sliderValue !== null ? "" : " " + classes.noInitialVal),
valueLabel: classes.countlabel,
}}
onChange={(evt, val) => {
@@ -891,39 +917,45 @@ function Rating({ onChange, options, value, ...props }) {
- {
- return {props?.children};
- }, sup: (props) => {
- return {props?.children};
- }}} />
+ : options[0].description} skipHtml={false} plugins={[gfm, emoji]} renderers={{
+ link: LinkRenderer, sub: (props) => {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props?.children};
+ }
+ }} />
{options.length > 2 && (
{
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ : options[Math.ceil(options.length / 2) - 1].description} skipHtml={false} plugins={[gfm, emoji]} renderers={{
+ link: LinkRenderer, sub: (props) => {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
)}
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
-
+ : options[options.length - 1].description} skipHtml={false} plugins={[gfm, emoji]} renderers={{
+ link: LinkRenderer, sub: (props) => {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
+
@@ -932,11 +964,13 @@ function Rating({ onChange, options, value, ...props }) {
{t("Your response")}:
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
@@ -955,7 +989,7 @@ function Rating({ onChange, options, value, ...props }) {
const csvParse = (x) => (Array.isArray(JSON.parse(`[${x}]`)) ? JSON.parse(`[${x}]`) : [])
const csvStringify = (x) => (Array.isArray(x) ? JSON.stringify(x).slice(1, -1) : "")
-function Matrix({ x, responses, onResponse, activityId, total,index, idx,startTime, setActiveStep,settingsQuestions, handleBack,
+function Matrix({ x, responses, onResponse, activityId, total, index, idx, startTime, setActiveStep, settingsQuestions, handleBack,
handleNext, onComplete, ...props }) {
const classes = useStyles()
const { t } = useTranslation()
@@ -963,214 +997,225 @@ function Matrix({ x, responses, onResponse, activityId, total,index, idx,startTi
const [selectedValue, setSelectedValue] = useState(responses?.current ?? null)
const getSorted = (options) => {
return options.sort((a, b) =>
- parseInt(a.value, 10) > parseInt(b.value, 10) ? 1 : parseInt(a.value, 10) < parseInt(b.value, 10) ? -1 : 0
- )
+ parseInt(a.value, 10) > parseInt(b.value, 10) ? 1 : parseInt(a.value, 10) < parseInt(b.value, 10) ? -1 : 0
+ )
}
return (
-
-
-
- {`${t("Question")}`} {(index + 1)} {`${t("of")}`} {settingsQuestions}
-
-
-
-
+
+
+
+ {`${t("Question")}`} {(index + 1)} {`${t("of")}`} {settingsQuestions}
+
+
-
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
-
-
-
-
-
- {Array.isArray(x.options) && x.options.length > 0 && (x.type === "likert" || x.type === "rating" || x.type === "list" ||x.type === "boolean" || x.type === "multiselect") && (
-
- {null}
- {(x.options || []).map((x) => (
-
- {(x.description || "").length > 0 && {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />}
-
- ))}
- )}
- {Array.isArray(x.options) && x.options.length > 0 && (x.type === "likert" || x.type === "rating" || x.type === "list" ||x.type === "boolean" || x.type === "multiselect") && (
-
- {null}
- {(x.options || []).map((x) => (
-
- 0 && (x.value || "").length > 0 ? `(${t(x.value?.toString())})` : `${t(x.value?.toString())}`} skipHtml={false} plugins={[gfm, emoji]} renderers={{ link: LinkRenderer, sub: (props) => {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
-
- ))}
- )}
- {(x.questions || []).map((question, qindex) => (
-
-
- *`:`${t(question.text)}`} allowDangerousHtml={true} plugins={[gfm, emoji]} renderers={{ link: LinkRenderer, span: (props) => {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
-
- {(Array.isArray(x.options) && (x.options || []).length > 0) ?(
- x.type === "list" ||x.type === "boolean" || x.type === "likert" ? (
- (x.options || []).map((op, k) => (
-
- }
- icon={}
- onClick={() => {
- setSelectedValue({...selectedValue, [idx+qindex]: {item: question.text, value:csvStringify([op.value])}})
- const response = { item: question.text, value: csvStringify([op.value]) }
- const data = updateResponses(x, response,activityId, responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }}
- />
- }
- label={null}
- />
-
- ))
-) :x.type === "multiselect" ? ((x.options || []).map((op, j) => (
-
- {
- let values = csvParse(selectedValue[idx+qindex]?.value || [])
-
- if(!csvParse(selectedValue[idx+qindex]?.value || []).includes(op.value)) {
- values.push(op.value)
- values = (values || []).filter((elem, i, self) => {
- return i === self.indexOf(elem);
- })
- } else {
- const key = values.indexOf(op.value);
- if (key !== -1) {
- values.splice(key, 1);
- }
- }
- setSelectedValue({...selectedValue, [idx+qindex]: {item: question.text,value:csvStringify(values)}})
- const response = { item: question.text, value: csvStringify(values) }
- const data = updateResponses(x, response, activityId,responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }}
- />
- }
- label={null}
- />
-
- ))
-)
- : x.type === "slider" ? (
-
- {
- setSelectedValue({...selectedValue, [idx+qindex]: {item: question.text, value:csvStringify([val])}})
- const response = { item: question.text, value: val !== null ? csvStringify([val]) : null }
- const data = updateResponses(x, response, activityId,responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }} value={csvParse(selectedValue[idx+qindex]?.value || [])[0]?? null} />
-
- ) : x.type === "rating" ?
- ((x.options || []).map((op, j) => (
-
- {
- setSelectedValue({...selectedValue, [idx+qindex]: {item: question.text, value:csvStringify([val])}})
- const response = { item: question.text, value: val !== null ? csvStringify([val]) : null }
- const data = updateResponses(x, response, activityId,responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }}
- value={op.value}
- />
-
-
- ))):x.type === "time"?(
-
- {
- const response = { item: question.text, value: val }
- const data = updateResponses(x, response, activityId,responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }} options={x.options} value={!!responses?.current[idx+qindex]?.value ? responses?.current[idx+qindex]?.value : undefined} />
- ) : null ) :
- (
-
- {
-
- x?.type === "short" ?
- (
- {
- const response = { item: question.text, value: val }
- const data = updateResponses(x, response, activityId,responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }} value={!!responses?.current[idx+qindex]?.value ? responses?.current[idx+qindex]?.value : undefined} />
- )
- :x.type === "text"?(
- {
- const response = { item: question.text, value: val }
- const data = updateResponses(x, response, activityId,responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }} charLimit={CHARACTER_LIMIT} value={!!responses?.current[idx+qindex]?.value ? responses?.current[idx+qindex]?.value : undefined} />
- ):
- x.type === "time"?(
-
- {
- const response = { item: question.text, value: val }
- const data = updateResponses(x, response, activityId,responses, idx+qindex, startTime, setActiveStep, total)
- onResponse(data)
- }} options={x.options} value={!!responses?.current[idx+qindex]?.value ? responses?.current[idx+qindex]?.value : undefined} />
- ):
- null
+
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
}
-
- )
- }
-
-
- ))}
-
-
-
+ }} />
+
+
+
+
+
+
+
+
+ {Array.isArray(x.options) && x.options.length > 0 && (x.type === "likert" || x.type === "rating" || x.type === "list" || x.type === "boolean" || x.type === "multiselect") && (
+
+ {null}
+ {(x.options || []).map((x) => (
+
+ {(x.description || "").length > 0 && {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />}
+
+ ))}
+ )}
+
+ {Array.isArray(x.options) && x.options.length > 0 && (x.type === "likert" || x.type === "rating" || x.type === "list" || x.type === "boolean" || x.type === "multiselect") && (
+
+ {null}
+ {(x.options || []).map((x) => (
+
+ 0 && (x.value || "").length > 0 ? `(${t(x.value?.toString())})` : `${t(x.value?.toString())}`} skipHtml={false} plugins={[gfm, emoji]} renderers={{
+ link: LinkRenderer, sub: (props) => {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
+
+ ))}
+ )}
+
+ {(x.questions || []).map((question, qindex) => (
+
+
+ *` : `${t(question.text)}`} allowDangerousHtml={true} plugins={[gfm, emoji]} renderers={{
+ link: LinkRenderer, span: (props) => {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
+
+ {(Array.isArray(x.options) && (x.options || []).length > 0) ? (
+ x.type === "list" || x.type === "boolean" || x.type === "likert" ? (
+ (x.options || []).map((op, k) => (
+
+ }
+ icon={}
+ onClick={() => {
+ setSelectedValue({ ...selectedValue, [idx + qindex]: { item: question.text, value: csvStringify([op.value]) } })
+ const response = { item: question.text, value: csvStringify([op.value]) }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }}
+ />
+ }
+ label={null}
+ />
+
+ ))
+ ) : x.type === "multiselect" ? ((x.options || []).map((op, j) => (
+
+ {
+ let values = csvParse(selectedValue[idx + qindex]?.value || [])
+
+ if (!csvParse(selectedValue[idx + qindex]?.value || []).includes(op.value)) {
+ values.push(op.value)
+ values = (values || []).filter((elem, i, self) => {
+ return i === self.indexOf(elem);
+ })
+ } else {
+ const key = values.indexOf(op.value);
+ if (key !== -1) {
+ values.splice(key, 1);
+ }
+ }
+ setSelectedValue({ ...selectedValue, [idx + qindex]: { item: question.text, value: csvStringify(values) } })
+ const response = { item: question.text, value: csvStringify(values) }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }}
+ />
+ }
+ label={null}
+ />
+
+ ))
+ )
+ : x.type === "slider" ? (
+
+ {
+ setSelectedValue({ ...selectedValue, [idx + qindex]: { item: question.text, value: csvStringify([val]) } })
+ const response = { item: question.text, value: val !== null ? csvStringify([val]) : null }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }} value={csvParse(selectedValue[idx + qindex]?.value || [])[0] ?? null} />
+
+ ) : x.type === "rating" ?
+ ((x.options || []).map((op, j) => (
+
+ {
+ setSelectedValue({ ...selectedValue, [idx + qindex]: { item: question.text, value: csvStringify([val]) } })
+ const response = { item: question.text, value: val !== null ? csvStringify([val]) : null }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }}
+ value={op.value}
+ />
+
+
+ ))) : x.type === "time" ? (
+
+ {
+ const response = { item: question.text, value: val }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }} options={x.options} value={!!responses?.current[idx + qindex]?.value ? responses?.current[idx + qindex]?.value : undefined} />
+ ) : null) :
+ (
+
+ {
+
+ x?.type === "short" ?
+ (
+ {
+ const response = { item: question.text, value: val }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }} value={!!responses?.current[idx + qindex]?.value ? responses?.current[idx + qindex]?.value : undefined} />
+ )
+ : x.type === "text" ? (
+ {
+ const response = { item: question.text, value: val }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }} charLimit={CHARACTER_LIMIT} value={!!responses?.current[idx + qindex]?.value ? responses?.current[idx + qindex]?.value : undefined} />
+ ) :
+ x.type === "time" ? (
+
+ {
+ const response = { item: question.text, value: val }
+ const data = updateResponses(x, response, activityId, responses, idx + qindex, startTime, setActiveStep, total)
+ onResponse(data)
+ }} options={x.options} value={!!responses?.current[idx + qindex]?.value ? responses?.current[idx + qindex]?.value : undefined} />
+ ) :
+ null
+ }
+
+ )
+ }
+
+
+ ))}
+
+
+
+
{supportsSidebar && index === settingsQuestions - 1 && (
{t("Submit")}
)}
-
-
-
+
+
)
}
@@ -1188,7 +1233,7 @@ function MultiSelectResponse({ onChange, options, value, ...props }) {
root: classes.fieldGroup,
}}
>
- {options.map((x) => (
+ {options.map((x) => (
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
}
@@ -1301,33 +1350,35 @@ function Question({ onResponse, text, desc, required, type, options, value, star
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
{!!required && *}
-
+
0
- ? options[0].description
- : options[0].value
- },
- ${options[options.length - 1].value} being ${
- !!options[options.length - 1].description && options[options.length - 1].description.trim().length > 0
- ? options[options.length - 1].description
- : options[options.length - 1].value
- }`
- )
- : !!desc && t(`${desc}`) } skipHtml={false} plugins={[gfm, emoji]} renderers={{ link: LinkRenderer, sub: (props) => {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ `${options[0].value} being ${!!options[0].description && options[0].description.trim().length > 0
+ ? options[0].description
+ : options[0].value
+ },
+ ${options[options.length - 1].value} being ${!!options[options.length - 1].description && options[options.length - 1].description.trim().length > 0
+ ? options[options.length - 1].description
+ : options[options.length - 1].value
+ }`
+ )
+ : !!desc && t(`${desc}`)} skipHtml={false} plugins={[gfm, emoji]} renderers={{
+ link: LinkRenderer, sub: (props) => {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
{component}
@@ -1357,7 +1408,7 @@ function Questions({
- {`${t("Question")}`} {(index + 1)} {`${t("of")}`} {settings.length}
+ {`${t("Question")}`} {(index + 1)} {`${t("of")}`} {settings.length}
@@ -1371,7 +1422,7 @@ function Questions({
options={Array.isArray(x.options) ? x.options?.map((y) => ({ ...y, label: y.value })) : x.options}
value={responses.current[idx] ?? null}
onResponse={(response) => {
- const data = updateResponses(x, response, activityId,responses, idx, startTime, setActiveStep, totalQuestions)
+ const data = updateResponses(x, response, activityId, responses, idx, startTime, setActiveStep, totalQuestions)
onResponse(data)
}}
startTime={new Date().getTime()}
@@ -1390,27 +1441,27 @@ function Questions({
}
const updateResponses = (x, response, activityId, responses, idx, startTime, setActiveStep, total) => {
- responses.current[idx] = response
- if (x.type !== "multiselect") {
- setActiveStep((prev) => prev + 1)
- }
- response.duration = new Date().getTime() - startTime
+ responses.current[idx] = response
+ if (x.type !== "multiselect") {
+ setActiveStep((prev) => prev + 1)
+ }
+ response.duration = new Date().getTime() - startTime
- response.endTime = new Date().getTime()
- response.type = null
- response.level = null
-
- localStorage.setItem("activity-survey-"+ activityId, JSON.stringify(Array.from({
+ response.endTime = new Date().getTime()
+ response.type = null
+ response.level = null
+
+ localStorage.setItem("activity-survey-" + activityId, JSON.stringify(Array.from({
+ ...responses.current,
+ length: total,
+ })))
+ return (
+ Array.from({
...responses.current,
length: total,
- })))
- return (
- Array.from({
- ...responses.current,
- length: total,
- })
- )
- }
+ })
+ )
+}
function Section({
onResponse,
@@ -1423,9 +1474,9 @@ function Section({
...props
}) {
const activityId = value?.id
- const base = value.settings.map((x, index) => (
- !!activityVal && activityVal[index] ?
- activityVal[index] : { item: x.text, value: null, duration: 0 }))
+ const base = value.settings.map((x, index) => (
+ !!activityVal && activityVal[index] ?
+ activityVal[index] : { item: x.text, value: null, duration: 0 }))
const responses = useRef(base)
const [activeStep, setActiveStep] = useState(0)
const classes = useStyles()
@@ -1440,46 +1491,46 @@ function Section({
const calcIndex = (idx) => {
let index = 0
- ;(settings || []).map((x, i) => {
- if(i < idx) {
- if(!!x.questions && x.questions.length > 0) {
- index = index + x.questions.length
- } else {
- index++
+ ; (settings || []).map((x, i) => {
+ if (i < idx) {
+ if (!!x.questions && x.questions.length > 0) {
+ index = index + x.questions.length
+ } else {
+ index++
+ }
}
- }
- })
+ })
return index
}
// Force creation of result data whether survey was interacted with or not.
useEffect(() => {
- if (slideElements === null) {
- let index = 0
+ if (slideElements === null) {
+ let index = 0
const slideElements = (settings || []).map((x, idx) => {
setElementIn(true)
index = calcIndex(idx)
return (
- {!!x.questions && x.questions.length > 0 ?
- 0 ?
+ :
+ /> :
- }
+ }
- )
+ )
})
setSlideElements(slideElements)
}
@@ -1522,43 +1573,43 @@ function Section({
const handleNext = () => {
const actualIndex = calcIndex(index)
- if(settings[index].subType === "matrix") {
+ if (settings[index].subType === "matrix") {
let i = 0;
let status = true
- for (const element of settings[index].questions){
- if(!(!element.required || (element.required && (responses?.current[actualIndex+i]?.value !== null && typeof responses?.current[actualIndex+i]?.value !== "undefined" &&
- (typeof responses?.current[actualIndex+i]?.value !== "string" || (typeof responses?.current[actualIndex+i]?.value === "string" &&
- responses?.current[actualIndex+i]?.value?.trim().length !== 0)))))) {
+ for (const element of settings[index].questions) {
+ if (!(!element.required || (element.required && (responses?.current[actualIndex + i]?.value !== null && typeof responses?.current[actualIndex + i]?.value !== "undefined" &&
+ (typeof responses?.current[actualIndex + i]?.value !== "string" || (typeof responses?.current[actualIndex + i]?.value === "string" &&
+ responses?.current[actualIndex + i]?.value?.trim().length !== 0)))))) {
enqueueSnackbar(t("Please enter your response."), {
variant: "error",
- })
+ })
status = false
break
}
i++
}
- if(!!status) {
+ if (!!status) {
slideElementChange(1)
}
} else {
- if(!value.settings[actualIndex].required || (value.settings[actualIndex].required && (responses?.current[actualIndex]?.value !== null && typeof responses.current[actualIndex].value !== "undefined" &&
- (typeof responses?.current[actualIndex]?.value !== "string" || (typeof responses?.current[actualIndex]?.value === "string" &&
- responses?.current[actualIndex]?.value?.trim().length !== 0))))) {
- slideElementChange(1)
- } else {
- enqueueSnackbar(t("Please enter your response."), {
- variant: "error",
- })
+ if (!value.settings[actualIndex].required || (value.settings[actualIndex].required && (responses?.current[actualIndex]?.value !== null && typeof responses.current[actualIndex].value !== "undefined" &&
+ (typeof responses?.current[actualIndex]?.value !== "string" || (typeof responses?.current[actualIndex]?.value === "string" &&
+ responses?.current[actualIndex]?.value?.trim().length !== 0))))) {
+ slideElementChange(1)
+ } else {
+ enqueueSnackbar(t("Please enter your response."), {
+ variant: "error",
+ })
+ }
}
}
- }
const tabDirection = (currentTab) => {
return supportsSidebar ? "up" : "left"
}
const handleChange = (event) => {
const target = event.target
- // if (target.getAttribute("role") === "dialog") {
+ // if (target.getAttribute("role") === "dialog") {
// const progressVal = (target.scrollTop / (target.scrollHeight - target.clientHeight)) * 100
// setProgressValue(progressVal + 10 > 100 ? progressVal : progressVal + 10)
// }
@@ -1566,17 +1617,19 @@ function Section({
return (
-
+
{!noBack && onResponse(null)}>
arrow_back
}
- {
- return {props?.children};
- }, sup: (props) => {
- return {props.children};
- }}} />
+ {
+ return {props?.children};
+ }, sup: (props) => {
+ return {props.children};
+ }
+ }} />
@@ -1584,37 +1637,37 @@ function Section({
{supportsSidebar ? (
settings.map((x, idx) => (
- {!!x.questions && x.questions.length > 0 ?
- 0 ?
+ :
- }
+ /> :
+ }
))
) : (
@@ -1645,7 +1698,7 @@ function Section({
)
}
-export default function SurveyQuestions({...props}) {
+export default function SurveyQuestions({ ...props }) {
const classes = useStyles()
const { t } = useTranslation()
const [responses, setResponses] = useState(null)
@@ -1661,39 +1714,39 @@ export default function SurveyQuestions({...props}) {
let status = true
const questions = activity.settings
let i = 0
- if(response === null) {
+ if (response === null) {
return false
}
for (const question of questions) {
- if(!question.required || (!!question.required && (!!response && !!response[i] && response[i]?.value !== null &&
+ if (!question.required || (!!question.required && (!!response && !!response[i] && response[i]?.value !== null &&
typeof response[i]?.value !== "undefined" && (typeof response[i]?.value !== "string" ||
- (typeof response[i]?.value === "string" && response[i]?.value?.trim().length !== 0))))) {
- status = true
+ (typeof response[i]?.value === "string" && response[i]?.value?.trim().length !== 0))))) {
+ status = true
} else {
status = false
break
}
i++
}
- return status
+ return status
}
const postSubmit = (response) => {
- if(validator(response)) {
+ if (validator(response)) {
response.map((r) => {
delete r.endTime
})
const result = {
temporal_slices: response,
- duration : new Date().getTime() - startTime,
+ duration: new Date().getTime() - startTime,
static_data: {},
timestamp: startTime
}
- onResponse(result)
+ onResponse(result)
} else {
enqueueSnackbar(t("Some responses are missing. Please complete all required questions before submitting."), {
variant: "error",
- })
+ })
}
}
const onResponse = (response) => {
@@ -1704,31 +1757,31 @@ export default function SurveyQuestions({...props}) {
}
const loadData = (statusVal: boolean) => {
- if(!!statusVal) {
- const val = localStorage.getItem("activity-survey-" +(props.data?.activity?.id ?? ""))
+ if (!!statusVal) {
+ const val = localStorage.getItem("activity-survey-" + (props.data?.activity?.id ?? ""))
setActivityVal(JSON.parse(val))
} else {
- localStorage.setItem('activity-survey-'+(props.data?.activity?.id ?? ""), "")
+ localStorage.setItem('activity-survey-' + (props.data?.activity?.id ?? ""), "")
}
const activity = props.data.activity ?? (props.data ?? {});
setActivity(activity);
setConfirm(false)
}
-
+
useEffect(() => {
- if(typeof localStorage.getItem('activity-survey-'+(props.data?.activity?.id ?? "")) !== 'undefined' &&
- (localStorage.getItem('activity-survey-'+(props.data?.activity?.id ?? ""))?.trim()?.length ?? 0) > 0) {
+ if (typeof localStorage.getItem('activity-survey-' + (props.data?.activity?.id ?? "")) !== 'undefined' &&
+ (localStorage.getItem('activity-survey-' + (props.data?.activity?.id ?? ""))?.trim()?.length ?? 0) > 0) {
setConfirm(true)
- } else {
+ } else {
const activity = props.data.activity ?? (props.data ?? {});
setActivity(activity);
}
- const configuration = props.data.configuration;
+ const configuration = props.data.configuration;
i18n.changeLanguage(!!configuration ? configuration?.language : "en-US");
}, [])
useEffect(() => {
- if(!!activity) {
+ if (!!activity) {
setQuestions()
}
}, [activity])
@@ -1737,7 +1790,7 @@ export default function SurveyQuestions({...props}) {
{ description: t("Yes"), value: "Yes" /* true */ },
{ description: t("No"), value: "No" /* false */ },
]
-
+
const likertOpts = [
{ description: t("Nearly All the Time"), value: 3 },
{ description: t("More than Half the Time"), value: 2 },
@@ -1746,57 +1799,57 @@ export default function SurveyQuestions({...props}) {
]
const setQuestions = () => {
- const settings = []
- const processed = []
- ;(activity.settings || []).map((question, index) => {
- if( !processed.includes(index)) {
- if(activity.settings[index+1]?.type === "matrix" || (index === 0 && question?.type === "matrix")) {
+ const settings = []
+ const processed = []
+ ; (activity.settings || []).map((question, index) => {
+ if (!processed.includes(index)) {
+ if (activity.settings[index + 1]?.type === "matrix" || (index === 0 && question?.type === "matrix")) {
const desc = question?.description ?? ""
const options = question?.type === "boolean" ? binaryOpts : question?.type === "likert" ? likertOpts : question?.options ?? []
const questions = []
- for (let k=index; k < activity.settings.length; k++) {
- if(k === index || (activity.settings[k]?.type === "matrix")){
- questions.push({text: activity.settings[k].text, required: activity.settings[k].required})
+ for (let k = index; k < activity.settings.length; k++) {
+ if (k === index || (activity.settings[k]?.type === "matrix")) {
+ questions.push({ text: activity.settings[k].text, required: activity.settings[k].required })
processed.push(k)
} else {
break
}
}
const type = index === 0 && question?.type === "matrix" ? "text" : question.type
- settings.push({type, subType:"matrix", description: desc, options, questions})
+ settings.push({ type, subType: "matrix", description: desc, options, questions })
} else {
settings.push(question)
}
}
})
- setSettings(settings)
+ setSettings(settings)
}
return (
-
-
+ setConfirm(false)}
open={confirm}
- confirmAction={loadData}
- confirmationMsg={t("Would you like to resume this activity where you left off?")}/>
-
+ confirmAction={loadData}
+ confirmationMsg={t("Would you like to resume this activity where you left off?")} />
+
{(activity !== null && settings !== null) ?
+ onResponse={(response) =>
(response === null) ? onResponse(null) :
- setResponses(response)
+ setResponses(response)
}
value={activity}
activityVal={activityVal}
settings={settings}
totalQuestions={(activity?.settings || []).length}
- noBack= {props.data.noBack}
- onComplete={() =>{
+ noBack={props.data.noBack}
+ onComplete={() => {
postSubmit(responses)
}}
- /> : null }
+ /> : null}
)
}
\ No newline at end of file