Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
compendium-v2
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
geant-swd
compendium-v2
Commits
4dbc8269
Commit
4dbc8269
authored
2 years ago
by
Saket Agrahari
Browse files
Options
Downloads
Patches
Plain Diff
COMP-213: progress bar
parent
6406643a
No related branches found
No related tags found
1 merge request
!46
COMP-213: progress bar
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
survey-frontend/src/ProgressBar.tsx
+48
-0
48 additions, 0 deletions
survey-frontend/src/ProgressBar.tsx
survey-frontend/src/SurveyComponent.tsx
+116
-61
116 additions, 61 deletions
survey-frontend/src/SurveyComponent.tsx
survey-frontend/src/survey.scss
+4
-0
4 additions, 0 deletions
survey-frontend/src/survey.scss
with
168 additions
and
61 deletions
survey-frontend/src/ProgressBar.tsx
0 → 100644
+
48
−
0
View file @
4dbc8269
import
React
from
"
react
"
;
function
ProgressBar
({
completionPercentage
,
unansweredPercentage
,
pages
,
pageTitle
,
})
{
const
progressBarContainerStyle
:
React
.
CSSProperties
=
{
display
:
"
flex
"
,
flexWrap
:
"
wrap
"
,
height
:
"
10px
"
,
margin
:
"
5px
"
,
width
:
`
${
100
/
pages
}
%`
,
};
const
progressBarFillStyle
:
React
.
CSSProperties
=
{
height
:
"
100%
"
,
transition
:
"
width 0.3s ease
"
,
};
const
progressBarFillStyleCopy
:
React
.
CSSProperties
=
{
...
progressBarFillStyle
,
width
:
`
${
completionPercentage
}
%`
,
backgroundColor
:
"
#1ab394
"
,
};
const
unansweredProgressBarFillStyle
:
React
.
CSSProperties
=
{
...
progressBarFillStyle
,
width
:
`
${
unansweredPercentage
}
%`
,
backgroundColor
:
"
#9d9d9d
"
,
};
const
pageTitleStyle
:
React
.
CSSProperties
=
{
width
:
"
100%
"
,
textAlign
:
"
center
"
}
return
(
<
div
style
=
{
progressBarContainerStyle
}
>
<
div
style
=
{
progressBarFillStyleCopy
}
/>
<
div
style
=
{
unansweredProgressBarFillStyle
}
/>
<
div
style
=
{
pageTitleStyle
}
>
{
pageTitle
}
</
div
>
</
div
>
);
}
export
default
ProgressBar
;
This diff is collapsed.
Click to expand it.
survey-frontend/src/SurveyComponent.tsx
+
116
−
61
View file @
4dbc8269
...
@@ -3,11 +3,17 @@ import { Model, Serializer, ComputedUpdater, Question } from "survey-core";
...
@@ -3,11 +3,17 @@ import { Model, Serializer, ComputedUpdater, Question } from "survey-core";
import
{
Survey
}
from
"
survey-react-ui
"
;
import
{
Survey
}
from
"
survey-react-ui
"
;
import
"
survey-core/modern.min.css
"
;
import
"
survey-core/modern.min.css
"
;
import
'
./survey.scss
'
;
import
'
./survey.scss
'
;
import
ProgressBar
from
"
./ProgressBar
"
;
Serializer
.
addProperty
(
"
itemvalue
"
,
"
customDescription:text
"
);
Serializer
.
addProperty
(
"
itemvalue
"
,
"
customDescription:text
"
);
Serializer
.
addProperty
(
"
question
"
,
"
hideCheckboxLabels:boolean
"
);
Serializer
.
addProperty
(
"
question
"
,
"
hideCheckboxLabels:boolean
"
);
interface
Progress
{
completionPercentage
:
number
;
unansweredPercentage
:
number
;
totalPages
:
number
;
pageTitle
:
string
;
}
enum
VerificationStatus
{
enum
VerificationStatus
{
New
=
"
new
"
,
// a question that was not answered last year
New
=
"
new
"
,
// a question that was not answered last year
Answered
=
"
answered
"
,
// a question that was not answered last year but has an answer now
Answered
=
"
answered
"
,
// a question that was not answered last year but has an answer now
...
@@ -18,9 +24,9 @@ enum VerificationStatus {
...
@@ -18,9 +24,9 @@ enum VerificationStatus {
function
SurveyComponent
()
{
function
SurveyComponent
()
{
const
[
surveyModel
,
setSurveyModel
]
=
useState
<
Model
>
();
const
[
surveyModel
,
setSurveyModel
]
=
useState
<
Model
>
(
);
const
[
progress
,
setProgress
]
=
useState
<
Progress
[]
>
([]
);
const
verificationStatus
=
useRef
<
Map
<
string
,
VerificationStatus
>>
(
new
Map
());
const
verificationStatus
=
useRef
<
Map
<
string
,
VerificationStatus
>>
(
new
Map
());
function
setVerifyButton
(
question
:
Question
,
state
:
VerificationStatus
)
{
function
setVerifyButton
(
question
:
Question
,
state
:
VerificationStatus
)
{
...
@@ -52,9 +58,9 @@ function SurveyComponent() {
...
@@ -52,9 +58,9 @@ function SurveyComponent() {
}
}
}
}
// const surveyComplete = useCallback((sender) => {
// const surveyComplete = useCallback((sender) => {
// console.log(sender.data);
// console.log(sender.data);
// }, []);
// }, []);
async
function
getModel
()
async
function
getModel
()
{
{
...
@@ -67,10 +73,9 @@ function SurveyComponent() {
...
@@ -67,10 +73,9 @@ function SurveyComponent() {
const
survey
=
new
Model
(
json
[
'
model
'
]);
const
survey
=
new
Model
(
json
[
'
model
'
]);
if
(
json
[
'
data
'
]
!==
null
)
if
(
json
[
'
data
'
]
!==
null
)
{
{
survey
.
data
=
json
[
'
data
'
];
survey
.
data
=
json
[
'
data
'
];
}
}
// TODO also use data and page info
// TODO also use data and page info
...
@@ -103,25 +108,24 @@ function SurveyComponent() {
...
@@ -103,25 +108,24 @@ function SurveyComponent() {
innerCss
:
"
sv-btn sv-btn--navigation sv-footer__complete-btn
"
innerCss
:
"
sv-btn sv-btn--navigation sv-footer__complete-btn
"
});
});
survey
.
onComplete
.
add
((
sender
,
options
)
=>
{
survey
.
onComplete
.
add
((
sender
,
options
)
=>
{
console
.
log
(
sender
.
data
);
console
.
log
(
sender
.
data
)
options
.
showSaveInProgress
();
options
.
showSaveInProgress
();
const
xhr
=
new
XMLHttpRequest
();
const
xhr
=
new
XMLHttpRequest
();
xhr
.
open
(
"
POST
"
,
"
/api/survey/save
"
);
xhr
.
open
(
"
POST
"
,
"
/api/survey/save
"
);
xhr
.
setRequestHeader
(
"
Content-Type
"
,
"
application/json; charset=utf-8
"
);
xhr
.
setRequestHeader
(
"
Content-Type
"
,
"
application/json; charset=utf-8
"
);
xhr
.
onload
=
xhr
.
onerror
=
function
()
{
xhr
.
onload
=
xhr
.
onerror
=
function
()
{
if
(
xhr
.
status
==
200
)
{
if
(
xhr
.
status
==
200
)
{
// Display the "Success" message (pass a string value to display a custom message)
// Display the "Success" message (pass a string value to display a custom message)
options
.
showSaveSuccess
();
options
.
showSaveSuccess
();
// Alternatively, you can clear all messages:
// Alternatively, you can clear all messages:
// options.clearSaveMessages();
// options.clearSaveMessages();
}
else
{
}
else
{
// Display the "Error" message (pass a string value to display a custom message)
// Display the "Error" message (pass a string value to display a custom message)
options
.
showSaveError
();
options
.
showSaveError
();
}
}
};
};
const
saveData
=
{
const
saveData
=
{
data
:
sender
.
data
,
data
:
sender
.
data
,
...
@@ -133,9 +137,8 @@ function SurveyComponent() {
...
@@ -133,9 +137,8 @@ function SurveyComponent() {
survey
.
onPartialSend
.
add
((
sender
,
options
)
=>
{
survey
.
onPartialSend
.
add
((
sender
,
options
)
=>
{
console
.
log
(
sender
.
data
)
console
.
log
(
sender
.
data
)
// TODO same as above
// TODO same as above
});
});
survey
.
onAfterRenderQuestion
.
add
(
function
(
survey
,
options
){
survey
.
onAfterRenderQuestion
.
add
(
function
(
survey
,
options
){
const
status
=
verificationStatus
.
current
.
get
(
options
.
question
.
name
);
const
status
=
verificationStatus
.
current
.
get
(
options
.
question
.
name
);
...
@@ -160,38 +163,90 @@ function SurveyComponent() {
...
@@ -160,38 +163,90 @@ function SurveyComponent() {
}
}
});
});
survey
.
onMatrixAfterCellRender
.
add
((
survey
,
options
)
=>
{
survey
.
onMatrixAfterCellRender
.
add
((
survey
,
options
)
=>
{
// get the customDescription for matrix rows and set it in the title
// get the customDescription for matrix rows and set it in the title
// attribute so that it shows up as a hover popup
// attribute so that it shows up as a hover popup
// NB I would have preferred using onAfterRenderQuestion, but unfortunately that is
// NB I would have preferred using onAfterRenderQuestion, but unfortunately that is
// not always triggered on re-renders (specifically when extra column become visble or invisible)
// not always triggered on re-renders (specifically when extra column become visble or invisible)
if
(
options
.
column
[
'
indexValue
'
]
==
0
&&
'
item
'
in
options
.
row
)
{
if
(
options
.
column
[
'
indexValue
'
]
==
0
&&
'
item
'
in
options
.
row
)
{
const
item
=
options
.
row
[
'
item
'
]
as
object
;
const
item
=
options
.
row
[
'
item
'
]
as
object
;
if
(
item
[
'
customDescription
'
]
!==
undefined
)
{
if
(
item
[
'
customDescription
'
]
!==
undefined
)
{
options
.
htmlElement
.
parentElement
?.
children
[
0
].
setAttribute
(
"
title
"
,
item
[
'
customDescription
'
]);
options
.
htmlElement
.
parentElement
?.
children
[
0
].
setAttribute
(
}
"
title
"
,
}
item
[
'
customDescription
'
]
);
}
}
});
survey
.
onCurrentPageChanged
.
add
((
sender
)
=>
{
console
.
log
(
"
sender-->
"
+
sender
);
calculateProgress
(
sender
);
});
setSurveyModel
(
survey
);
}
const
filterCallback
=
(
question
)
=>
{
return
question
.
value
!==
null
&&
question
.
value
!==
undefined
;
};
const
calculateProgress
=
(
survey
)
=>
{
// console.log("survey--> "+ survey);
if
(
survey
&&
survey
.
pages
)
{
console
.
log
(
"
survey.page-->
"
+
survey
.
pages
);
const
progressArray
:
Progress
[]
=
[];
survey
.
pages
.
forEach
((
page
)
=>
{
const
sectionQuestions
=
page
.
questions
.
filter
(
(
question
)
=>
question
.
startWithNewLine
);
const
questionCount
=
sectionQuestions
.
length
;
const
answeredCount
=
sectionQuestions
.
filter
(
filterCallback
).
length
;
const
unansweredCount
=
questionCount
-
answeredCount
;
const
completionPercentage
=
answeredCount
/
questionCount
;
progressArray
.
push
({
completionPercentage
:
completionPercentage
*
100
,
unansweredPercentage
:
(
unansweredCount
/
questionCount
)
*
100
,
totalPages
:
survey
.
pages
.
length
,
pageTitle
:
page
.
title
,
});
});
});
setSurveyModel
(
survey
);
setProgress
(
progressArray
);
}
}
};
useEffect
(()
=>
{
useEffect
(()
=>
{
getModel
();
getModel
();
},
[]);
},
[]);
if
(
surveyModel
)
useEffect
(()
=>
{
{
if
(
surveyModel
)
{
return
(<
Survey
model
=
{
surveyModel
}
/>
);
calculateProgress
(
surveyModel
);
}
}
else
},
[
surveyModel
]);
{
return
(<
span
>
loading...
</
span
>);
if
(
surveyModel
)
{
}
return
(
<
div
className
=
"survey-container"
>
<
div
className
=
"survey-progress"
>
{
progress
.
map
((
sectionProgress
,
index
)
=>
(
<
ProgressBar
key
=
{
index
}
completionPercentage
=
{
sectionProgress
.
completionPercentage
}
unansweredPercentage
=
{
sectionProgress
.
unansweredPercentage
}
pages
=
{
sectionProgress
.
totalPages
}
pageTitle
=
{
sectionProgress
.
pageTitle
}
/>
))
}
</
div
>
<
Survey
model
=
{
surveyModel
}
/>
</
div
>
);
}
else
{
return
<
span
>
loading...
</
span
>;
}
}
}
export
default
SurveyComponent
;
export
default
SurveyComponent
;
\ No newline at end of file
This diff is collapsed.
Click to expand it.
survey-frontend/src/survey.scss
+
4
−
0
View file @
4dbc8269
...
@@ -24,4 +24,8 @@
...
@@ -24,4 +24,8 @@
.sv-action-bar-item.verification.verification-ok
:hover
{
.sv-action-bar-item.verification.verification-ok
:hover
{
cursor
:
auto
;
cursor
:
auto
;
background-color
:
transparent
;
background-color
:
transparent
;
}
.survey-progress
{
display
:
flex
;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment