Skip to content

Commit

Permalink
Merge pull request #7670 from jrjohnson/3594-course-year-report
Browse files Browse the repository at this point in the history
Add Some Reporting by Academic Year
  • Loading branch information
dartajax authored Feb 29, 2024
2 parents b653725 + 89a90f1 commit d5b27f2
Show file tree
Hide file tree
Showing 15 changed files with 353 additions and 27 deletions.
2 changes: 1 addition & 1 deletion packages/frontend/app/components/reports/new-subject.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<option value="" selected={{eq null this.prepositionalObject}}>
{{t "general.anything"}}
</option>
{{#each this.prepositionalObjectList as |o|}}
{{#each (sort-by "label" this.prepositionalObjectList) as |o|}}
<option
value={{o.value}}
selected={{eq o.value this.prepositionalObject}}
Expand Down
16 changes: 16 additions & 0 deletions packages/frontend/app/components/reports/new-subject.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import NewProgramYearComponent from './subject/new/program-year';
import NewSessionComponent from './subject/new/session';
import NewSessionTypeComponent from './subject/new/session-type';
import NewTermComponent from './subject/new/term';
import NewAcademicYearComponent from './subject/new/academic-year';

@validatable
export default class ReportsNewSubjectComponent extends Component {
Expand Down Expand Up @@ -173,6 +174,19 @@ export default class ReportsNewSubjectComponent extends Component {
label: this.intl.t('general.term'),
subjects: ['course', 'session', 'program', 'program year', 'session type'],
},
{
value: 'academic year',
label: this.intl.t('general.academicYear'),
subjects: [
'course',
'session',
'instructor',
'instructor group',
'competency',
'session type',
'term',
],
},
];

userModelData = new TrackedAsyncData(this.currentUser.getModel());
Expand Down Expand Up @@ -224,6 +238,8 @@ export default class ReportsNewSubjectComponent extends Component {
return ensureSafeComponent(NewSessionTypeComponent, this);
case 'term':
return ensureSafeComponent(NewTermComponent, this);
case 'academic year':
return ensureSafeComponent(NewAcademicYearComponent, this);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export default class ReportsSubjectResultsComponent extends Component {
get showAcademicYearFilter() {
return (
this.args.prepositionalObject !== 'course' &&
this.args.prepositionalObject !== 'academic year' &&
['course', 'session'].includes(this.args.subject)
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/app/components/reports/subject/course.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default class ReportsSubjectCourseComponent extends Component {
}

get showYear() {
return !this.args.year;
return !this.args.year && this.args.prepositionalObject !== 'academic year';
}

get filteredCourses() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,13 @@ export default class ReportsSubjectInstructorComponent extends Component {
}
if (prepositionalObject && prepositionalObjectTableRowId) {
let what = pluralize(camelize(prepositionalObject));
const specialInstructed = ['learningMaterials', 'sessionTypes', 'courses', 'sessions'];
const specialInstructed = [
'learningMaterials',
'sessionTypes',
'courses',
'sessions',
'academicYears',
];
if (specialInstructed.includes(what)) {
what = 'instructed' + capitalize(what);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<p data-test-reports-subject-new-academic-year>
<label for="new-term">
{{t "general.whichIs"}}
</label>
{{#if this.isLoaded}}
<select
id="new-academic-year"
data-test-prepositional-objects
{{on "change" (pick "target.value" @changeId)}}
{{did-insert (perform this.setInitialValue)}}
{{did-update (perform this.setInitialValue) @school}}
>
{{#each (sort-by "title" this.academicYears) as |year|}}
<option
selected={{eq year.id @currentId}}
value={{year.id}}
>
{{#if this.academicYearCrossesCalendarYearBoundaries}}
{{year.id}} - {{add year.id 1}}
{{else}}
{{year.id}}
{{/if}}
</option>
{{/each}}
</select>
{{else}}
<LoadingSpinner />
{{/if}}
</p>
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Component from '@glimmer/component';
import { TrackedAsyncData } from 'ember-async-data';
import { cached } from '@glimmer/tracking';
import { service } from '@ember/service';
import { task, timeout } from 'ember-concurrency';

export default class ReportsSubjectNewAcademicYearComponent extends Component {
@service store;
@service iliosConfig;

@cached
get data() {
return new TrackedAsyncData(this.store.findAll('academic-year'));
}

crossesBoundaryConfig = new TrackedAsyncData(
this.iliosConfig.itemFromConfig('academicYearCrossesCalendarYearBoundaries'),
);

@cached
get academicYearCrossesCalendarYearBoundaries() {
return this.crossesBoundaryConfig.isResolved ? this.crossesBoundaryConfig.value : false;
}

get academicYears() {
return this.data.value;
}

get isLoaded() {
return this.data.isResolved;
}

@task
*setInitialValue() {
yield timeout(1); //wait a moment so we can render before setting
const ids = this.academicYears.map(({ id }) => id);
if (ids.includes(this.args.currentId)) {
return;
}
if (!this.academicYears.length) {
this.args.changeId(null);
} else {
this.args.changeId(this.academicYears[0].id);
}
}
}
1 change: 1 addition & 0 deletions packages/frontend/app/services/reporting.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const objectTranslations = {
session: 'general.session',
school: 'general.school',
term: 'general.term',
'academic year': 'general.academicYear',
};

export default class ReportingService extends Service {
Expand Down
81 changes: 80 additions & 1 deletion packages/frontend/tests/acceptance/reports/subjects-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ module('Acceptance | Reports - Subject Reports', function (hooks) {
});

test('get all courses associated with mesh term #3419', async function (assert) {
assert.expect(14);
assert.expect(15);
await page.visit();
assert.strictEqual(page.root.list.table.reports.length, 2);
assert.strictEqual(
Expand Down Expand Up @@ -248,6 +248,7 @@ module('Acceptance | Reports - Subject Reports', function (hooks) {
subjectReportPage.report.title.text,
'All Courses for descriptor 0 in school 0',
);
assert.ok(subjectReportPage.report.academicYears.isVisible);
assert.strictEqual(subjectReportPage.report.results.length, 2);
assert.strictEqual(
subjectReportPage.report.results[0].text,
Expand Down Expand Up @@ -411,4 +412,82 @@ module('Acceptance | Reports - Subject Reports', function (hooks) {
'All Sessions for term 0 in school 0',
);
});

test('create new report for instructors by academic year #3594', async function (assert) {
assert.expect(14);
this.server.createList('user', 3);
await page.visit();
assert.strictEqual(page.root.list.table.reports.length, 2);
assert.ok(page.root.list.newReportLinkIsHidden);
await page.root.list.toggleNewSubjectReportForm();
await page.root.list.newSubject.schools.choose('1');
await page.root.list.newSubject.subjects.choose('instructor');
await page.root.list.newSubject.objects.choose('academic year');
await page.root.list.newSubject.save();
assert.notOk(page.root.list.newReportLinkIsHidden);
assert.strictEqual(page.root.list.table.reports.length, 3);
assert.strictEqual(
page.root.list.table.reports[0].title,
'All Instructors for 2015 - 2016 in school 0',
);
assert.strictEqual(page.root.list.newReportLink, 'All Instructors for 2015 - 2016 in school 0');

this.server.post('api/graphql', ({ db }, { requestBody }) => {
const { query } = JSON.parse(requestBody);

assert.strictEqual(
query,
'query { users(schools: [1], instructedAcademicYears: [2015]) { firstName,middleName,lastName,displayName } }',
);
return {
data: {
users: db.users.map(({ firstName, middleName, lastName, displayName }) => {
return { firstName, middleName, lastName, displayName };
}),
},
};
});
await page.root.list.table.reports[0].select();
assert.strictEqual(currentURL(), '/reports/subjects/3');
assert.strictEqual(
subjectReportPage.report.title.text,
'All Instructors for 2015 - 2016 in school 0',
);
assert.strictEqual(subjectReportPage.report.results.length, 4);
assert.strictEqual(subjectReportPage.report.results[0].text, '0 guy M. Mc0son');
assert.strictEqual(subjectReportPage.report.results[1].text, '1 guy M. Mc1son');
assert.strictEqual(subjectReportPage.report.results[2].text, '2 guy M. Mc2son');
assert.strictEqual(subjectReportPage.report.results[3].text, '3 guy M. Mc3son');
});

test('courses by academic year hides year', async function (assert) {
assert.expect(5);
await page.visit();
await page.root.list.toggleNewSubjectReportForm();
await page.root.list.newSubject.schools.choose('');
await page.root.list.newSubject.subjects.choose('course');
await page.root.list.newSubject.objects.choose('academic year');
await page.root.list.newSubject.prepositionalObjects.choose('2015');
await page.root.list.newSubject.save();
this.server.post('api/graphql', ({ db }, { requestBody }) => {
const { query } = JSON.parse(requestBody);
assert.strictEqual(
query,
'query { courses(academicYears: [2015]) { id, title, year, externalId } }',
);
const coursesIn2015 = db.courses.filter(({ year }) => year === 2015);
return {
data: {
courses: coursesIn2015.map(({ id, title, year, externalId }) => {
return { id, title, year, externalId };
}),
},
};
});
await page.root.list.table.reports[0].select();
assert.strictEqual(currentURL(), '/reports/subjects/3');
assert.notOk(subjectReportPage.report.academicYears.isVisible);
assert.strictEqual(subjectReportPage.report.results.length, 1);
assert.strictEqual(subjectReportPage.report.results[0].text, 'course 0 (Theoretical Phys Ed)');
});
});
Loading

0 comments on commit d5b27f2

Please sign in to comment.