Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Data rearchitecture] sync with master #6096

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
df6c6f8
Improve BlockedUserAlert emails
cyrillefr May 2, 2024
1420423
Extend error logging for course data updates
wulanseruniati Oct 24, 2024
f1667b6
Add navigation utility hook for opening student details view
Abishekcs Dec 8, 2024
ef80c36
Use navigation utility hook in multiple components for opening studen…
Abishekcs Dec 8, 2024
9a07fca
Fix campaigns list rendering issue to consistently appear below Recen…
Abishekcs Dec 8, 2024
8e507b7
Localisation updates from https://translatewiki.net.
translatewiki Dec 9, 2024
ac972e4
Merge pull request #6047 from Abishekcs/fix/campaign-table-appears-wh…
ragesoss Dec 9, 2024
44a0b48
Merge pull request #6007 from wulanseruniati/error-logging-course-update
ragesoss Dec 10, 2024
24b9abb
chore: Remove unused ReviewerLink component and related code
Abishekcs Dec 11, 2024
61dc883
Merge pull request #6058 from Abishekcs/chore/remove-unused-reviewerlink
ragesoss Dec 11, 2024
c6c219e
[WIP] Bypass Revisions table queries for DiffViewer
ragesoss Dec 4, 2024
eaa6ac7
Fix DiffViewer error when there's only 1 revision
ragesoss Dec 5, 2024
bd96bce
Fix broken JS test
ragesoss Dec 9, 2024
ff3a87a
Fix broken rspec test for new details.json behavior
ragesoss Dec 10, 2024
80b7833
Localisation updates from https://translatewiki.net.
translatewiki Dec 12, 2024
def64a2
feat(milestones):add dates to milestones section (#6020)
shishiro26 Dec 13, 2024
f0ed9fc
fix: add missing interface message does_not_exist, used in the feedb…
Formasitchijoh Dec 17, 2024
677d731
fix: failing test in assigned_article_spec by waiting for the compone…
Formasitchijoh Dec 17, 2024
bde5268
fix:failing test in account_requests_spec by ensuring the confirm mod…
Formasitchijoh Dec 17, 2024
4d38f71
Merge pull request #6063 from Formasitchijoh/@outreachy/improve-test-…
ragesoss Dec 17, 2024
d0b9ec4
Merge pull request #6054 from Abishekcs/refactor/student-view-navigat…
ragesoss Dec 17, 2024
5220f4e
Generic label for Programs & Events Dashboard (#6061)
bhushan354 Dec 17, 2024
f951240
Remove the 'revisions' CSV download
ragesoss Dec 12, 2024
d77c021
Merge pull request #6065 from Formasitchijoh/@fix/account_request_spec
ragesoss Dec 17, 2024
0708c45
Remove features for generating CSVs of course/campaign revisions
ragesoss Dec 17, 2024
1b0bf00
Merge branch 'Improve_BlockedUserAlert_emails' of https://github.com/…
ragesoss Dec 17, 2024
a97297e
Tidy up email and preview for BlockedUserAlert mail
ragesoss Dec 17, 2024
ad1f07c
fixes the previous fix which failed, by adding an extra wait time to …
Formasitchijoh Dec 17, 2024
1e1e8b2
updated comment from referencing ores to using liftwing api
Formasitchijoh Dec 17, 2024
a8b016d
feat: Add visual indicator for closed courses (#6066)
swayam-agrahari Dec 18, 2024
83f294f
Fix broken conditionals in cloned question groups by updating referen…
Abishekcs Dec 14, 2024
7724cec
Update test suite to validate conditional parameters for cloned quest…
Abishekcs Dec 19, 2024
1e3bd09
Improved readability by renaming variables and comments for better co…
Abishekcs Dec 19, 2024
4856f0b
Localisation updates from https://translatewiki.net.
translatewiki Dec 19, 2024
a9dc385
Merge pull request #6064 from Abishekcs/fix/cloning-survey-group-cond…
ragesoss Dec 19, 2024
e85116c
Quick fix for plagiarism alerts with no Article record
ragesoss Dec 19, 2024
c16d5f8
Check Salesforce for closing timestamp as soon as courses end
ragesoss Dec 19, 2024
2f658ef
Don't do full update for a manual_update
ragesoss Dec 19, 2024
3172093
fix:increase Capybara default wait time to resolve category_scopes_sp…
Formasitchijoh Dec 19, 2024
da90e45
fix: use CampaignList index to ensure unique keys for course campaigns
Formasitchijoh Dec 19, 2024
e43a8f2
fix: handle undefined 'valid' and 'search' values in course_reator page
Formasitchijoh Dec 19, 2024
c2623bf
add visual indicator for campaign view
swayam-agrahari Dec 20, 2024
a7eaabc
feat: enhance WeekdayPicker accessibility with aria-label and aria-li…
Abishekcs Dec 11, 2024
5223d0d
fixed some linting issue
swayam-agrahari Dec 20, 2024
759e1fc
Remove fetchUserRevisions from StudentExercise
ragesoss Dec 20, 2024
ff904ab
Remove unused prop
ragesoss Dec 20, 2024
00de9de
Get recent revisions from wiki instead Dashboard
ragesoss Dec 20, 2024
9248acf
Remove RevisionsController
ragesoss Dec 20, 2024
07fe87a
Remove unused routes
ragesoss Dec 20, 2024
53b823a
Remove broken reducer spec
ragesoss Dec 20, 2024
15624e0
Merge pull request #6071 from swayam-agrahari/master
ragesoss Dec 20, 2024
738ceac
Fix users_path
ragesoss Dec 20, 2024
57c8959
Merge pull request #6073 from WikiEducationFoundation/StudentRevision…
ragesoss Dec 20, 2024
32227a6
Fix commented-out tests and Poltergeist selector issues in SurveyAdmi…
Abishekcs Dec 22, 2024
4ecaf09
Localisation updates from https://translatewiki.net.
translatewiki Dec 23, 2024
9fd13fc
Localisation updates from https://translatewiki.net.
translatewiki Dec 26, 2024
b2b9aa1
Initial work on adding new student endpoint
Aminehassou Dec 26, 2024
32ddb9b
fixing Unnecessary Logs, Preventing System Inefficiencies and Ineffic…
JiyaGupta-cs Dec 29, 2024
23e4a78
Added endpoints for classroomprogram courses and fellowscohort courses
Aminehassou Dec 29, 2024
9e5b8e8
Localisation updates from https://translatewiki.net.
translatewiki Dec 30, 2024
745f93a
Merge pull request #6076 from Abishekcs/fix/survey-admin-spec-tests
ragesoss Dec 30, 2024
6f8a743
Update 'cite systematic reviews' exercise
ragesoss Dec 30, 2024
a01b22c
Fix 'show last revision' toggle
ragesoss Dec 30, 2024
41e0c8e
Adds Admin guide explaining how the dashboard is run on Toolforge and…
empty-codes Dec 30, 2024
a2cbae3
Include registration date in campaign user CSV data
ragesoss Dec 30, 2024
42bc73f
Merge pull request #6078 from JiyaGupta-cs/populate_logs
ragesoss Dec 30, 2024
6afed6e
Filtered out data from newly-added endpoints for easier access
Aminehassou Dec 31, 2024
cb55336
fix(DiffViewer & ArticleViewer): handle moved articles using MediaWik…
Abishekcs Dec 31, 2024
d8d46eb
fix-failing-test: apply 10-second wait for article viewer spec tests
Abishekcs Dec 31, 2024
3465125
Merge pull request #6072 from Abishekcs/fix/diffviewer-handle-moved-a…
ragesoss Dec 31, 2024
3d912ba
Merge pull request #6080 from Aminehassou/AddStudentProgramEndpoint
ragesoss Dec 31, 2024
d43dc28
fix:issue with meeting dates extending beyond the ending date. (#6028)
shishiro26 Dec 31, 2024
622b37b
Merge pull request #6055 from Abishekcs/fix/screen-reader-weekdaypick…
ragesoss Dec 31, 2024
b382331
Restructures contents + Adds details about 3rd party APIs and tools t…
empty-codes Dec 31, 2024
14e2da5
Fix linting violations
ragesoss Dec 31, 2024
5ba4451
Updates tool descriptions to focus on how the Dashboard uses each + M…
empty-codes Dec 31, 2024
782e990
Merge pull request #6082 from empty-codes/improve-documentation-phabT…
ragesoss Dec 31, 2024
efc5e32
Localisation updates from https://translatewiki.net.
translatewiki Jan 2, 2025
7517540
Merge pull request #6070 from Formasitchijoh/@fix/front-end-bug
ragesoss Jan 2, 2025
3d3a960
Adds links to admin guide in relevant docs + Add link to main README …
empty-codes Jan 2, 2025
c70d184
Merge pull request #6084 from empty-codes/link-to-admin-guide
ragesoss Jan 2, 2025
14a906b
Resolve Style/StringConcatenation rubocop violations and enable the …
bhushan354 Jan 3, 2025
d589414
fix: made end date for course creation in student role spec dynamic
Formasitchijoh Jan 4, 2025
320b525
Merge pull request #6086 from Formasitchijoh/@fix/multiwiki_student_r…
ragesoss Jan 4, 2025
ac19ee0
Localisation updates from https://translatewiki.net.
translatewiki Jan 6, 2025
25ac01d
Merge remote-tracking branch 'upstream/master' into data-rearchitectu…
gabina Jan 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ Layout/HashAlignment:
Enabled: false # Hashes look uglier when corrected
Rails/I18nLocaleTexts:
Enabled: false # Generally the translations are done manually so most times many language translations will be missing while the fallback message is English
Style/StringConcatenation:
Enabled: false

########################
# Temporary exceptions #
Expand Down Expand Up @@ -171,8 +173,6 @@ Style/DateTime:
Enabled: false
Rails/ContentTag:
Enabled: false
Style/StringConcatenation:
Enabled: false
Style/OptionalBooleanParameter:
Enabled: false
Style/ExplicitBlockArgument:
Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ If you're a new developer and you're looking for an easy way to get involved, tr
- [MediaWiki API Sandbox](https://en.wikipedia.org/wiki/Special%3aApiSandbox)
- [Quarry](http://quarry.wmflabs.org/): Public querying interface for the Labs replica database. Very useful for testing SQL queries and for figuring out what data is available.
- [Guide to the front end](docs/frontend.md)
- [Admin Guide](docs/admin_guide.md): Overview of the Dashboard infrastructure, including servers, tools, dependencies, and troubleshooting resources.
- [Vagrant](https://github.com/marxarelli/wikied-vagrant): a configuration to quickly get a development environment up and running using Vagrant. If you already have VirtualBox and/or Vagrant on your machine, this might be a simple way to set up a dev environment. However, it is not actively maintained. If you try it and run into problems, let us know!

#### Code Style
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ This project welcomes contributions, and we try to be as newbie-friendly as poss
- [Interface strings & Internationalization](docs/i18n.md)
- [OAuth setup](docs/oauth.md)
- [Deployment](docs/deploy.md)
- [Admin Guide](docs/admin_guide.md) - Overview of the Dashboard infrastructure, including servers, tools, dependencies, and troubleshooting resources.
- [Tools & Integrations](docs/tools.md)
- [Using Docker for development](docs/docker.md)
- [Model diagram](erd.pdf)
Expand Down
94 changes: 87 additions & 7 deletions app/assets/javascripts/actions/article_actions.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,70 @@
import * as types from '../constants';
import API from '../utils/api.js';
import { getRevisionRange } from '../utils/mediawiki_revisions_utils';
import { find } from 'lodash-es';

// This action uses the Thunk middleware pattern: instead of returning a plain
// action object, it returns a function that takes the store dispatch fucntion
// action object, it returns a function that takes the store dispatch function
// which Thunk automatically provides — and can then dispatch a series of plain
// actions to be handled by the store.
// This is how actions with side effects — such as API calls — are handled in
// Redux.
export function fetchArticleDetails(articleId, courseId) {
return function (dispatch) {
return async function (dispatch, getState) {
return API.fetchArticleDetails(articleId, courseId)
.then(response => (dispatch({
type: types.RECEIVE_ARTICLE_DETAILS,
articleId,
data: response
})))
.then((response) => {
const details = response.article_details;

return getRevisionRange(details.apiUrl, details.articleTitle, details.editors, details.startDate, details.endDate)
.then(async (revisionRange) => {
// If no revisions are found (both first and last revisions are missing),
// it may indicate a mismatch in the article title as the article was moved to a new title.
if (!revisionRange.first_revision && !revisionRange.last_revision) {
const { title: articleTitle, mw_page_id: article_mw_page_id } = find(
getState().articles.articles,
{ id: articleId }
);

// Dispatch an action to cross-check the article title with its metadata.
const crossCheckedArticleTitle = await dispatch(crossCheckArticleTitle(articleId, articleTitle, article_mw_page_id));

// Re-fetch the article details using the cross-checked title for accuracy.
fetchArticleDetailsAgain(crossCheckedArticleTitle, articleId, courseId, dispatch);
} else {
dispatch({ type: types.RECEIVE_ARTICLE_DETAILS, articleId, details, revisionRange });
}
});
})
.catch(response => (dispatch({ type: types.API_FAIL, data: response })));
};
}

// Re-fetches article details using the corrected or cross-checked article title.
// This function is used when the initial fetch fails to retrieve valid revision data,
// likely due to a mismatch in the article title. It ensures the Redux store is updated
// with accurate article details and revision ranges after the re-fetch.
function fetchArticleDetailsAgain(crossCheckedArticleTitle, articleId, courseId, dispatch) {
return API.fetchArticleDetails(articleId, courseId)
.then((response) => {
const details = response.article_details;

// Calculate the revision range for the updated article title.
return getRevisionRange(
details.apiUrl,
crossCheckedArticleTitle,
details.editors,
details.startDate,
details.endDate
).then((revisionRange) => {
// Dispatch the updated article details and revision range to Redux.
dispatch({ type: types.RECEIVE_ARTICLE_DETAILS, articleId, details, revisionRange });
});
})
.catch((response) => {
(dispatch({ type: types.API_FAIL, data: response }));
});
}

export function updateArticleTrackedStatus(articleId, courseId, tracked) {
return function (dispatch) {
return API.updateArticleTrackedStatus(articleId, courseId, tracked).then(response => (dispatch({
Expand All @@ -29,3 +75,37 @@ export function updateArticleTrackedStatus(articleId, courseId, tracked) {
}))).catch(response => (dispatch({ type: types.API_FAIL, data: response })));
};
}

export const crossCheckArticleTitle = (articleId, articleTitle, article_mw_page_id) => {
return async (dispatch) => {
try {
// Fetch the page title from Wikipedia API
const response = await fetch(
`https://en.wikipedia.org/w/api.php?action=query&pageids=${article_mw_page_id}&format=json&origin=*`
);

if (!response.ok) {
throw new Error(`API request failed with status ${response.status}`);
}

const apiResponse = await response.json();
const wikipediaArticleTitle = apiResponse.query.pages[article_mw_page_id]?.title;

if (wikipediaArticleTitle && wikipediaArticleTitle !== articleTitle) {
const baseUrl = 'https://en.wikipedia.org/wiki/';
const updatedUrl = `${baseUrl}${wikipediaArticleTitle.replace(/ /g, '_')}`;

dispatch({
type: types.UPDATE_ARTICLE_TITLE_AND_URL,
payload: { articleId, title: wikipediaArticleTitle, url: updatedUrl },
});

return wikipediaArticleTitle;
}

return articleTitle;
} catch (error) {
dispatch({ type: types.API_FAIL, data: error });
}
};
};
26 changes: 7 additions & 19 deletions app/assets/javascripts/actions/user_revisions_actions.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
import { RECEIVE_USER_REVISIONS, API_FAIL } from '../constants';
import logErrorMessage from '../utils/log_error_message';
import request from '../utils/request';
import { fetchLatestRevisionsForUser } from '../utils/mediawiki_revisions_utils';


const fetchUserRevisionsPromise = async (courseId, userId) => {
const response = await request(`/revisions.json?user_id=${userId}&course_id=${courseId}`);
if (!response.ok) {
logErrorMessage(response);
const data = await response.text();
response.responseText = data;
throw response;
}
return response.json();
};

export const fetchUserRevisions = (courseId, userId) => (dispatch, getState) => {
export const fetchUserRevisions = (course, user) => (dispatch, getState) => {
// Don't refetch a user's revisions if they are already in the store.
if (getState().userRevisions[userId]) { return; }
if (getState().userRevisions[user.username]) { return; }

return (
fetchUserRevisionsPromise(courseId, userId)
fetchLatestRevisionsForUser(user.username, course.home_wiki)
.then((resp) => {
dispatch({
type: RECEIVE_USER_REVISIONS,
data: resp,
userId
revisions: resp,
username: user.username,
wiki: course.home_wiki
});
})
.catch(response => (dispatch({ type: API_FAIL, data: response })))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const CampaignStatsDownloadModal = ({ campaign_slug }) => {

const courseDataLink = `/campaigns/${campaign_slug}/courses.csv`;
const articlesEditedLink = `/campaigns/${campaign_slug}/articles_csv.csv`;
const RevisionsLink = `/campaigns/${campaign_slug}/revisions_csv.csv`;
const editorsLink = `/campaigns/${campaign_slug}/students.csv`;
const editorsByCourseLink = `/campaigns/${campaign_slug}/students.csv?course=true`;
const instructorsLink = `/campaigns/${campaign_slug}/instructors.csv?course=true`;
Expand All @@ -32,11 +31,6 @@ const CampaignStatsDownloadModal = ({ campaign_slug }) => {
{I18n.t('campaign.data_articles_info')}
</p>
<hr />
<p>
<a href={RevisionsLink} className="button right">{I18n.t('campaign.data_revisions')}</a>
{I18n.t('campaign.data_revisions_info')}
</p>
<hr />
<p>
<a href={editorsLink} className="button right">{I18n.t('campaign.data_editor_usernames')}</a>
{I18n.t('campaign.data_editor_usernames_info')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import colors from '@components/common/ArticleViewer/constants/colors';

// Actions
import { resetBadWorkAlert, submitBadWorkAlert } from '~/app/assets/javascripts/actions/alert_actions.js';
import { crossCheckArticleTitle } from '@actions/article_actions';

/*
Quick summary of the ArticleViewer component's main logic
Expand Down Expand Up @@ -55,7 +56,11 @@ const ArticleViewer = ({ showOnMount, users, showArticleFinder, showButtonLabel,
const [unhighlightedContributors, setUnhighlightedContributors] = useState([]);
const [revisionId, setRevisionId] = useState(null);
const [pendingRequest, setPendingRequest] = useState(false);
const lastRevisionId = useSelector(state => state.articleDetails[article.id]?.last_revision?.mw_rev_id);
const lastRevisionId = useSelector(state => state.articleDetails[article.id]?.last_revision?.revid);

// State to track whether the article title needs to be verified and updated
// (i.e., if a fetch failed due to the article title being moved)
const [checkArticleTitle, setCheckArticleTitle] = useState(false);

const dispatch = useDispatch();
const ref = useRef();
Expand Down Expand Up @@ -245,6 +250,8 @@ const ArticleViewer = ({ showOnMount, users, showArticleFinder, showButtonLabel,
setFailureMessage(error.message);
setFetched(true);
setWhoColorFailed(true);
// Set flag to verify and fetch the article title if the fetch failed, possibly due to the article being moved
setCheckArticleTitle(true);
});
};

Expand All @@ -257,9 +264,32 @@ const ArticleViewer = ({ showOnMount, users, showArticleFinder, showButtonLabel,
}).catch((error) => {
setWhoColorFailed(true);
setFailureMessage(error.message);
// Set flag to verify and fetch the article title if the fetch failed, possibly due to the article being moved
setCheckArticleTitle(true);
});
};

// Function to verify if the article title has changed and fetch updated data accordingly
const verifyAndFetchArticle = async () => {
// Dispatch an action to cross-check the current article title using its ID and MediaWiki page ID
const crossCheckedArticleTitle = await dispatch(crossCheckArticleTitle(article.id, article.title, article.mw_page_id));

if (crossCheckedArticleTitle === article.title) {
setWhoColorFailed(false); // Clear the failure state for WhoColor data
setCheckArticleTitle(false); // Stop further title verification checks
fetchParsedArticle(); // Re-fetch the parsed article content with the current title
fetchWhocolorHtml(); // Re-fetch the WhoColor HTML for the article using the current title
} else if (crossCheckArticleTitle !== article.title) {
setFetched(false); // Indicate a loading state until the Redux store updates the new article title and the component re-renders
}
};

// Trigger the article title verification and data fetching process if a previous fetch failed
if (checkArticleTitle) {
verifyAndFetchArticle();
}


// These are mediawiki user ids, and don't necessarily match the dashboard
// database user ids, so we must fetch them by username from the wiki.
const fetchUserIds = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ const AssignmentLinks = ({ assignment, courseType, user, course, project, editMo
let groupMembers;
if (editors) {
if (role === ASSIGNED_ROLE) {
groupMembers = <GroupMembersLink members={editors} />;
groupMembers = <GroupMembersLink members={editors} course={course} />;
} else {
groupMembers = <EditorLink key={`editor-${id}`} editors={editors} />;
groupMembers = <EditorLink key={`editor-${id}`} editors={editors} course={course} />;
}
}

Expand All @@ -70,7 +70,6 @@ const AssignmentLinks = ({ assignment, courseType, user, course, project, editMo
reviewers = <AllPeerReviewLinks assignment={assignment} />;
}

// const reviewers = <ReviewerLink key={`reviewers-${id}`} reviewers={assignment.reviewers} />;
const links = actions.reduce(interleaveSeparators, []);

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import PropTypes from 'prop-types';

import AssignedToLink from '@components/overview/my_articles/common/AssignedToLink.jsx';

export const EditorLink = ({ editors }) => {
return <AssignedToLink members={editors} name="editors" />;
export const EditorLink = ({ editors, course }) => {
return <AssignedToLink members={editors} course={course} name="editors" />;
};

EditorLink.propTypes = {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';

import AssignedToLink from '@components/overview/my_articles/common/AssignedToLink.jsx';

export const GroupMembersLink = ({ members }) => {
return <AssignedToLink members={members} name="group_members" />;
export const GroupMembersLink = ({ members, course }) => {
return <AssignedToLink members={members} course={course} name="group_members" />;
};

GroupMembersLink.propTypes = {
Expand Down

This file was deleted.

22 changes: 17 additions & 5 deletions app/assets/javascripts/components/common/weekday_picker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const WeekdayPicker = ({
style,
tabIndex,

ariaModifier,
modifiers,

locale,
Expand Down Expand Up @@ -145,7 +144,7 @@ const WeekdayPicker = ({

dayClassName += customModifiers.map(modifier => ` ${dayClassName}--${modifier}`).join('');

const ariaSelected = customModifiers.indexOf(ariaModifier) > -1;
const ariaSelected = customModifiers.indexOf('selected') > -1;

let tabIndexValue = null;
if (onWeekdayClick) {
Expand All @@ -159,10 +158,20 @@ const WeekdayPicker = ({
const onMouseEnterHandler = onWeekdayMouseEnter ? e => handleWeekdayMouseEnter(e, weekday, customModifiers) : null;
const onMouseLeaveHandler = onWeekdayMouseLeave ? e => handleWeekdayMouseLeave(e, weekday, customModifiers) : null;

const ariaLabelMessage = ariaSelected
? I18n.t('weekday_picker.aria.weekday_selected', { weekday: localeUtils.formatWeekdayLong(weekday), })
: I18n.t('weekday_picker.aria.weekday_select', { weekday: localeUtils.formatWeekdayLong(weekday), });

const ariaLiveMessage = ariaSelected
? I18n.t('weekday_picker.aria.weekday_selected', { weekday: localeUtils.formatWeekdayLong(weekday), })
: I18n.t('weekday_picker.aria.weekday_unselected', { weekday: localeUtils.formatWeekdayLong(weekday), });

return (
<button
key={weekday} className={dayClassName} tabIndex={tabIndexValue}
aria-pressed={ariaSelected}
key={weekday}
className={dayClassName}
tabIndex={tabIndexValue}
aria-label= {ariaLabelMessage}
onClick={onClickHandler}
onKeyDown={e => handleDayKeyDown(e, weekday, customModifiers)}
onMouseEnter={onMouseEnterHandler}
Expand All @@ -171,6 +180,10 @@ const WeekdayPicker = ({
<span title={localeUtils.formatWeekdayLong(weekday)}>
{localeUtils.formatWeekdayShort(weekday)}
</span>
{/* Aria-live region for screen reader announcements for confirmation of when a week day is selected or unselected */}
<div aria-live="assertive" aria-atomic="true" className="sr-WeekdayPicker-aria-live">
{ariaLiveMessage}
</div>
</button>
);
};
Expand Down Expand Up @@ -201,7 +214,6 @@ WeekdayPicker.propTypes = {
style: PropTypes.object,
tabIndex: PropTypes.number,

ariaModifier: PropTypes.string,
modifiers: PropTypes.object,

locale: PropTypes.string,
Expand Down
Loading
Loading