Skip to content

Commit

Permalink
Display badge indicating when a student dropped an assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya committed Dec 4, 2024
1 parent c6bf186 commit dfaced7
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 30 deletions.
3 changes: 3 additions & 0 deletions lms/static/scripts/frontend_apps/api-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,9 @@ export type Student = {
h_userid: string;
lms_id: string;
display_name: string | null;

/** Whether this student is active in the course/assignment or roster */
active: boolean;
};

export type AutoGradingGrade = {
Expand Down
23 changes: 23 additions & 0 deletions lms/static/scripts/frontend_apps/components/Badge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import classnames from 'classnames';

export type BadgeType = 'new' | 'error' | 'syncing' | 'drop';

export default function Badge({ type }: { type: BadgeType }) {
return (
<div
className={classnames(
'px-1 py-0.5 rounded cursor-auto font-bold uppercase text-[0.65rem]',
{
'bg-grey-7 text-white': type === 'new' || type === 'drop',
'bg-grade-error-light text-grade-error': type === 'error',
'bg-grey-2 text-grey-7': type === 'syncing',
},
)}
>
{type === 'new' && 'New'}
{type === 'error' && 'Error'}
{type === 'syncing' && 'Syncing'}
{type === 'drop' && 'Drop'}
</div>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { courseURL } from '../../utils/dashboard/navigation';
import { rootViewTitle } from '../../utils/dashboard/root-view-title';
import { useDocumentTitle } from '../../utils/hooks';
import { type QueryParams, replaceURLParams } from '../../utils/url';
import Badge from '../Badge';
import RelativeTime from '../RelativeTime';
import type {
DashboardActivityFiltersProps,
Expand Down Expand Up @@ -47,6 +48,9 @@ type StudentsTableRow = {
* If the assignment is not auto-grading, this will be ´undefined`.
*/
last_grade?: number | null;

/** Whether this student is active in the course/assignment or roster */
active: boolean;
};

/**
Expand Down Expand Up @@ -380,16 +384,26 @@ export default function AssignmentActivity() {
''
);
case 'display_name':
return (
stats.display_name ?? (
<span className="flex flex-col gap-1.5">
<span className="italic">Unknown</span>
<span className="text-xs text-grey-7">
This student launched the assignment but didn{"'"}t
annotate yet
</span>
return stats.display_name ? (
<div className="flex items-center justify-between gap-x-2">
{stats.display_name}
{!stats.active && (
<div
className="-my-0.5"
title="This student is no longer in this assignment"
>
<Badge type="drop" />
</div>
)}
</div>
) : (
<div className="flex flex-col gap-1.5">
<span className="italic">Unknown</span>
<span className="text-xs text-grey-7">
This student launched the assignment but didn{"'"}t annotate
yet
</span>
)
</div>
);
case 'current_grade':
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import type {
AutoGradingConfig,
StudentGradingSyncStatus,
} from '../../api-types';
import type { BadgeType } from '../Badge';
import Badge from '../Badge';
import GradeStatusChip from './GradeStatusChip';

type AnnotationCountProps = {
Expand Down Expand Up @@ -57,27 +59,6 @@ function SectionTitle({ children }: { children: ComponentChildren }) {
);
}

type BadgeType = 'new' | 'error' | 'syncing';

function Badge({ type }: { type: BadgeType }) {
return (
<div
className={classnames(
'px-1 py-0.5 rounded cursor-auto font-bold uppercase text-[0.65rem]',
{
'bg-grey-7 text-white': type === 'new',
'bg-grade-error-light text-grade-error': type === 'error',
'bg-grey-2 text-grey-7': type === 'syncing',
},
)}
>
{type === 'new' && 'New'}
{type === 'error' && 'Error'}
{type === 'syncing' && 'Syncing'}
</div>
);
}

export type GradeIndicatorProps = {
grade: number;
lastGrade?: number | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ describe('AssignmentActivity', () => {
current_grade: 0.5,
last_grade: null,
},
active: true,
},
{
display_name: 'a',
Expand All @@ -35,6 +36,7 @@ describe('AssignmentActivity', () => {
current_grade: 0.8,
last_grade: 0.61,
},
active: true,
},
{
display_name: 'c',
Expand All @@ -47,6 +49,7 @@ describe('AssignmentActivity', () => {
current_grade: 0.4,
last_grade: null,
},
active: false,
},
];
const activeAssignment = {
Expand Down Expand Up @@ -121,6 +124,8 @@ describe('AssignmentActivity', () => {
// Do not mock FormattedDate, for consistency when checking
// rendered values in different columns
'./FormattedDate': true,
// Let badges render normally so that we can assert on their text
'../Badge': true,
});
$imports.$mock({
'../../utils/api': {
Expand Down Expand Up @@ -231,13 +236,23 @@ describe('AssignmentActivity', () => {
display_name: null,
},
},
// Render inactive user's display name
{
fieldName: 'display_name',
expectedValue: 'Jane DoeDrop',
studentStats: {
display_name: 'Jane Doe',
active: false,
},
},
].forEach(({ fieldName, expectedValue, studentStats }) => {
it('renders every field as expected', () => {
const fallbackStudentStats = {
display_name: 'Jane Doe',
last_activity: '2024-01-01T10:35:18',
annotations: 37,
replies: 25,
active: true,
};
const wrapper = createComponent();

Expand Down

0 comments on commit dfaced7

Please sign in to comment.