Skip to content

Commit a291c23

Browse files
committed
Merge branch 'master' into QuillEditorIntegration
# Conflicts: # src/intl/en.json # src/intl/zh-tw.json
2 parents 1a5495c + 678dec0 commit a291c23

17 files changed

+230
-127
lines changed

package-lock.json

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"@fortawesome/react-fontawesome": "0.1.8",
3737
"@mdx-js/mdx": "^1.5.9",
3838
"@mdx-js/react": "^1.5.9",
39-
"@rehooks/local-storage": "^2.4.0",
39+
"@rehooks/local-storage": "2.4.0",
4040
"@svgr/webpack": "^5.1.0",
4141
"antd": "^4.16.6",
4242
"aos": "^3.0.0-beta.6",

src/components/Auth/LoginNeededWrapper.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Button, Result } from 'antd';
33
import { FormattedMessage } from 'gatsby-plugin-intl';
44
import React from 'react';
55
import { useAuth0 } from '@auth0/auth0-react';
6+
import useAuth from '../../hooks/useAuth';
67

78
const LoginNeededWrapper = ({
89
title,
@@ -11,10 +12,10 @@ const LoginNeededWrapper = ({
1112
children
1213
}) => {
1314
const {
14-
loginWithRedirect,
1515
isLoading,
1616
isAuthenticated
1717
} = useAuth0();
18+
const { handleLogin } = useAuth();
1819
if (!isLoginNeeded) {
1920
return children;
2021
}
@@ -28,7 +29,7 @@ const LoginNeededWrapper = ({
2829
subTitle={subTitle}
2930
extra={[
3031
<Button type="primary" key="enableOrg"
31-
onClick={() => loginWithRedirect(location.pathname)}>
32+
onClick={() => handleLogin(location.pathname)}>
3233
<FormattedMessage defaultMessage="Login here"/>
3334
</Button>
3435
]}

src/components/GetStarted/CreateAssessment.js

+94-25
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,113 @@
11
import InterviewForm from '../Interviews/InterviewForm';
2-
import React from 'react';
2+
import React, { useEffect, useState } from 'react';
33
import { FormattedMessage, navigate, useIntl } from 'gatsby-plugin-intl';
44
import GetStartedInformationBox from './GetStartedInformationBox';
5+
import ConfirmModal from '../Organization/ConfirmModal';
6+
import { Select, Spin } from 'antd';
7+
import useApi from '../../hooks/useApi';
8+
import { LoadingOutlined } from '@ant-design/icons';
59

610
const CreateAssessment = ({
711
setStep,
812
setAssessmentId
913
}) => {
1014
const intl = useIntl();
15+
const { getInterviews } = useApi();
16+
const [templateInterviews, setTemplateInterviews] = useState([]);
17+
const [templateId, setTemplateId] = useState('');
18+
const [templateSelected, setTemplateSelected] = useState(false);
19+
const [loading, setLoading] = useState(true);
20+
const [okButtonDisabled, setOkButtonDisabled] = useState(true);
1121
const handlePublished = (interview) => {
1222
setAssessmentId(interview.id);
1323
setStep(1);
1424
navigate('/get-started');
1525
};
26+
useEffect(() => {
27+
getInterviews({ template: true })
28+
.then(({ results }) => {
29+
setTemplateInterviews(results);
30+
setLoading(false);
31+
});
32+
}, []);
33+
34+
const onTemplateSelect = (templateId) => {
35+
setOkButtonDisabled(false);
36+
setTemplateId(templateId);
37+
};
38+
39+
const handleSelectTemplate = () => {
40+
setTemplateSelected(true);
41+
};
1642
return (
1743
<>
18-
<GetStartedInformationBox
19-
title={intl.formatMessage({ defaultMessage: 'Get started - Create Assessment' })}>
20-
<FormattedMessage
21-
defaultMessage={'Learn how to create your own assessments! Multiple settings includes:'}/>
22-
<ul>
23-
<li>
24-
<FormattedMessage defaultMessage={'Set assess time period to your assessment.'}/>
25-
</li>
26-
<li>
27-
<FormattedMessage defaultMessage={'Public/Private Visibility of Assessment'}/>
28-
</li>
29-
<li>
30-
<FormattedMessage
31-
defaultMessage={'Show Assessment result and answers to your candidate right after they submit.'}/>
32-
</li>
33-
<li>
34-
<FormattedMessage defaultMessage={'Section ability to aggregate your questions'}/>
35-
</li>
36-
<li>
37-
<FormattedMessage defaultMessage={'Reorder your questions by Drag and Drop'}/>
38-
</li>
39-
</ul>
40-
</GetStartedInformationBox>
41-
<InterviewForm onPublished={handlePublished}/>
44+
<Spin spinning={loading} indicator={<LoadingOutlined spin/>}>
45+
<ConfirmModal
46+
title={intl.formatMessage({
47+
id: 'assessment.template.select.title',
48+
defaultMessage: 'Choose a Template'
49+
})}
50+
submitButtonTitle={intl.formatMessage({
51+
id: 'general.button.select',
52+
defaultMessage: 'Select'
53+
})}
54+
showDirectly={true}
55+
closable={false}
56+
maskClosable={false}
57+
cancelButtonHidden={true}
58+
okButtonDisabled={okButtonDisabled}
59+
onOK={handleSelectTemplate}
60+
>
61+
<FormattedMessage id={'assessment.template.select.desc'}
62+
defaultMessage={'Please select a template to let us populate Assessment content quickly for you'}
63+
values={{ br: <br/> }}
64+
/>
65+
<Select
66+
onChange={(v) => onTemplateSelect(v)}
67+
style={{
68+
width: '100%',
69+
padding: '10px 0'
70+
}}
71+
>
72+
{
73+
templateInterviews.map((templateInterview) => (
74+
<Select.Option key={templateInterview.id}
75+
value={templateInterview.id}
76+
>
77+
{templateInterview.title}
78+
</Select.Option>
79+
))
80+
}
81+
</Select>
82+
</ConfirmModal>
83+
84+
<GetStartedInformationBox
85+
title={intl.formatMessage({ defaultMessage: 'Get started - Create Assessment' })}>
86+
<FormattedMessage
87+
defaultMessage={'Learn how to create your own assessments! Multiple settings includes:'}/>
88+
<ul>
89+
<li>
90+
<FormattedMessage defaultMessage={'Set assess time period to your assessment.'}/>
91+
</li>
92+
<li>
93+
<FormattedMessage defaultMessage={'Public/Private Visibility of Assessment'}/>
94+
</li>
95+
<li>
96+
<FormattedMessage
97+
defaultMessage={'Show Assessment result and answers to your candidate right after they submit.'}/>
98+
</li>
99+
<li>
100+
<FormattedMessage defaultMessage={'Section ability to aggregate your questions'}/>
101+
</li>
102+
<li>
103+
<FormattedMessage defaultMessage={'Reorder your questions by Drag and Drop'}/>
104+
</li>
105+
</ul>
106+
</GetStartedInformationBox>
107+
{
108+
templateSelected && <InterviewForm id={templateId} onPublished={handlePublished} copy/>
109+
}
110+
</Spin>
42111
</>
43112
);
44113
};

src/components/GetStarted/GetStartedCompleted.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { FormattedMessage, Link, useIntl } from 'gatsby-plugin-intl';
22
import { Button, Result } from 'antd';
33
import React, { useEffect } from 'react';
4-
import { useAuth0 } from '@auth0/auth0-react';
54
import useGetStarted from '../../hooks/useGetStarted';
5+
import useAuth from '../../hooks/useAuth';
66

77
const GetStartedCompleted = () => {
8-
const { loginWithRedirect } = useAuth0();
8+
const { handleLogin } = useAuth();
99
const { clearGSTokens } = useGetStarted();
1010
const intl = useIntl();
1111
useEffect(() => {
@@ -22,7 +22,7 @@ const GetStartedCompleted = () => {
2222
<FormattedMessage defaultMessage={'Try Get Started Again'}/>
2323
</Link>
2424
<Button type="primary" key="enableOrg"
25-
onClick={() => loginWithRedirect(location.pathname)}>
25+
onClick={() => handleLogin(location.pathname)}>
2626
<FormattedMessage defaultMessage="Login here"/>
2727
</Button></>}
2828
/>

src/components/GetStarted/ViewAssessmentResult.js

-2
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@ import React from 'react';
22
import InterviewResult from '../ManageInterviews/InterviewResult';
33
import { FormattedMessage, useIntl } from 'gatsby-plugin-intl';
44
import { Button } from 'antd';
5-
import { useAuth0 } from '@auth0/auth0-react';
65
import useGetStarted from '../../hooks/useGetStarted';
76
import GetStartedInformationBox from './GetStartedInformationBox';
87

98
const ViewAssessmentResult = ({
109
id,
1110
sid
1211
}) => {
13-
const { loginWithRedirect } = useAuth0();
1412
const intl = useIntl();
1513
const { setStep } = useGetStarted();
1614
return (

src/components/Interviews/InterviewForm.js

+40-27
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,10 @@ const defaultSectionTitle = 'default section';
117117

118118
const InterviewForm = ({
119119
id,
120-
onPublished
120+
onPublished,
121+
copy
121122
}) => {
122-
const isEditForm = !!id;
123+
const isEditForm = !!id && !copy;
123124
const intl = useIntl();
124125
const {
125126
createInterview,
@@ -143,6 +144,30 @@ const InterviewForm = ({
143144
const [selectedQuestionIds, setSelectedQuestionIds] = useState([]);
144145
const [publishedInterviewId, setPublishedInterviewId] = useState(null);
145146

147+
const populateInterviewById = () => {
148+
getInterview(id)
149+
.then((data = { sections: [] }) => {
150+
data.visibility = data.visibility === 'PUBLIC';
151+
form.setFieldsValue({
152+
...data,
153+
// specializationId: data.specialization.id,
154+
defaultDuration: data.defaultDuration === -1 ? '' : data.defaultDuration
155+
});
156+
setAnchorSections(data.sections.map((section, index) => ({
157+
href: `#section_${index}`,
158+
title: section.title,
159+
subAnchors: section.questions?.map((question, qindex) =>
160+
({
161+
href: `#section_${index}_question_${qindex}`,
162+
title: `Q ${qindex + 1}`
163+
}))
164+
})));
165+
if (!copy) {
166+
setPublishedInterviewId(data.publishedInterviewId);
167+
}
168+
setLoading(false);
169+
});
170+
};
146171
useEffect(() => {
147172
const historyUnsubscribe = globalHistory.listen((listener) => {
148173
});
@@ -155,34 +180,21 @@ const InterviewForm = ({
155180
window.onbeforeunload = undefined;
156181
};
157182
}, []);
183+
158184
useEffect(() => {
159185
// getSpecializations()
160186
// .then(((data = []) => {
161187
// setSpecializations(data);
162188
// }));
163189
if (isEditForm) {
164190
setLoading(true);
165-
getInterview(id)
166-
.then((data = { sections: [] }) => {
167-
data.visibility = data.visibility === 'PUBLIC';
168-
form.setFieldsValue({
169-
...data,
170-
// specializationId: data.specialization.id,
171-
defaultDuration: data.defaultDuration === -1 ? '' : data.defaultDuration
172-
});
173-
setAnchorSections(data.sections.map((section, index) => ({
174-
href: `#section_${index}`,
175-
title: section.title,
176-
subAnchors: section.questions?.map((question, qindex) =>
177-
({
178-
href: `#section_${index}_question_${qindex}`,
179-
title: `Q ${qindex + 1}`
180-
}))
181-
})));
182-
setPublishedInterviewId(data.publishedInterviewId);
183-
setLoading(false);
184-
});
191+
populateInterviewById();
192+
185193
} else {
194+
if (id && copy) {
195+
populateInterviewById();
196+
return;
197+
}
186198
const formdata = {
187199
sections: [{
188200
title: defaultSectionTitle,
@@ -551,6 +563,8 @@ const InterviewForm = ({
551563
placeholder={intl.formatMessage({ defaultMessage: 'Please select assess duration' })}
552564
allowClear
553565
>
566+
<Option value={0}><FormattedMessage defaultMessage="No limit"
567+
values={{ minutes: 0 }}/> </Option>
554568
<Option value={30}><FormattedMessage defaultMessage="{minutes} Minutes"
555569
values={{ minutes: 30 }}/> </Option>
556570
<Option value={60}><FormattedMessage defaultMessage="{minutes} Minutes"
@@ -562,14 +576,12 @@ const InterviewForm = ({
562576
</Select>
563577
</FormItem>
564578
<FormItem
565-
label={
566-
<FormattedMessage defaultMessage={'Show Answer Immediately:'}/>
567-
}
579+
label={intl.formatMessage({ defaultMessage: 'Show Answer Immediately:' })}
568580
name="releaseResult"
569581
tooltip={intl.formatMessage({ defaultMessage: 'choose yes if you want your candidate can see answers right after submitting.' })}
570582
>
571583
<Select
572-
defaultValue="NO"
584+
defaultValue="YES"
573585
>
574586
<Option value="YES"><FormattedMessage defaultMessage="YES"/></Option>
575587
<Option value="NO"><FormattedMessage defaultMessage="NO"/> </Option>
@@ -830,5 +842,6 @@ InterviewForm.propTypes = {
830842

831843
InterviewForm.defaultProps = {
832844
onPublished: () => {
833-
}
845+
},
846+
copy: false
834847
};

src/components/Login/LoginPrompt.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import React, { useState } from 'react';
44
import { useLocation } from '@reach/router';
55
import { useAuth0 } from '@auth0/auth0-react';
66
import { FormattedMessage, useIntl } from 'gatsby-plugin-intl';
7+
import useAuth from '../../hooks/useAuth';
78

89

910
const LoginPrompt = ({
@@ -12,9 +13,9 @@ const LoginPrompt = ({
1213
isLoginNeeded
1314
}) => {
1415
const {
15-
isAuthenticated,
16-
loginWithRedirect
16+
isAuthenticated
1717
} = useAuth0();
18+
const { handleLogin } = useAuth();
1819
const location = useLocation();
1920
const intl = useIntl();
2021
const [isLoginPrompt, setIsLoginPrompt] = useState(false);
@@ -31,7 +32,7 @@ const LoginPrompt = ({
3132
visible={isLoginPrompt}
3233
onCancel={() => setIsLoginPrompt(false)}
3334
footer={[
34-
<Button key="submit" type="primary" onClick={() => loginWithRedirect(location.pathname)}>
35+
<Button key="submit" type="primary" onClick={() => handleLogin(location.pathname)}>
3536
<FormattedMessage defaultMessage={'Login'}/>
3637
</Button>
3738
]}

0 commit comments

Comments
 (0)