Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4cd9e7b
add isTopForSubject property in LibAppsDataFilter.filterBySubject()
kenirwin Jun 3, 2025
ed2d604
don't report isTopForSubject if not requested in LibAppsDataFilter.fi…
kenirwin Jun 4, 2025
d13081e
UserLibGuidesData -- don't do it all upon initialization; wait for th…
kenirwin Jun 4, 2025
080f1aa
UserLibGuidesData.test passes but needs reorg
kenirwin Jun 6, 2025
fec722d
UserLibGuidesData.test restructured to avoid mutating data during tests
kenirwin Jun 6, 2025
574984a
UserLibGuidesData.getSubjectFiles uses separateTopAndFavDatabases (bu…
kenirwin Jun 6, 2025
a3386eb
first stab at displaying top and rest of db in view
kenirwin Jun 6, 2025
64ac2be
update top-db accordion ids in view
kenirwin Jun 9, 2025
2c7e382
add databases-other view, with database-item
kenirwin Jun 9, 2025
96068b0
use databases-other in subject-info view
kenirwin Jun 9, 2025
90b710c
use database-item in databases-top view (but mysteriously top accordi…
kenirwin Jun 9, 2025
e00ad90
deconflict collapseCirc with database accordion collapse
kenirwin Jun 9, 2025
7670228
keep top db open when other dbs are opened; no autocollapse
kenirwin Jun 9, 2025
eab5318
top/other databases accordion full width of card
kenirwin Jun 9, 2025
a89c16e
updated bootstrap and sass to @latest
kenirwin Jun 10, 2025
213f8df
tidy formatting of databases-top view
kenirwin Jun 10, 2025
37531c1
apply color to "additional" databases link
kenirwin Jun 10, 2025
6a6fbc6
styling top/other database list headers
kenirwin Jun 10, 2025
22e7036
hover color on other databases button
kenirwin Jun 10, 2025
9eed69e
comment in main.csss for new database section
kenirwin Jun 10, 2025
c35f448
take spacebar characters out of html id params on multi-word subjects…
kenirwin Jun 11, 2025
2cdfd79
minor layout tweaks on top/other databases -- matching each other
kenirwin Jun 11, 2025
17988ea
replaceAll spaces with underscores in subjectName (not replace just o…
kenirwin Jun 12, 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: 3 additions & 1 deletion controllers/UserDataController.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,12 @@ module.exports = class UserDataController {
let subjectListWithLiaisons = liaisonList.concat(subjectList);
let uniqueSubjectList = _.uniq(subjectListWithLiaisons);

let userLibGuides = new UserLibGuidesData(
let userLibGuidesObject = new UserLibGuidesData(
uniqueSubjectList,
this.user.favorites
);
userLibGuidesObject.getSubjectFiles();
let userLibGuides = userLibGuidesObject.subjectData;

let finishedUserData = {
person: this.userLoginInfo,
Expand Down
35 changes: 24 additions & 11 deletions models/libGuides/LibAppsDataFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,28 @@ module.exports = class LibAppsDataFilter {
});
}

filterBySubject(resourceList, subject, topOnly = false) {
filterBySubject(resourceList, subject, reportTopForSubject = false) {
var results = [];
resourceList.forEach(function (item) {
// if there are subjects defined for the item,
// find the one that matches the requested subject
// if there are no subjects, skip the item
if (item.subjects !== undefined) {
if (topOnly) {
var temp = item.subjects.filter(
(s) => s.name === subject && s.featured === 1
);
} else {
var temp = item.subjects.filter((s) => s.name === subject);
}
// determine if item matches the requested subject
var itemMatchingSubject = item.subjects.filter(
(s) => s.name === subject
);

// if the item has subjects and matches the requested subject
// add it to the results
// if requested, also check to see if it a featured/top item for that subject
if (item.subjects !== undefined) {
if (temp.length > 0) {
if (itemMatchingSubject.length > 0) {
if (reportTopForSubject) {
let isTopForSubject =
itemMatchingSubject[0].featured === 1 ? true : false;
item.isTopForSubject = isTopForSubject;
}
results.push(item);
}
}
Expand All @@ -108,7 +117,7 @@ module.exports = class LibAppsDataFilter {
return matches;
}

getBestBySubject(resourceList, subjects, topOnly = false) {
getBestBySubject(resourceList, subjects, reportTopForSubject = false) {
// expects resourceList to be an object listing database, librarians, or libguides
// expect subjects to be an array of subject areas in order of best fit, e.g.:
// subjects = ['English','Languages']
Expand All @@ -121,7 +130,11 @@ module.exports = class LibAppsDataFilter {
for (var i = 0; i < subjects.length; i++) {
if (found === false) {
// console.log('checking', subjects[i])
let response = this.filterBySubject(resourceList, subjects[i], topOnly);
let response = this.filterBySubject(
resourceList,
subjects[i],
reportTopForSubject
);
// console.log(response)
if (response.length > 0) {
var done = response;
Expand Down
34 changes: 28 additions & 6 deletions models/libGuides/test/LibAppsDataFilter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,34 @@ describe('LibAppsDataFilter: databases', () => {
});

describe('LibAppsDataFilter: filterBySubject: Databases', () => {
english = obj.filterBySubject(databases, 'English'); // 5
topEnglish = obj.filterBySubject(databases, 'English', true); // 1
bws = obj.filterBySubject(databases, 'Black World Studies'); // 2
english = obj.filterBySubject(databases, 'English', true); // 5
bws = obj.filterBySubject(databases, 'Black World Studies', true); // 2

// re-write these tests for the top/nonTop divide

it('should find five English databases', () => {
expect(english.length).toBe(5);
});
it('should find two BWS databases', () => {
expect(bws.length).toBe(2);
});
it('should fine one top English database', () => {
expect(topEnglish.length).toBe(1);
expect(topEnglish[0].name).toBe('19th Century Index');
it('should find one top English database and 4 non-top', () => {
expect(english[0].name).toBe('19th Century Index');
expect(english[0]).toHaveProperty('isTopForSubject');
expect(english[0].isTopForSubject).toBe(true);
// expect(english[1]).toHaveProperty('isTopForSubject');
// expect(english[1].isTopForSubject).toBe(false);
// expect(english[2]).toHaveProperty('isTopForSubject');
// expect(english[2].isTopForSubject).toBe(false);
// expect(english[3]).toHaveProperty('isTopForSubject');
// expect(english[3].isTopForSubject).toBe(false);
// expect(english[4]).toHaveProperty('isTopForSubject');
// expect(english[4].isTopForSubject).toBe(false);
});
it('should find no top BWS databases and two non-top', () => {
expect(bws[0]).toHaveProperty('isTopForSubject');
expect(bws[0].isTopForSubject).toBe(false);
expect(bws[1].isTopForSubject).toBe(false);
});
});

Expand Down Expand Up @@ -68,6 +83,10 @@ describe('LibAppsDataFilter: filterBySubject: librarians', () => {
expect(bizLib.length).toBe(1);
expect(bizLib[0].last_name).toBe('Janeway');
});
it('should not have isTopForSubject property', () => {
expect(bizLib[0]).not.toHaveProperty('isTopForSubject');
expect(langLib[0]).not.toHaveProperty('isTopForSubject');
});
});

describe('LibAppsDataFilter: guides', () => {
Expand All @@ -81,6 +100,9 @@ describe('LibAppsDataFilter: guides', () => {
it('should find nine guides', () => {
expect(guides.length).toBe(9);
});
it('should not have isTopForSubject property', () => {
expect(guides[0]).not.toHaveProperty('isTopForSubject');
});
});

describe('LibAppsDataFilter: removeUnpublishedGuides', () => {
Expand Down
24 changes: 20 additions & 4 deletions models/userLoginData/UserLibGuidesData.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ module.exports = class UserLibGuidesData {
this.subjectCachePath = subjectCachePath;
this.customPath = customPath;
this.subjectData = [];
this.getSubjectFiles();
return this.subjectData;
// this.getSubjectFiles();
// return this.subjectData;
}

getSubjectFiles() {
Expand All @@ -35,10 +35,11 @@ module.exports = class UserLibGuidesData {
}
let fileContents = this.getFileContents(filename);
fileContents = this.markFavoriteGuidesAndDatabases(fileContents);
fileContents = this.separateTopAndFavDatabases(fileContents);
this.subjectData.push({
name: subject,
resources: fileContents,
kenTest: true,
// kenTest: true,
});
});
}
Expand Down Expand Up @@ -94,7 +95,7 @@ module.exports = class UserLibGuidesData {
contents.databases !== undefined
) {
contents.databases.forEach((database) => {
database.testString = 'bogusKen';
// database.testString = 'bogusKen';
database.favorite =
this.favorites.favoriteDatabases.includes(database.id) ||
this.favorites.favoriteDatabases.includes(database.id.toString());
Expand All @@ -103,4 +104,19 @@ module.exports = class UserLibGuidesData {

return contents;
}

separateTopAndFavDatabases(contents) {
const databases = contents.databases;
let aboveFold = databases.filter((db) => db.isTopForSubject || db.favorite);
let belowFold = databases.filter(
(db) => !db.isTopForSubject && !db.favorite
);
contents.databases = {
aboveFold: aboveFold,
belowFold: belowFold,
isArray: Array.isArray(databases),
length: databases.length,
};
return contents;
}
};
114 changes: 114 additions & 0 deletions models/userLoginData/test/UserLibGuidesData.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const spanish = require('./sample-data/subjectsAfterFavsAdded/Spanish.json');
const german = require('./sample-data/subjectsAfterFavsAdded/German.json');

const UserLibGuidesData = require('../UserLibGuidesData');

describe('UserLibGuidesData: separateTopAndFavDatabases', () => {
describe('separateTopAndFavDatabases: Spanish', () => {
const obj = new UserLibGuidesData();

it('should get a response with databases: [aboveFold, belowFold]', () => {
// Note: `structuredClone` is used to avoid mutating the original data.
const result = obj.separateTopAndFavDatabases(structuredClone(spanish));
expect(result).toHaveProperty('databases');
expect(result.databases).toHaveProperty('aboveFold');
expect(result.databases).toHaveProperty('belowFold');
});

it('should get 5 above/3 below', () => {
const result = obj.separateTopAndFavDatabases(structuredClone(spanish));
expect(Array.isArray(result.databases.aboveFold)).toBe(true);
expect(Array.isArray(result.databases.belowFold)).toBe(true);
expect(result.databases.aboveFold.length).toBe(5);
expect(result.databases.belowFold.length).toBe(3);
});

it('should have expected databases in aboveFold and belowFold for Spanish', () => {
const result = obj.separateTopAndFavDatabases(structuredClone(spanish));
let expectedAboveFold = [
'Clase and Periodica',
'Film and Television Literature Index with Full Text',
'Fuente Academica',
'Linguistics & Language Behavior Abstracts',
'MLA International Bibliography',
];
let expectedBelowFold = [
'Ethnic NewsWatch',
'Latin American Women Writers',
'Latino Literature',
];
expect(
expectedAboveFold.includes(result.databases.aboveFold[0].name)
).toBe(true);
expect(
expectedAboveFold.includes(result.databases.aboveFold[1].name)
).toBe(true);
expect(
expectedAboveFold.includes(result.databases.aboveFold[2].name)
).toBe(true);
expect(
expectedAboveFold.includes(result.databases.aboveFold[3].name)
).toBe(true);
expect(
expectedAboveFold.includes(result.databases.aboveFold[4].name)
).toBe(true);
expect(
expectedBelowFold.includes(result.databases.belowFold[0].name)
).toBe(true);
expect(
expectedBelowFold.includes(result.databases.belowFold[1].name)
).toBe(true);
expect(
expectedBelowFold.includes(result.databases.belowFold[2].name)
).toBe(true);
});
});

describe('separateTopAndFavDatabases: German', () => {
const obj = new UserLibGuidesData();

it('should get a response with databases: [aboveFold, belowFold]', () => {
const result = obj.separateTopAndFavDatabases(structuredClone(german));
expect(result).toHaveProperty('databases');
expect(result.databases).toHaveProperty('aboveFold');
expect(result.databases).toHaveProperty('belowFold');
});

it('should get 5 above/3 below', () => {
const result = obj.separateTopAndFavDatabases(structuredClone(german));
expect(Array.isArray(result.databases.aboveFold)).toBe(true);
expect(Array.isArray(result.databases.belowFold)).toBe(true);
expect(result.databases.aboveFold.length).toBe(3);
expect(result.databases.belowFold.length).toBe(2);
});

it('should have expected databases in aboveFold and belowFold for German', () => {
const result = obj.separateTopAndFavDatabases(structuredClone(german));

let expectedAboveFold = [
'Film and Television Literature Index with Full Text',
'MLA International Bibliography',
'Linguistics & Language Behavior Abstracts',
];
let expectedBelowFold = [
'German Life and Letters',
'Oxford Bibliographies Online: Literary and Critical Theory',
];
expect(
expectedAboveFold.includes(result.databases.aboveFold[0].name)
).toBe(true);
expect(
expectedAboveFold.includes(result.databases.aboveFold[1].name)
).toBe(true);
expect(
expectedAboveFold.includes(result.databases.aboveFold[2].name)
).toBe(true);
expect(
expectedBelowFold.includes(result.databases.belowFold[0].name)
).toBe(true);
expect(
expectedBelowFold.includes(result.databases.belowFold[1].name)
).toBe(true);
});
});
});
Loading