Skip to content
This repository has been archived by the owner on Feb 9, 2022. It is now read-only.

Commit

Permalink
Selection Plan ExtraQuestions
Browse files Browse the repository at this point in the history
refactoring

Signed-off-by: smarcet <[email protected]>
  • Loading branch information
smarcet committed Nov 10, 2022
1 parent 963dad6 commit 4abdb72
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 78 deletions.
10 changes: 8 additions & 2 deletions src/actions/event-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ export const getEvent = (eventId) => async (dispatch, getState) => {

const params = {
access_token: accessToken,
expand: 'creator,speakers,moderator,sponsors,groups,type,type.allowed_media_upload_types, type.allowed_media_upload_types.type, slides, links, videos, media_uploads, tags, media_uploads.media_upload_type, media_uploads.media_upload_type.type,extra_questions,selection_plan,selection_plan.extra_questions,selection_plan.extra_questions.values,created_by'
expand: 'creator,speakers,moderator,sponsors,groups,type,type.allowed_media_upload_types,type.allowed_media_upload_types.type, slides, links, videos, media_uploads, tags, media_uploads.media_upload_type, media_uploads.media_upload_type.type,extra_questions,selection_plan,selection_plan.extra_questions,selection_plan.extra_questions.values,created_by'
};

dispatch(startLoading());
Expand Down Expand Up @@ -270,7 +270,8 @@ export const saveEvent = (entity, publish) => async (dispatch, getState) => {
const normalizedEntity = normalizeEntity(entity, eventTypeConfig);

const params = {
access_token: accessToken
access_token: accessToken,
expand: 'creator,speakers,moderator,sponsors,groups,type,type.allowed_media_upload_types,type.allowed_media_upload_types.type, slides, links, videos, media_uploads, tags, media_uploads.media_upload_type, media_uploads.media_upload_type.type,extra_questions,selection_plan,selection_plan.extra_questions,selection_plan.extra_questions.values,created_by'
};

if (entity.id) {
Expand Down Expand Up @@ -586,6 +587,11 @@ const normalizeEntity = (entity, eventTypeConfig) => {
}
}

if(normalizedEntity.hasOwnProperty('extra_questions')){

normalizedEntity.extra_questions = normalizedEntity.extra_questions.map((q) => ({ question_id : q.question_id, answer : q.value}))
}

return normalizedEntity;
}

Expand Down
40 changes: 38 additions & 2 deletions src/actions/selection-plan-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
showSuccessMessage,
authErrorHandler
} from 'openstack-uicore-foundation/lib/utils/actions';
import {getAccessTokenSafely} from '../utils/methods';
import { getAccessTokenSafely, escapeFilterValue, fetchResponseHandler, fetchErrorHandler } from '../utils/methods';
import _ from 'lodash';

export const RECEIVE_SELECTION_PLAN = 'RECEIVE_SELECTION_PLAN';
export const RESET_SELECTION_PLAN_FORM = 'RESET_SELECTION_PLAN_FORM';
Expand All @@ -35,6 +36,8 @@ export const SELECTION_PLAN_ADDED = 'SELECTION_PLAN_ADDED';
export const SELECTION_PLAN_DELETED = 'SELECTION_PLAN_DELETED';
export const TRACK_GROUP_REMOVED = 'TRACK_GROUP_REMOVED';
export const TRACK_GROUP_ADDED = 'TRACK_GROUP_ADDED';
export const SELECTION_PLAN_ASSIGNED_EXTRA_QUESTION = 'SELECTION_PLAN_ASSIGNED_EXTRA_QUESTION';
const callDelay = 500; //miliseconds

export const getSelectionPlan = (selectionPlanId) => async (dispatch, getState) => {

Expand Down Expand Up @@ -573,4 +576,37 @@ export const deleteRatingType = (selectionPlanId, ratingTypeId) => async (dispat
dispatch(stopLoading());
}
);
};
};

export const querySelectionPlanExtraQuestions = _.debounce(async (summitId, input, callback) => {

const accessToken = await getAccessTokenSafely();
input = escapeFilterValue(input);
let filters = encodeURIComponent(`name=@${input}`);

fetch(`${window.API_BASE_URL}/api/v1/summits/${summitId}/selection-plan-extra-questions?filter=${filters}&&access_token=${accessToken}`)
.then(fetchResponseHandler)
.then((json) => {
let options = [...json.data];

callback(options);
})
.catch(fetchErrorHandler);

}, callDelay);

export const assignExtraQuestion2SelectionPlan = (summitId, selectionPlanId, questionId) => async (dispatch, getState) => {
const accessToken = await getAccessTokenSafely();
dispatch(startLoading());
postRequest(
null,
createAction(SELECTION_PLAN_ASSIGNED_EXTRA_QUESTION),
`${window.API_BASE_URL}/api/v1/summits/${summitId}/selection-plans/${selectionPlanId}/extra-questions/${questionId}?access_token=${accessToken}`,
{},
authErrorHandler
)({})(dispatch)
.then((payload) => {
dispatch(stopLoading());
dispatch(showSuccessMessage(T.translate("edit_selection_plan.selection_plan_saved")));
});
}
83 changes: 60 additions & 23 deletions src/components/forms/event-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ import {
MemberInput, FreeTextSearch
} from 'openstack-uicore-foundation/lib/components'
import {isEmpty, scrollToError, shallowEqual, hasErrors} from "../../utils/methods";
import QuestionAnswersInput from "../inputs/question-answers-input";
import {Pagination} from "react-bootstrap";
import {deleteEventFeedback, getEventFeedbackCSV} from "../../actions/event-actions";
import ExtraQuestionsForm from 'openstack-uicore-foundation/lib/components/extra-questions';


class EventForm extends React.Component {

constructor(props) {
super(props);

Expand All @@ -47,12 +47,13 @@ class EventForm extends React.Component {
errors: props.errors
};

this.formRef = React.createRef();

this.handleChange = this.handleChange.bind(this);
this.handleQAuserChange = this.handleQAuserChange.bind(this);
this.handleTimeChange = this.handleTimeChange.bind(this);
this.handleUploadFile = this.handleUploadFile.bind(this);
this.handleRemoveFile = this.handleRemoveFile.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleMaterialEdit = this.handleMaterialEdit.bind(this);
this.handleNewMaterial = this.handleNewMaterial.bind(this);
this.handleUploadPic = this.handleUploadPic.bind(this);
Expand All @@ -64,23 +65,25 @@ class EventForm extends React.Component {
this.handleFeedbackSort = this.handleFeedbackSort.bind(this);
this.handleFeedbackSearch = this.handleFeedbackSearch.bind(this);
this.handleDeleteEventFeedback = this.handleDeleteEventFeedback.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.triggerFormSubmit = this.triggerFormSubmit.bind(this);
}

componentDidUpdate(prevProps, prevState, snapshot) {
const state = {};
const newState = {};
scrollToError(this.props.errors);

if (!shallowEqual(prevProps.entity, this.props.entity)) {
state.entity = {...this.props.entity};
state.errors = {};
newState.entity = {...this.props.entity};
newState.errors = {};
}

if (!shallowEqual(prevProps.errors, this.props.errors)) {
state.errors = {...this.props.errors};
newState.errors = {...this.props.errors};
}

if (!isEmpty(state)) {
this.setState({...this.state, ...state})
if (!isEmpty(newState)) {
this.setState({...this.state, ...newState})
}
}

Expand Down Expand Up @@ -234,13 +237,43 @@ class EventForm extends React.Component {
this.setState({entity: entity});
}

handleSubmit(publish, ev) {
const entity = {...this.state.entity};

triggerFormSubmit(publish, ev) {
ev.preventDefault();
// do regular submit
const entity = { ... this.state.entity };
// check current ( could not be rendered)
if(this.formRef.current) {
this.formRef.current.dispatchEvent(new Event("submit", {cancelable: true, bubbles: true}));
return;
}

// if we did not changed the extra questions , then dont send them
if (entity.extra_questions) {
delete entity.extra_questions;
}

this.props.onSubmit(entity, publish);
this.props.onSubmit(entity);
}

handleSubmit(formValues) {

const {extraQuestions} = this.props;

const formattedAnswers = [];

Object.keys(formValues).map(a => {
let question = extraQuestions.find(q => q.name === a);
const newQuestion = { question_id: question.id, value: `${formValues[a]}` }
formattedAnswers.push(newQuestion);
});

this.setState({...this.state, entity: {...this.state.entity, extra_questions: formattedAnswers}}, () => {
this.props.onSubmit(this.state.entity);
});
}


handleUnpublish(ev) {
ev.preventDefault();
this.props.onUnpublish(this.state.entity);
Expand Down Expand Up @@ -401,7 +434,9 @@ class EventForm extends React.Component {
}

render() {

const {entity, showSection, errors} = this.state;

const {
currentSummit, levelOpts, typeOpts, trackOpts,
locationOpts, rsvpTemplateOpts, selectionPlansOpts, history, extraQuestions, feedbackState
Expand Down Expand Up @@ -489,7 +524,7 @@ class EventForm extends React.Component {
const streaming_type_ddl = [{label: 'LIVE', value: 'LIVE'}, {label: 'VOD', value: 'VOD'}];

return (
<form>
<div>
<input type="hidden" id="id" value={entity.id}/>
<div className="row form-group">
<div className="col-md-8">
Expand Down Expand Up @@ -950,11 +985,13 @@ class EventForm extends React.Component {
{entity.id !== 0 && extraQuestions && extraQuestions.length > 0 &&
<Panel show={showSection === 'extra_questions'} title={T.translate("edit_event.extra_questions")}
handleClick={this.toggleSection.bind(this, 'extra_questions')}>
<QuestionAnswersInput
id="extra_questions"
answers={entity.extra_questions}
questions={extraQuestions}
onChange={this.handleChange}

<ExtraQuestionsForm
extraQuestions={extraQuestions}
userAnswers={entity.extra_questions}
onAnswerChanges={this.handleSubmit}
ref={this.formRef}
className="extra-questions"
/>
</Panel>
}
Expand Down Expand Up @@ -1010,9 +1047,9 @@ class EventForm extends React.Component {
<div className="col-md-12 submit-buttons">
{!entity.is_published &&
<div>
<input type="button" onClick={this.handleSubmit.bind(this, false)}
<input type="button" onClick={this.triggerFormSubmit.bind(this, false)}
className="btn btn-primary pull-right" value={T.translate("general.save")}/>
<input type="button" onClick={this.handleSubmit.bind(this, true)}
<input type="button" onClick={this.triggerFormSubmit.bind(this, true)}
className="btn btn-success pull-right"
value={T.translate("general.save_and_publish")}/>
</div>
Expand All @@ -1022,13 +1059,13 @@ class EventForm extends React.Component {
<div>
<input
type="button"
onClick={this.handleSubmit.bind(this, true)}
onClick={this.triggerFormSubmit.bind(this, true)}
className="btn btn-success pull-right"
value={T.translate("general.save_and_publish")}
/>
<input
type="button"
onClick={this.handleUnpublish.bind(this)}
onClick={this.triggerFormSubmit.bind(this)}
className="btn btn-danger pull-right"
value={T.translate("edit_event.unpublish")}
/>
Expand All @@ -1050,7 +1087,7 @@ class EventForm extends React.Component {

</div>
</div>
</form>
</div>
);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/components/forms/extra-question-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
Dropdown,
Input,
EditableTable,
Table,
TextEditor,
SortableTable
} from 'openstack-uicore-foundation/lib/components'
Expand Down Expand Up @@ -118,7 +117,7 @@ class ExtraQuestionForm extends React.Component {
}

allowsSubQuestionRules(question) {
return ExtraQuestionsTypeAllowSubQuestion.includes(question.type)
return this.props.shouldAllowSubRules && ExtraQuestionsTypeAllowSubQuestion.includes(question.type)
}

render() {
Expand Down
31 changes: 28 additions & 3 deletions src/components/forms/selection-plan-form.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ import {Input, DateTimePicker, SimpleLinkList, SortableTable, TextEditor, Panel}
import {isEmpty, scrollToError, shallowEqual, stripTags} from "../../utils/methods";
import EmailTemplateInput from "../inputs/email-template-input";
import { PresentationTypeClassName } from '../../utils/constants';

import Many2ManyDropDown from "../inputs/many-2-many-dropdown";
import {
querySelectionPlanExtraQuestions
} from '../../actions/selection-plan-actions';

class SelectionPlanForm extends React.Component {
constructor(props) {
Expand All @@ -46,6 +49,22 @@ class SelectionPlanForm extends React.Component {
this.handleEditRatingType = this.handleEditRatingType.bind(this);
this.toggleSection = this.toggleSection.bind(this);
this.handleNotificationEmailTemplateChange = this.handleNotificationEmailTemplateChange.bind(this);
this.fetchSummitSelectionPlanExtraQuestions = this.fetchSummitSelectionPlanExtraQuestions.bind(this);
this.linkSummitSelectionPlanExtraQuestion = this.linkSummitSelectionPlanExtraQuestion.bind(this);
}

fetchSummitSelectionPlanExtraQuestions(input, callback) {
let {currentSummit} = this.props;

if (!input) {
return Promise.resolve({ options: [] });
}
querySelectionPlanExtraQuestions(currentSummit.id, input, callback);
}

linkSummitSelectionPlanExtraQuestion(question){
let {currentSummit} = this.props;
this.props.onAssignExtraQuestion2SelectionPlan(currentSummit.id, this.state.entity.id, question.id);
}

handleEditExtraQuestion(questionId){
Expand Down Expand Up @@ -394,6 +413,12 @@ class SelectionPlanForm extends React.Component {
handleClick={() => {this.toggleSection('extra_questions')}}
>
<div className={'row'}>
<Many2ManyDropDown id="addAllowedExtraQuestions"
isClearable={true}
placeholder={T.translate("edit_selection_plan.placeholders.link_question")}
fetchOptions={this.fetchSummitSelectionPlanExtraQuestions}
onAdd={this.linkSummitSelectionPlanExtraQuestion}
/>
<div className="col-md-6 text-right col-md-offset-6">
<button className="btn btn-primary right-space" onClick={this.handleNewExtraQuestion}>
{T.translate("edit_selection_plan.add_extra_questions")}
Expand Down Expand Up @@ -461,8 +486,8 @@ class SelectionPlanForm extends React.Component {
<Panel
show={showSection === 'rating_types'}
title={T.translate("edit_rating_type.title")}
handleClick={() => {this.toggleSection('rating_types')}}
>
handleClick={() => {this.toggleSection('rating_types')}}>

<div className={'row'}>
<div className="col-md-6 text-right col-md-offset-6">
<button className="btn btn-primary right-space" onClick={this.handleAddRatingType}>
Expand Down
Loading

0 comments on commit 4abdb72

Please sign in to comment.