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

Added a new editor filter button to the Activity tab. #6221

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 38 additions & 3 deletions app/assets/javascripts/components/revisions/revisions_handler.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { ARTICLE_FETCH_LIMIT } from '../../constants/revisions.js';
import Select from 'react-select';
import sortSelectStyles from '../../styles/sort_select';
import { getStudentUsers } from '../../selectors/index.js';
import { sortByKey } from '../../utils/model_utils.js';

const RevisionHandler = ({ course, courseScopedLimit }) => {
const [isCourseScoped, setIsCourseScoped] = useState(false);
const [isNewEditor, setIsNewEditor] = useState(false);

const dispatch = useDispatch();

Expand Down Expand Up @@ -74,10 +76,19 @@ const RevisionHandler = ({ course, courseScopedLimit }) => {
}
};

const toggleNewEditor = () => {
const toggledIsNewEditor = !isNewEditor;
setIsNewEditor(toggledIsNewEditor);
};

const revisionFilterButtonText = () => {
return isCourseScoped ? I18n.t('revisions.show_all') : I18n.t('revisions.show_course_specific');
};

const newEditorFilterButtonText = () => {
return isNewEditor ? 'Show all' : 'Show new Editors';
};

const sortSelect = (e) => {
dispatch(sortRevisions(e.value));
};
Expand All @@ -102,7 +113,11 @@ const RevisionHandler = ({ course, courseScopedLimit }) => {
// we only fetch articles data for a max of 500 articles(for course specific revisions).
// If there are more than 500 articles, the toggle button is not shown
const revisionFilterButton = (
<div><button className="button ghost stacked right" onClick={toggleCourseSpecific}>{revisionFilterButtonText()}</button></div>
<button className="button ghost stacked right" style={{ marginLeft: '10px' }} onClick={toggleCourseSpecific}>{revisionFilterButtonText()}</button>
);

const editorFilterButton = (
<button className="button ghost stacked right" onClick={toggleNewEditor}>{newEditorFilterButtonText()}</button>
);

const options = [
Expand All @@ -114,11 +129,31 @@ const RevisionHandler = ({ course, courseScopedLimit }) => {
{ value: 'date', label: I18n.t('revisions.date_time') },
];

const filterRevisions = () => {
let revisions = isCourseScoped ? revisionsDisplayedCourseSpecific : revisionsDisplayed;
if (isNewEditor) {
// this filters out the revisions where the user registered after the course start date and presents only those revisions
revisions = revisions.filter((revision) => {
const registered_at = new Date(revision.registered_at);
const course_start = new Date(course.start);
return registered_at > course_start;
});

const sorted = sortByKey(revisions, 'registered_at');
return sorted.newModels;
}
return revisions;
};


return (
<div id="revisions">
<div className="section-header">
<h3>{I18n.t('application.recent_activity')}</h3>
{course.article_count <= ARTICLE_FETCH_LIMIT && revisionFilterButton}
<div>
{course.article_count <= ARTICLE_FETCH_LIMIT && revisionFilterButton}
{editorFilterButton}
</div>
<div className="sort-container">
<Select
name="sorts"
Expand All @@ -130,7 +165,7 @@ const RevisionHandler = ({ course, courseScopedLimit }) => {
</div>
<div className="revision-list-container">
<RevisionList
revisions={isCourseScoped ? revisionsDisplayedCourseSpecific : revisionsDisplayed}
revisions={filterRevisions()}
loaded={loaded}
course={course}
sortBy={sortRevisions}
Expand Down
9 changes: 9 additions & 0 deletions app/assets/javascripts/utils/mediawiki_revisions_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const fetchAll = async (API_URL, params, continue_str) => {
// currently its used to filter tracked articles
export const fetchRevisionsFromUsers = async (course, users, days, last_date, filter) => {
const usernames = users.map(user => user.username);
const registered_dates = users.map(user => user.registered_at);

let revisions = [];
const wikiPromises = [];
Expand Down Expand Up @@ -80,6 +81,14 @@ export const fetchRevisionsFromUsers = async (course, users, days, last_date, fi
// remove duplicates
// they occur because dates overlap and sometimes the same revision is included twice
revisions = [...new Map(revisions.map(v => [v.id, v])).values()];
// adds the enrolled_at property to each revision
revisions = revisions.map((revision) => {
const userIndex = usernames.indexOf(revision.user);
return {
...revision,
registered_at: userIndex !== -1 ? registered_dates[userIndex] : null
};
});

return { revisions, last_date };
};
Expand Down
1 change: 1 addition & 0 deletions app/views/courses/_users.json.jbuilder
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ json.users course.courses_users.eager_load(:user, :course) do |cu|
json.call(cu.user, :id, :username)
json.enrolled_at cu.created_at
json.admin cu.user.admin?
json.registered_at cu.user.registered_at

exercise_progress = cu.course.training_progress_manager.course_exercise_progress(cu.user)
if exercise_progress.is_a?(Hash)
Expand Down
Loading