mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-06-03 08:24:38 -04:00
fix: [UEPR-177] prevent multiple submission of feedback answers
This commit is contained in:
commit
8a73da07b1
15 changed files with 115 additions and 86 deletions
9
.github/workflows/ci-cd.yml
vendored
9
.github/workflows/ci-cd.yml
vendored
|
@ -84,11 +84,12 @@ jobs:
|
||||||
ONBOARDING_TESTING_ENDING_DATE: "${{ vars.ONBOARDING_TESTING_ENDING_DATE }}"
|
ONBOARDING_TESTING_ENDING_DATE: "${{ vars.ONBOARDING_TESTING_ENDING_DATE }}"
|
||||||
QUALITATIVE_FEEDBACK_ACTIVE: "${{ vars.QUALITATIVE_FEEDBACK_ACTIVE }}"
|
QUALITATIVE_FEEDBACK_ACTIVE: "${{ vars.QUALITATIVE_FEEDBACK_ACTIVE }}"
|
||||||
QUALITATIVE_FEEDBACK_STARTING_DATE: "${{ vars.QUALITATIVE_FEEDBACK_STARTING_DATE }}"
|
QUALITATIVE_FEEDBACK_STARTING_DATE: "${{ vars.QUALITATIVE_FEEDBACK_STARTING_DATE }}"
|
||||||
QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_RATE: "${{ vars.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_RATE }}"
|
QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_FREQUENCY: "${{ vars.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_FREQUENCY }}"
|
||||||
QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_RATE: "${{ vars.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_RATE }}"
|
QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_FREQUENCY: "${{ vars.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_FREQUENCY }}"
|
||||||
QUALITATIVE_FEEDBACK_DEBUGGING_USER_RATE: "${{ vars.QUALITATIVE_FEEDBACK_DEBUGGING_USER_RATE }}"
|
QUALITATIVE_FEEDBACK_DEBUGGING_USER_FREQUENCY: "${{ vars.QUALITATIVE_FEEDBACK_DEBUGGING_USER_FREQUENCY }}"
|
||||||
QUALITATIVE_FEEDBACK_TUTORIALS_USER_RATE: "${{ vars.QUALITATIVE_FEEDBACK_TUTORIALS_USER_RATE }}"
|
QUALITATIVE_FEEDBACK_TUTORIALS_USER_FREQUENCY: "${{ vars.QUALITATIVE_FEEDBACK_TUTORIALS_USER_FREQUENCY }}"
|
||||||
QUALITATIVE_FEEDBACK_ENDING_DATE: "${{ vars.QUALITATIVE_FEEDBACK_ENDING_DATE }}"
|
QUALITATIVE_FEEDBACK_ENDING_DATE: "${{ vars.QUALITATIVE_FEEDBACK_ENDING_DATE }}"
|
||||||
|
IDEAS_GENERATOR_SOURCE: "${{ vars.IDEAS_GENERATOR_SOURCE }}"
|
||||||
|
|
||||||
# used by src/template-config.js
|
# used by src/template-config.js
|
||||||
GTM_ID: ${{ secrets.GTM_ID }}
|
GTM_ID: ${{ secrets.GTM_ID }}
|
||||||
|
|
|
@ -59,9 +59,11 @@ const Carousel = props => {
|
||||||
href = `/studios/${item.id}/`;
|
href = `/studios/${item.id}/`;
|
||||||
break;
|
break;
|
||||||
case 'project':
|
case 'project':
|
||||||
href = props.fromStarterProjectsPage ?
|
href = `/projects/${item.id}${
|
||||||
`/projects/${item.id}?fromStarterProjectsPage=${props.fromStarterProjectsPage}` :
|
props.fromStarterProjectsPage ?
|
||||||
`/projects/${item.id}/`;
|
'?fromStarterProjectsPage=true' :
|
||||||
|
''
|
||||||
|
}`;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
href = `/${item.type}/${item.id}/`;
|
href = `/${item.type}/${item.id}/`;
|
||||||
|
|
|
@ -4,8 +4,8 @@ import {hideQualitativeFeedback} from '../../../redux/qualitative-feedback.js';
|
||||||
import {
|
import {
|
||||||
QUALITATIVE_FEEDBACK_DATA,
|
QUALITATIVE_FEEDBACK_DATA,
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID
|
QUALITATIVE_FEEDBACK_QUESTION_ID
|
||||||
} from './qualitative_feedback_data.js';
|
} from './qualitative-feedback-data.js';
|
||||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
import {QualitativeFeedback} from './qualitative-feedback.jsx';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import {hideQualitativeFeedback} from '../../../redux/qualitative-feedback.js';
|
||||||
import {
|
import {
|
||||||
QUALITATIVE_FEEDBACK_DATA,
|
QUALITATIVE_FEEDBACK_DATA,
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID
|
QUALITATIVE_FEEDBACK_QUESTION_ID
|
||||||
} from './qualitative_feedback_data.js';
|
} from './qualitative-feedback-data.js';
|
||||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
import {QualitativeFeedback} from './qualitative-feedback.jsx';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ import {Formik} from 'formik';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import FormikRadioButton from '../../formik-forms/formik-radio-button.jsx';
|
import FormikRadioButton from '../../formik-forms/formik-radio-button.jsx';
|
||||||
|
|
||||||
import './qualitative_feedback.scss';
|
import './qualitative-feedback.scss';
|
||||||
|
|
||||||
const FeedbackOption = ({
|
const FeedbackOption = ({
|
||||||
id,
|
id,
|
||||||
|
@ -45,7 +45,12 @@ FeedbackOption.propTypes = {
|
||||||
value: PropTypes.string
|
value: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen, sendGAEvent}) => {
|
export const QualitativeFeedback = ({
|
||||||
|
feedbackData,
|
||||||
|
hideFeedback,
|
||||||
|
isOpen,
|
||||||
|
sendGAEvent
|
||||||
|
}) => {
|
||||||
const [displayModal, setDisplayModal] = useState(false);
|
const [displayModal, setDisplayModal] = useState(false);
|
||||||
const [_, setFilledFeedback] = useLocalStorage(
|
const [_, setFilledFeedback] = useLocalStorage(
|
||||||
feedbackData.questionId,
|
feedbackData.questionId,
|
||||||
|
@ -54,23 +59,37 @@ export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen, sendGAE
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const onClose = useCallback(() => {
|
const onClose = useCallback(() => {
|
||||||
sendGAEvent('closed');
|
if (displayModal) {
|
||||||
|
setDisplayModal(false);
|
||||||
|
sendGAEvent('closed');
|
||||||
|
}
|
||||||
|
|
||||||
setFilledFeedback(true);
|
setFilledFeedback(true);
|
||||||
hideFeedback();
|
hideFeedback();
|
||||||
setDisplayModal(false);
|
}, [
|
||||||
}, [setFilledFeedback, hideFeedback, setDisplayModal]);
|
displayModal,
|
||||||
|
setFilledFeedback,
|
||||||
|
hideFeedback,
|
||||||
|
setDisplayModal,
|
||||||
|
sendGAEvent
|
||||||
|
]);
|
||||||
|
|
||||||
// TBD: add logic for sending events to GA
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
formData => {
|
formData => {
|
||||||
if (formData.feedback) {
|
if (formData.feedback && displayModal) {
|
||||||
|
setDisplayModal(false);
|
||||||
sendGAEvent(formData.feedback);
|
sendGAEvent(formData.feedback);
|
||||||
setFilledFeedback(true);
|
setFilledFeedback(true);
|
||||||
hideFeedback();
|
hideFeedback();
|
||||||
setDisplayModal(false);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[hideFeedback, setDisplayModal, setFilledFeedback]
|
[
|
||||||
|
displayModal,
|
||||||
|
hideFeedback,
|
||||||
|
setDisplayModal,
|
||||||
|
setFilledFeedback,
|
||||||
|
sendGAEvent
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -78,7 +97,7 @@ export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen, sendGAE
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
setDisplayModal(true);
|
setDisplayModal(true);
|
||||||
}, 5000);
|
}, 5000);
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}
|
}
|
||||||
}, [isOpen]);
|
}, [isOpen]);
|
||||||
|
@ -102,33 +121,31 @@ export const QualitativeFeedback = ({feedbackData, hideFeedback, isOpen, sendGAE
|
||||||
}}
|
}}
|
||||||
onSubmit={onSubmit}
|
onSubmit={onSubmit}
|
||||||
>
|
>
|
||||||
{({handleSubmit, setFieldValue, values}) =>
|
{({handleSubmit, setFieldValue, values}) => (
|
||||||
(
|
<form
|
||||||
<form
|
className="feedback-form"
|
||||||
className="feedback-form"
|
onSubmit={handleSubmit}
|
||||||
onSubmit={handleSubmit}
|
>
|
||||||
>
|
<div className="feedback-question">
|
||||||
<div className="feedback-question">
|
<FormattedMessage id={feedbackData.questionId} />
|
||||||
<FormattedMessage id={feedbackData.questionId} />
|
</div>
|
||||||
</div>
|
<div className="feedback-options">
|
||||||
<div className="feedback-options">
|
{feedbackData.options.map(option => (
|
||||||
{feedbackData.options.map(option => (
|
<FeedbackOption
|
||||||
<FeedbackOption
|
key={option.value}
|
||||||
key={option.value}
|
id={option.label}
|
||||||
id={option.label}
|
label={intl.formatMessage({id: option.label})}
|
||||||
label={intl.formatMessage({id: option.label})}
|
selectedValue={values.feedback}
|
||||||
selectedValue={values.feedback}
|
value={option.value}
|
||||||
value={option.value}
|
onSetFieldValue={setFieldValue}
|
||||||
onSetFieldValue={setFieldValue}
|
/>
|
||||||
/>
|
))}
|
||||||
))}
|
</div>
|
||||||
</div>
|
<Button className="feedback-submit">
|
||||||
<Button className="feedback-submit">
|
<FormattedMessage id="feedback.submit" />
|
||||||
<FormattedMessage id="feedback.submit" />
|
</Button>
|
||||||
</Button>
|
</form>
|
||||||
</form>
|
)}
|
||||||
)
|
|
||||||
}
|
|
||||||
</Formik>
|
</Formik>
|
||||||
</ModalInnerContent>
|
</ModalInnerContent>
|
||||||
</Modal>
|
</Modal>
|
|
@ -4,8 +4,8 @@ import {hideQualitativeFeedback} from '../../../redux/qualitative-feedback.js';
|
||||||
import {
|
import {
|
||||||
QUALITATIVE_FEEDBACK_DATA,
|
QUALITATIVE_FEEDBACK_DATA,
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID
|
QUALITATIVE_FEEDBACK_QUESTION_ID
|
||||||
} from './qualitative_feedback_data.js';
|
} from './qualitative-feedback-data.js';
|
||||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
import {QualitativeFeedback} from './qualitative-feedback.jsx';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ const StarterProjectsFeedback = ({hideFeedback, isOpen, projectName}) => {
|
||||||
projectName: projectName,
|
projectName: projectName,
|
||||||
feedbackResponse: data
|
feedbackResponse: data
|
||||||
}),
|
}),
|
||||||
[]
|
[projectName]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,8 +4,8 @@ import {hideQualitativeFeedback} from '../../../redux/qualitative-feedback.js';
|
||||||
import {
|
import {
|
||||||
QUALITATIVE_FEEDBACK_DATA,
|
QUALITATIVE_FEEDBACK_DATA,
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID
|
QUALITATIVE_FEEDBACK_QUESTION_ID
|
||||||
} from './qualitative_feedback_data.js';
|
} from './qualitative-feedback-data.js';
|
||||||
import {QualitativeFeedback} from './qualitative_feedback.jsx';
|
import {QualitativeFeedback} from './qualitative-feedback.jsx';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
import {triggerAnalyticsEvent} from '../../../lib/google-analytics-utils.js';
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,13 @@ const isCurrentDayInRange = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasGivenFeedback = feedbackQuestionId =>
|
const notRespondedToFeedback = feedbackQuestionId =>
|
||||||
localStorageAvailable && localStorage.getItem(feedbackQuestionId) !== 'true';
|
localStorageAvailable && localStorage.getItem(feedbackQuestionId) !== 'true';
|
||||||
|
|
||||||
const canShowFeedbackWidget = feedbackUserRate => {
|
const canShowFeedbackWidget = feedbackUserRate => {
|
||||||
|
// randomNumber will be in the range [0, feedbackUserRate - 1]
|
||||||
|
// and we are assering against one number from the range
|
||||||
|
// this way we simulate picking one from n users
|
||||||
const randomNum = Math.floor(
|
const randomNum = Math.floor(
|
||||||
Math.random() * feedbackUserRate
|
Math.random() * feedbackUserRate
|
||||||
);
|
);
|
||||||
|
@ -35,11 +38,11 @@ const isUserEligibleForFeedback = (user, permissions, feedbackQuestionId, feedba
|
||||||
JSON.parse(process.env.QUALITATIVE_FEEDBACK_ACTIVE) &&
|
JSON.parse(process.env.QUALITATIVE_FEEDBACK_ACTIVE) &&
|
||||||
canShowFeedbackWidget(feedbackUserRate) &&
|
canShowFeedbackWidget(feedbackUserRate) &&
|
||||||
isCurrentDayInRange() &&
|
isCurrentDayInRange() &&
|
||||||
hasGivenFeedback(feedbackQuestionId)
|
notRespondedToFeedback(feedbackQuestionId)
|
||||||
);
|
);
|
||||||
|
|
||||||
const isFeedbackDisplayed = feedbacksDisplayed =>
|
const isFeedbackDisplayed = feedbacksDisplayed =>
|
||||||
!Object.entries(feedbacksDisplayed).some(feedback =>
|
Object.entries(feedbacksDisplayed).some(feedback =>
|
||||||
feedback.value
|
feedback.value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -51,7 +54,7 @@ export const shouldDisplayFeedbackWidget = (
|
||||||
feedbacksDisplayed
|
feedbacksDisplayed
|
||||||
) => (
|
) => (
|
||||||
isUserEligibleForFeedback(user, permissions, feedbackQuestionId, feedbackUserRate) &&
|
isUserEligibleForFeedback(user, permissions, feedbackQuestionId, feedbackUserRate) &&
|
||||||
isFeedbackDisplayed(feedbacksDisplayed)
|
!isFeedbackDisplayed(feedbacksDisplayed)
|
||||||
);
|
);
|
||||||
|
|
||||||
export const sendUserPropertiesForFeedback = (user, permissions, shouldDisplayFeedback) => {
|
export const sendUserPropertiesForFeedback = (user, permissions, shouldDisplayFeedback) => {
|
||||||
|
|
|
@ -17,7 +17,7 @@ export const isDateInRange = (date, startDate, endDate) => {
|
||||||
|
|
||||||
export const calculateAgeGroup = (birthYear, birthMonth) => {
|
export const calculateAgeGroup = (birthYear, birthMonth) => {
|
||||||
if (!birthMonth || !birthYear) {
|
if (!birthMonth || !birthYear) {
|
||||||
return '[unset]';
|
return '[no-data]';
|
||||||
}
|
}
|
||||||
|
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {QUALITATIVE_FEEDBACK_QUESTION_ID} from '../components/modal/feedback/qualitative_feedback_data';
|
import {QUALITATIVE_FEEDBACK_QUESTION_ID} from '../components/modal/feedback/qualitative-feedback-data';
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
[QUALITATIVE_FEEDBACK_QUESTION_ID.ideasGenerator]: false,
|
[QUALITATIVE_FEEDBACK_QUESTION_ID.ideasGenerator]: false,
|
||||||
|
|
|
@ -29,7 +29,7 @@ const {
|
||||||
const {useRef} = require('react');
|
const {useRef} = require('react');
|
||||||
const {
|
const {
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID
|
QUALITATIVE_FEEDBACK_QUESTION_ID
|
||||||
} = require('../../components/modal/feedback/qualitative_feedback_data.js');
|
} = require('../../components/modal/feedback/qualitative-feedback-data.js');
|
||||||
const {shouldDisplayFeedbackWidget, sendUserPropertiesForFeedback} = require('../../lib/feedback.js');
|
const {shouldDisplayFeedbackWidget, sendUserPropertiesForFeedback} = require('../../lib/feedback.js');
|
||||||
|
|
||||||
require('./ideas.scss');
|
require('./ideas.scss');
|
||||||
|
@ -165,25 +165,30 @@ const Ideas = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const shoulDisplayFeedback = shouldDisplayFeedbackWidget(
|
const shouldDisplayFeedback = shouldDisplayFeedbackWidget(
|
||||||
user,
|
user,
|
||||||
permissions,
|
permissions,
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID.ideasGenerator,
|
QUALITATIVE_FEEDBACK_QUESTION_ID.ideasGenerator,
|
||||||
process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_RATE,
|
process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_FREQUENCY,
|
||||||
feedback
|
feedback
|
||||||
);
|
);
|
||||||
|
|
||||||
if (iframe && shoulDisplayFeedback) {
|
if (iframe && shouldDisplayFeedback) {
|
||||||
sendUserPropertiesForFeedback(
|
sendUserPropertiesForFeedback(
|
||||||
user,
|
user,
|
||||||
permissions,
|
permissions,
|
||||||
shoulDisplayFeedback
|
shouldDisplayFeedback
|
||||||
);
|
);
|
||||||
iframe.addEventListener('load', onIframeLoad);
|
iframe.addEventListener('load', onIframeLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
|
iframe.contentWindow.document
|
||||||
|
.querySelectorAll('[class*="green-flag"]')
|
||||||
|
.forEach(element =>
|
||||||
|
element.removeEventListener('click', onGreenFlagClick)
|
||||||
|
);
|
||||||
iframe.removeEventListener('load', onIframeLoad);
|
iframe.removeEventListener('load', onIframeLoad);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -197,7 +202,7 @@ const Ideas = ({
|
||||||
<div className="banner-wrapper">
|
<div className="banner-wrapper">
|
||||||
<iframe
|
<iframe
|
||||||
ref={iframeRef}
|
ref={iframeRef}
|
||||||
src={`http://localhost:8333/projects/9999923/embed`}
|
src={`${process.env.IDEAS_GENERATOR_SOURCE}/embed`}
|
||||||
width="485"
|
width="485"
|
||||||
height="402"
|
height="402"
|
||||||
allowfullscreen
|
allowfullscreen
|
||||||
|
|
|
@ -47,7 +47,7 @@ const TutorialsHighlight = require('../../components/journeys/tutorials-highligh
|
||||||
const {sendUserPropertiesForOnboarding, shouldDisplayOnboarding} = require('../../lib/onboarding.js');
|
const {sendUserPropertiesForOnboarding, shouldDisplayOnboarding} = require('../../lib/onboarding.js');
|
||||||
const {triggerAnalyticsEvent} = require('../../lib/google-analytics-utils.js');
|
const {triggerAnalyticsEvent} = require('../../lib/google-analytics-utils.js');
|
||||||
const {StarterProjectsFeedback} = require('../../components/modal/feedback/starter-projects-feedback.jsx');
|
const {StarterProjectsFeedback} = require('../../components/modal/feedback/starter-projects-feedback.jsx');
|
||||||
const {QUALITATIVE_FEEDBACK_QUESTION_ID} = require('../../components/modal/feedback/qualitative_feedback_data.js');
|
const {QUALITATIVE_FEEDBACK_QUESTION_ID} = require('../../components/modal/feedback/qualitative-feedback-data.js');
|
||||||
const {shouldDisplayFeedbackWidget, sendUserPropertiesForFeedback} = require('../../lib/feedback.js');
|
const {shouldDisplayFeedbackWidget, sendUserPropertiesForFeedback} = require('../../lib/feedback.js');
|
||||||
const {displayQualitativeFeedback} = require('../../redux/qualitative-feedback.js');
|
const {displayQualitativeFeedback} = require('../../redux/qualitative-feedback.js');
|
||||||
const {DebuggingFeedback} = require('../../components/modal/feedback/debugging-feedback.jsx');
|
const {DebuggingFeedback} = require('../../components/modal/feedback/debugging-feedback.jsx');
|
||||||
|
@ -73,7 +73,7 @@ const IntlGUIWithProjectHandler = ({...props}) => {
|
||||||
}, [props.projectId, prevProjectId, props.user, props.permissions]);
|
}, [props.projectId, prevProjectId, props.user, props.permissions]);
|
||||||
|
|
||||||
const displayGuiFeedback = useCallback((feedbackQuestionId, feedbackUserRate) => {
|
const displayGuiFeedback = useCallback((feedbackQuestionId, feedbackUserRate) => {
|
||||||
const shoulDisplayFeedback = shouldDisplayFeedbackWidget(
|
const shouldDisplayFeedback = shouldDisplayFeedbackWidget(
|
||||||
props.user,
|
props.user,
|
||||||
props.permissions,
|
props.permissions,
|
||||||
feedbackQuestionId,
|
feedbackQuestionId,
|
||||||
|
@ -81,11 +81,11 @@ const IntlGUIWithProjectHandler = ({...props}) => {
|
||||||
props.feedback
|
props.feedback
|
||||||
);
|
);
|
||||||
|
|
||||||
if (shoulDisplayFeedback) {
|
if (shouldDisplayFeedback) {
|
||||||
sendUserPropertiesForFeedback(
|
sendUserPropertiesForFeedback(
|
||||||
props.user,
|
props.user,
|
||||||
props.permissions,
|
props.permissions,
|
||||||
shoulDisplayFeedback
|
shouldDisplayFeedback
|
||||||
);
|
);
|
||||||
props.displayFeedback(feedbackQuestionId);
|
props.displayFeedback(feedbackQuestionId);
|
||||||
}
|
}
|
||||||
|
@ -95,14 +95,14 @@ const IntlGUIWithProjectHandler = ({...props}) => {
|
||||||
<>
|
<>
|
||||||
<IntlGUI
|
<IntlGUI
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
displayDebugFeedback={() => displayGuiFeedback(
|
onDebugModalClose={() => displayGuiFeedback(
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID.debugging,
|
QUALITATIVE_FEEDBACK_QUESTION_ID.debugging,
|
||||||
process.env.QUALITATIVE_FEEDBACK_DEBUGGING_USER_RATE
|
process.env.QUALITATIVE_FEEDBACK_DEBUGGING_USER_FREQUENCY
|
||||||
)}
|
)}
|
||||||
// eslint-disable-next-line react/jsx-no-bind
|
// eslint-disable-next-line react/jsx-no-bind
|
||||||
displayTutorialsFeedback={() => displayGuiFeedback(
|
onTutorialSelect={() => displayGuiFeedback(
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID.tutorials,
|
QUALITATIVE_FEEDBACK_QUESTION_ID.tutorials,
|
||||||
process.env.QUALITATIVE_FEEDBACK_TUTORIALS_USER_RATE
|
process.env.QUALITATIVE_FEEDBACK_TUTORIALS_USER_FREQUENCY
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
|
@ -305,18 +305,18 @@ class Preview extends React.Component {
|
||||||
sendUserPropertiesForOnboarding(this.props.user, this.props.permissions);
|
sendUserPropertiesForOnboarding(this.props.user, this.props.permissions);
|
||||||
|
|
||||||
const fromStarterProjectsPage = queryString.parse(location.search).fromStarterProjectsPage === 'true';
|
const fromStarterProjectsPage = queryString.parse(location.search).fromStarterProjectsPage === 'true';
|
||||||
const shoulDisplayFeedback = shouldDisplayFeedbackWidget(
|
const shouldDisplayFeedback = shouldDisplayFeedbackWidget(
|
||||||
this.props.user,
|
this.props.user,
|
||||||
this.props.permissions,
|
this.props.permissions,
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects,
|
QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects,
|
||||||
process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_RATE,
|
process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_FREQUENCY,
|
||||||
this.props.feedback
|
this.props.feedback
|
||||||
);
|
);
|
||||||
if (fromStarterProjectsPage && shoulDisplayFeedback) {
|
if (fromStarterProjectsPage && shouldDisplayFeedback) {
|
||||||
sendUserPropertiesForFeedback(
|
sendUserPropertiesForFeedback(
|
||||||
this.props.user,
|
this.props.user,
|
||||||
this.props.permissions,
|
this.props.permissions,
|
||||||
shoulDisplayFeedback
|
shouldDisplayFeedback
|
||||||
);
|
);
|
||||||
this.props.displayFeedback(
|
this.props.displayFeedback(
|
||||||
QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects
|
QUALITATIVE_FEEDBACK_QUESTION_ID.starterProjects
|
||||||
|
|
|
@ -308,19 +308,20 @@ module.exports = {
|
||||||
process.env.QUALITATIVE_FEEDBACK_STARTING_DATE || '2024-01-20'
|
process.env.QUALITATIVE_FEEDBACK_STARTING_DATE || '2024-01-20'
|
||||||
}"`,
|
}"`,
|
||||||
'process.env.QUALITATIVE_FEEDBACK_ENDING_DATE': `"${
|
'process.env.QUALITATIVE_FEEDBACK_ENDING_DATE': `"${
|
||||||
process.env.QUALITATIVE_FEEDBACK_ENDING_DATE || '2030-11-20'
|
process.env.QUALITATIVE_FEEDBACK_ENDING_DATE || '2024-11-20'
|
||||||
}"`,
|
}"`,
|
||||||
'process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_RATE': `"${
|
// Given user frequency X, show qualitative feedback to 1 in X users
|
||||||
process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_RATE || 2
|
'process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_FREQUENCY': `"${
|
||||||
|
process.env.QUALITATIVE_FEEDBACK_IDEAS_GENERATOR_USER_FREQUENCY || 2
|
||||||
}"`,
|
}"`,
|
||||||
'process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_RATE': `"${
|
'process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_FREQUENCY': `"${
|
||||||
process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_RATE || 2
|
process.env.QUALITATIVE_FEEDBACK_STARTER_PROJECTS_USER_FREQUENCY || 2
|
||||||
}"`,
|
}"`,
|
||||||
'process.env.QUALITATIVE_FEEDBACK_DEBUGGING_USER_RATE': `"${
|
'process.env.QUALITATIVE_FEEDBACK_DEBUGGING_USER_FREQUENCY': `"${
|
||||||
process.env.QUALITATIVE_FEEDBACK_DEBUGGING_USER_RATE || 2
|
process.env.QUALITATIVE_FEEDBACK_DEBUGGING_USER_FREQUENCY || 2
|
||||||
}"`,
|
}"`,
|
||||||
'process.env.QUALITATIVE_FEEDBACK_TUTORIALS_USER_RATE': `"${
|
'process.env.QUALITATIVE_FEEDBACK_TUTORIALS_USER_FREQUENCY': `"${
|
||||||
process.env.QUALITATIVE_FEEDBACK_TUTORIALS_USER_RATE || 2
|
process.env.QUALITATIVE_FEEDBACK_TUTORIALS_USER_FREQUENCY || 2
|
||||||
}"`,
|
}"`,
|
||||||
'process.env.IDEAS_GENERATOR_SOURCE': `"${
|
'process.env.IDEAS_GENERATOR_SOURCE': `"${
|
||||||
process.env.IDEAS_GENERATOR_SOURCE || 'https://scratch.mit.edu/projects/1108790117'
|
process.env.IDEAS_GENERATOR_SOURCE || 'https://scratch.mit.edu/projects/1108790117'
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue