* feat: add language selection chore: update tests so we have less error message test: update test * test: update tests * chore: remove duplicate translation * chore: lint for console * chore: remove comments * chore: make sure the affect url frame refresh after the language selection change * chore: add whole_course_translation and language to courseware meta (#1305) * feat: Add feedback widget UI mock Add unit tests Fix snapshot Clean Sequence component logEvent calls Clean unit test Put feedback widget behind whole course translation flag Fix useFeedbackWidget test * chore: add src and dest translation * feat: first iteration of plugin translation chore: update plugin instruction * feat: Connect FeedbackWidget with backend services (#1325) Connect FeedbackWidget with backend services Move feedback widget to unit translation plugin * feat: Add authentication to WCT feedback endpoints (#1329) * chore: add fetch config and move feedback widget for the plugin chore: rewrite and test the api request chore: rebase chore: update translation feedback chore: test chore: add more tests * chore: rebase * chore: update requested change * chore: update package * chore: upgrade frontend-lib-special-exams and frontend-lib-learning-assistant * chore: update tests * chore: remove unneeded package * chore: update example config * chore: add source-map-loader * fix: feedback widget render error after submit feedback (#1335) * fix: feedback widget render error after submit feedback * fix: widget logic --------- Co-authored-by: Rodrigo Martin <rodrigom_94@hotmail.com>
60 lines
1.8 KiB
JavaScript
60 lines
1.8 KiB
JavaScript
import React, { useState } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
|
|
import { OverlayTrigger, Popover } from '@openedx/paragon';
|
|
|
|
import messages from './messages';
|
|
|
|
const IncompleteDonutSegment = ({ incompletePercentage, intl }) => {
|
|
const [showIncompletePopover, setShowIncompletePopover] = useState(false);
|
|
|
|
if (!incompletePercentage) {
|
|
return null;
|
|
}
|
|
|
|
const incompleteSegmentOffset = (3.6 * incompletePercentage) / 16;
|
|
const incompleteTooltipDegree = incompletePercentage < 100 ? incompleteSegmentOffset : 0;
|
|
|
|
return (
|
|
<g
|
|
className="donut-segment-group"
|
|
onBlur={() => setShowIncompletePopover(false)}
|
|
onFocus={() => setShowIncompletePopover(true)}
|
|
tabIndex="-1"
|
|
>
|
|
<circle
|
|
className="donut-ring incomplete-stroke"
|
|
cx="21"
|
|
cy="21"
|
|
r="15.91549430918954"
|
|
strokeDasharray={`${incompletePercentage} ${100 - incompletePercentage}`}
|
|
strokeDashoffset="25"
|
|
/>
|
|
|
|
{/* Tooltip */}
|
|
<OverlayTrigger
|
|
show={showIncompletePopover}
|
|
placement="top"
|
|
overlay={(
|
|
<Popover id="incomplete-tooltip-popover" aria-hidden="true">
|
|
<Popover.Content>
|
|
{intl.formatMessage(messages.incompleteContentTooltip)}
|
|
</Popover.Content>
|
|
</Popover>
|
|
)}
|
|
>
|
|
{/* Used to anchor the tooltip within the incomplete segment's stroke */}
|
|
<rect x="19" y="3" style={{ transform: `rotate(${incompleteTooltipDegree}deg)` }} />
|
|
</OverlayTrigger>
|
|
</g>
|
|
);
|
|
};
|
|
|
|
IncompleteDonutSegment.propTypes = {
|
|
incompletePercentage: PropTypes.number.isRequired,
|
|
intl: intlShape.isRequired,
|
|
};
|
|
|
|
export default injectIntl(IncompleteDonutSegment);
|