Skip to content

Commit

Permalink
Mitigate word wrapping in date columns for dashboard activity tables (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
acelaya authored Jun 21, 2024
1 parent a5d1137 commit 9b4feee
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { useParams } from 'wouter-preact';
import type { Assignment, StudentsResponse } from '../../api-types';
import { useConfig } from '../../config';
import { urlPath, useAPIFetch } from '../../utils/api';
import { formatDateTime } from '../../utils/date';
import { replaceURLParams } from '../../utils/url';
import DashboardBreadcrumbs from './DashboardBreadcrumbs';
import FormattedDate from './FormattedDate';
import OrderableActivityTable from './OrderableActivityTable';

type StudentsTableRow = {
Expand Down Expand Up @@ -100,9 +100,11 @@ export default function AssignmentActivity() {
case 'replies':
return <div className="text-right">{stats[field]}</div>;
case 'last_activity':
return stats.last_activity
? formatDateTime(new Date(stats.last_activity))
: '';
return stats.last_activity ? (
<FormattedDate date={stats.last_activity} />
) : (
''
);
case 'display_name':
return (
stats.display_name ?? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { Link as RouterLink, useParams } from 'wouter-preact';
import type { AssignmentsResponse, Course } from '../../api-types';
import { useConfig } from '../../config';
import { urlPath, useAPIFetch } from '../../utils/api';
import { formatDateTime } from '../../utils/date';
import { replaceURLParams } from '../../utils/url';
import DashboardBreadcrumbs from './DashboardBreadcrumbs';
import FormattedDate from './FormattedDate';
import OrderableActivityTable from './OrderableActivityTable';

type AssignmentsTableRow = {
Expand Down Expand Up @@ -105,7 +105,7 @@ export default function CourseActivity() {
}

return (
stats.last_activity && formatDateTime(new Date(stats.last_activity))
stats.last_activity && <FormattedDate date={stats.last_activity} />
);
}}
navigateOnConfirmRow={stats => assignmentURL(stats.id)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMemo } from 'preact/hooks';

import { formatDateTime } from '../../utils/date';

export type FormattedDateProps = {
/** Date in ISO format */
date: string;
};

/**
* Formats a date for current user's locale, and shows it in a non-wrapping
* container
*/
export default function FormattedDate({ date }: FormattedDateProps) {
const formattedDate = useMemo(() => formatDateTime(new Date(date)), [date]);
return <div className="whitespace-nowrap">{formattedDate}</div>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function OrderableActivityTable<T>({
columns.map(({ field, label }, index) => ({
field,
label,
classes: index === 0 ? 'w-[60%]' : undefined,
classes: index === 0 ? 'lg:w-[60%] md:w-[45%]' : undefined,
})),
[columns],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { Link as RouterLink } from 'wouter-preact';
import type { CoursesResponse } from '../../api-types';
import { useConfig } from '../../config';
import { urlPath, useAPIFetch } from '../../utils/api';
import { formatDateTime } from '../../utils/date';
import { replaceURLParams } from '../../utils/url';
import FormattedDate from './FormattedDate';
import OrderableActivityTable from './OrderableActivityTable';

export type OrganizationActivityProps = {
Expand Down Expand Up @@ -76,9 +76,11 @@ export default function OrganizationActivity({
if (field === 'assignments') {
return <div className="text-right">{stats[field]}</div>;
} else if (field === 'last_launched') {
return stats.last_launched
? formatDateTime(new Date(stats.last_launched))
: '';
return stats.last_launched ? (
<FormattedDate date={stats.last_launched} />
) : (
''
);
}

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ describe('AssignmentActivity', () => {
};

$imports.$mock(mockImportedComponents());
$imports.$restore({
// Do not mock FormattedDate, for consistency when checking
// rendered values in different columns
'./FormattedDate': true,
});
$imports.$mock({
'../../utils/api': {
useAPIFetch: fakeUseAPIFetch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { mount } from 'enzyme';
import sinon from 'sinon';

import { Config } from '../../../config';
import { formatDateTime } from '../../../utils/date';
import CourseActivity, { $imports } from '../CourseActivity';

describe('CourseActivity', () => {
Expand Down Expand Up @@ -154,7 +153,7 @@ describe('CourseActivity', () => {
{ fieldName: 'replies', expectedValue: '25' },
{
fieldName: 'last_activity',
expectedValue: formatDateTime(new Date('2024-01-01T10:35:18')),
expectedValue: '2024-01-01T10:35:18',
},
].forEach(({ fieldName, expectedValue }) => {
it('renders every field as expected', () => {
Expand All @@ -172,12 +171,13 @@ describe('CourseActivity', () => {
.props()
.renderItem(assignmentStats, fieldName);

const itemWrapper = mount(item);

if (fieldName === 'last_activity') {
assert.equal(item, expectedValue);
assert.equal(itemWrapper.prop('date'), expectedValue);
return;
}

const itemWrapper = mount(item);
assert.equal(itemWrapper.text(), expectedValue);

if (fieldName === 'title') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ describe('OrganizationActivity', () => {
};

$imports.$mock(mockImportedComponents());
$imports.$restore({
// Do not mock FormattedDate, for consistency when checking
// rendered values in different columns
'./FormattedDate': true,
});
$imports.$mock({
'../../utils/api': {
useAPIFetch: fakeUseAPIFetch,
Expand Down Expand Up @@ -114,11 +119,12 @@ describe('OrganizationActivity', () => {

it('renders last launched date', () => {
const wrapper = createComponent();
const item = renderItem(wrapper, 'last_launched');
const { last_launched } = courseRow;
const item = renderItem(wrapper, 'last_launched');
const itemText = last_launched ? mount(item).text() : '';

assert.equal(
item,
itemText,
last_launched ? formatDateTime(new Date(last_launched)) : '',
);
});
Expand Down

0 comments on commit 9b4feee

Please sign in to comment.