diff --git a/backend/src/controllers/person.controller.ts b/backend/src/controllers/person.controller.ts index 03929d63..67184196 100644 --- a/backend/src/controllers/person.controller.ts +++ b/backend/src/controllers/person.controller.ts @@ -131,7 +131,6 @@ export const getPersonsByCompany = async ( res: Response, next: NextFunction, ): Promise => { - logger.info('GET /persons/companies/:id request from frontend'); const authId = req.headers.authorization?.['user_id']; @@ -151,7 +150,7 @@ export const getPersonsByCompany = async ( async (personsId: any) => (await getPersonDetails(personsId)), )); } - + if (!company) { res.status(httpStatus.NOT_FOUND).end(); } else { @@ -163,6 +162,40 @@ export const getPersonsByCompany = async ( } }; +export const getPersonsByLabel = async ( + req: Request, + res: Response, + next: NextFunction, +): Promise => { + logger.info('GET /persons/label request from frontend'); + + const authId = req.headers.authorization?.['user_id']; + const user = await userService.getUserByAuthId(authId); + const reqLabel = req.query.label?.toString(); + + try { + if (!user) { + res.status(httpStatus.UNAUTHORIZED).end(); + } else { + // get all the persons for this user + let people: any = await Promise.all(user.persons.map( + async (personsId: any) => (await personService.getPersonWithId(personsId)), + )); + + // filter, getting all people that have this label ( case insensitive ) + let peopleWithLabel: any = people.filter((person) => person?.labels.some((label) => label.toLowerCase() === reqLabel?.toLowerCase())); + + if (!peopleWithLabel) { + res.status(httpStatus.NOT_FOUND).end(); + } else { + res.status(httpStatus.OK).json(peopleWithLabel).end(); + } + } + } catch (e) { + next(e); + } +}; + export const deletePersons = async ( req: Request, res: Response, diff --git a/backend/src/models/person.model.ts b/backend/src/models/person.model.ts index 8f9e6f17..bfd6f527 100644 --- a/backend/src/models/person.model.ts +++ b/backend/src/models/person.model.ts @@ -14,6 +14,7 @@ export interface PersonModel { first_met: Date, how_we_met: string, interests: string[], + labels: string[], organisation: string, social_media: Map, image: Buffer, @@ -32,6 +33,7 @@ const schema = new Schema({ first_met: { type: Date, required: false }, how_we_met: { type: String, required: false }, interests: { type: [String], required: false }, + labels: { type: [String], required: false }, organisation: { type: String, required: false }, social_media: { type: Map, of: String, required: false }, image: { type: Buffer, required: false }, diff --git a/backend/src/routes/__test__/company.route.test.ts b/backend/src/routes/__test__/company.route.test.ts index 33ffe942..019c361b 100644 --- a/backend/src/routes/__test__/company.route.test.ts +++ b/backend/src/routes/__test__/company.route.test.ts @@ -47,6 +47,7 @@ const person1Data: PersonModel = { first_name: 'Ping', last_name: 'Pong', interests: ['video games', 'hockey'], + labels: ['Devop'], organisation: 'helloc', time_updated: new Date('2022-01-01'), importance_level: Importance.Very_Important, @@ -65,6 +66,7 @@ const person2Data: PersonModel = { first_name: 'Adam', last_name: 'Bong', interests: ['badminton', 'golf'], + labels: ['Devop'], organisation: 'helloc', time_updated: new Date('2022-02-23'), importance_level: Importance.Should_Remember, diff --git a/backend/src/routes/__test__/encounter.route.test.ts b/backend/src/routes/__test__/encounter.route.test.ts index 9e731ca2..faacefc0 100644 --- a/backend/src/routes/__test__/encounter.route.test.ts +++ b/backend/src/routes/__test__/encounter.route.test.ts @@ -48,6 +48,7 @@ const person1Data: PersonModel = { first_name: 'Ping', last_name: 'Pong', interests: ['video games', 'hockey'], + labels: ['Devop'], organisation: 'helloc', time_updated: new Date('2022-01-01'), importance_level: Importance.Very_Important, @@ -66,6 +67,7 @@ const person2Data: PersonModel = { first_name: 'Adam', last_name: 'Bong', interests: ['badminton', 'golf'], + labels: ['Devop'], organisation: 'helloc', time_updated: new Date('2022-02-23'), importance_level: Importance.Should_Remember, diff --git a/backend/src/routes/__test__/person.route.test.ts b/backend/src/routes/__test__/person.route.test.ts index 7f20c48c..75dff812 100644 --- a/backend/src/routes/__test__/person.route.test.ts +++ b/backend/src/routes/__test__/person.route.test.ts @@ -38,6 +38,7 @@ const person1Data: PersonModel = { first_name: 'Ping', last_name: 'Pong', interests: ['video games', 'hockey'], + labels: ['Devop'], organisation: 'helloc', time_updated: new Date('2022-01-01'), importance_level: Importance.Very_Important, @@ -56,6 +57,7 @@ const person2Data: PersonModel = { first_name: 'Adam', last_name: 'Bong', interests: ['badminton', 'golf'], + labels: ['Devop'], organisation: 'helloc', time_updated: new Date('2022-02-23'), importance_level: Importance.Should_Remember, @@ -74,6 +76,7 @@ const person3Data: PersonModel = { first_name: 'Billy', last_name: 'John', interests: ['surfing', 'cooking'], + labels: ['Devop'], organisation: 'an organisation', time_updated: new Date('2022-02-23'), importance_level: Importance.Casual_Contact, @@ -92,6 +95,7 @@ const person4Data: PersonModel = { first_name: 'Kelvin', last_name: 'Kong', interests: ['Studying', 'Winning'], + labels: ['Devop'], organisation: 'Winnie', time_updated: new Date('2022-01-01'), importance_level: Importance.Very_Important, @@ -118,6 +122,7 @@ const userData: UserModel = { const person5Data = { last_name: 'John', interests: ['surfing', 'cooking'], + labels: ['Devop'], organisation: 'an organisation', time_updated: new Date('2022-02-23'), importance_level: Importance.Casual_Contact, @@ -136,6 +141,7 @@ const person6Data = { first_name: 'Billy', last_name: 'John', interests: ['surfing', 'cooking'], + labels: ['Devop'], organisation: 'an organisation', how_we_met: 'At the park', birthday: new Date('2001-07-16'), @@ -172,6 +178,7 @@ const person7Data = { first_name: 'Yesterday', last_name: 'Birthday', interests: ['surfing', 'cooking'], + labels: [], organisation: 'an organisation', how_we_met: 'At the park', birthday: new Date(new Date().getTime() - 24 * 60 * 60 * 1000), @@ -187,6 +194,7 @@ const person8Data = { first_name: 'Tomorrow', last_name: 'Birthday', interests: ['surfing', 'cooking'], + labels: ['Devop'], organisation: 'an organisation', how_we_met: 'At the park', birthday: new Date(new Date().getTime() + 24 * 60 * 60 * 1000), @@ -202,6 +210,7 @@ const person9Data = { first_name: 'NextMonth', last_name: 'Birthday', interests: ['surfing', 'cooking'], + labels: ['Backend'], organisation: 'an organisation', how_we_met: 'At the park', birthday: new Date(new Date().getTime() + 24 * 60 * 60 * 1000 * 30), @@ -1029,6 +1038,45 @@ describe('GET /birthdays', () => { .set('Accept', 'application/json') .set('Authorization', token); + expect(people).toEqual({}); + }); +}); + +describe('GET /label', () => { + + async function populateDbWithUsersPersons() { + const person1 = new Person(person7Data); + const person2 = new Person(person8Data); + const person3 = new Person(person9Data); + + await person1.save(); + await person2.save(); + await person3.save(); + + userData.auth_id = await testUtils.getAuthIdFromToken(token); + const user = new User(userData); + user.persons.push(person1._id, person2._id, person3._id); + await user.save(); + + const storedPersonIds = [person1._id, person2._id, person3._id]; + + return storedPersonIds; + } + + it('Returns correct number of entries', async () => { + await populateDbWithUsersPersons(); + const { body: people } = await supertest(app).get('/api/persons/label?label=Devop') + .set('Accept', 'application/json') + .set('Authorization', token); + + expect(people.length).toEqual(1); + }); + + it('Empty array is returned when there is none with the label', async () => { + const { body: people } = await supertest(app).get('/api/persons/label?label=frontend') + .set('Accept', 'application/json') + .set('Authorization', token); + expect(people).toEqual({}); }); }); \ No newline at end of file diff --git a/backend/src/routes/__test__/user.route.test.ts b/backend/src/routes/__test__/user.route.test.ts index 727a1c6b..39b26c9c 100644 --- a/backend/src/routes/__test__/user.route.test.ts +++ b/backend/src/routes/__test__/user.route.test.ts @@ -60,6 +60,7 @@ const person1Data: PersonModel = { first_name: "Ray", last_name: "Ping", interests: ["video games", "hockey"], + labels: ['Devop'], organisation: "helloc", time_updated: new Date("2022-01-01"), importance_level: null as any, @@ -78,6 +79,7 @@ const person2Data: PersonModel = { first_name: "Adam", last_name: "Bong", interests: ["badminton", "golf"], + labels: ['Devop'], organisation: "helloc", time_updated: new Date("2022-02-23"), importance_level: Importance.Should_Remember, diff --git a/backend/src/routes/person.route.ts b/backend/src/routes/person.route.ts index e191654a..1cc9244b 100644 --- a/backend/src/routes/person.route.ts +++ b/backend/src/routes/person.route.ts @@ -3,12 +3,13 @@ */ import { Router } from 'express'; import { - createPerson, getAllPeople, getPersonWithId, updatePersonWithId, deletePersons, getPersonsByCompany, + createPerson, getAllPeople, getPersonWithId, updatePersonWithId, deletePersons, getPersonsByCompany, getPersonsByLabel, } from '../controllers/person.controller'; const routes = Router(); routes.post('/', createPerson) + .get('/label', getPersonsByLabel) .get('/:id', getPersonWithId) .get('/', getAllPeople) .get('/companies/:id', getPersonsByCompany) diff --git a/backend/src/services/__test__/company.service.unit.test.ts b/backend/src/services/__test__/company.service.unit.test.ts index 6b15a069..fbe4f274 100644 --- a/backend/src/services/__test__/company.service.unit.test.ts +++ b/backend/src/services/__test__/company.service.unit.test.ts @@ -19,6 +19,7 @@ const personOne: PersonModel = { first_met: new Date('2012-12-21'), how_we_met: "Life", interests: ['things'], + labels: ['Devop'], organisation: "World", social_media: null as any, image: null as any, diff --git a/backend/src/services/__test__/encounter.service.unit.test.ts b/backend/src/services/__test__/encounter.service.unit.test.ts index 87996f16..21b5744f 100644 --- a/backend/src/services/__test__/encounter.service.unit.test.ts +++ b/backend/src/services/__test__/encounter.service.unit.test.ts @@ -14,6 +14,7 @@ const person1Data: PersonModel = { first_name: 'Ping', last_name: 'Pong', interests: ['video games', 'hockey'], + labels: ['Devop'], organisation: 'helloc', time_updated: new Date('2022-01-01'), importance_level: Importance.Very_Important, diff --git a/backend/src/services/__test__/person.service.unit.test.ts b/backend/src/services/__test__/person.service.unit.test.ts index 3759ea6c..5d894fc6 100644 --- a/backend/src/services/__test__/person.service.unit.test.ts +++ b/backend/src/services/__test__/person.service.unit.test.ts @@ -13,6 +13,7 @@ const person1Data:PersonModel = { first_name: 'testlname', last_name: 'testllastName', interests: ['a', 'b'], + labels: ['Devop'], organisation: 'testorg', time_updated: new Date('2022-01-01'), importance_level: Importance.Very_Important, @@ -31,6 +32,7 @@ const person1Data:PersonModel = { first_name: 'test2name', last_name: 'test2lastName', interests: ['c', 'd'], + labels: ['Devop'], organisation: 'anotherOrg', time_updated: new Date('2022-01-01'), importance_level: Importance.Should_Remember, @@ -49,6 +51,7 @@ const person1Data:PersonModel = { first_name: 'test3name', last_name: 'test3lastName', interests: ['c', 'd'], + labels: ['Devop'], organisation: 'anotherOrg', time_updated: new Date('2022-01-01'), importance_level: Importance.Casual_Contact, @@ -67,6 +70,7 @@ const person1Data:PersonModel = { first_name: null as any, last_name: 'testllastName', interests: ['a', 'b'], + labels: ['Devop'], organisation: 'testorg', time_updated: new Date('2022-01-01'), importance_level: Importance.Very_Important, @@ -85,6 +89,7 @@ const person1Data:PersonModel = { first_name: 'testfirstname', last_name: 'testllastName', interests: ['a', 'b'], + labels: ['Devop'], organisation: 'testorg', time_updated: null as any, importance_level: Importance.Casual_Contact, diff --git a/forgettable-frontend/src/components/PersonCard/PersonCard.js b/forgettable-frontend/src/components/PersonCard/PersonCard.js index e5700552..0701b379 100644 --- a/forgettable-frontend/src/components/PersonCard/PersonCard.js +++ b/forgettable-frontend/src/components/PersonCard/PersonCard.js @@ -5,6 +5,8 @@ import IconButton from '@mui/material/IconButton'; import Menu from '@mui/material/Menu'; import MenuItem from '@mui/material/MenuItem'; import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; +import Chip from '@mui/material/Chip'; +import Box from '@mui/material/Box'; import {convertSocialMediaToIcon} from '../../functions/socialMediaIconConverter'; import PropTypes from 'prop-types'; import {getFirstMetTimeString, getLongDateStringWithSlashes} from '../../functions/dateFormatter'; @@ -133,6 +135,16 @@ const PersonCard = (props) => { )} + {props.label && +
+ + {props.labels.map((label) => { + return ( + + ); + })} + +
}

{ })} :}

+

+ {'Labels: '} + {props.labels && props.labels.length > 0 ? + + {props.labels.join(', ')} + : + } +

{props.staticDrawer &&

+

+ Labels: + +

diff --git a/forgettable-frontend/src/pages/PersonPage/PersonPage.js b/forgettable-frontend/src/pages/PersonPage/PersonPage.js index d56e570f..c548765d 100644 --- a/forgettable-frontend/src/pages/PersonPage/PersonPage.js +++ b/forgettable-frontend/src/pages/PersonPage/PersonPage.js @@ -142,6 +142,7 @@ const PersonPage = (props) => { socialMedia={person.socialMedia} data-testid="drawer-component" onEdit={() => navigate(`/person/${id}/edit`)} + labels={person.labels} />
diff --git a/forgettable-frontend/src/pages/PersonsListPage/PersonsListPage.js b/forgettable-frontend/src/pages/PersonsListPage/PersonsListPage.js index 53ae9898..d3518b7b 100644 --- a/forgettable-frontend/src/pages/PersonsListPage/PersonsListPage.js +++ b/forgettable-frontend/src/pages/PersonsListPage/PersonsListPage.js @@ -147,6 +147,7 @@ export default function PersonsListPage(props) { firstMet={selectedInfo.firstMet} location={selectedInfo.location} interests={selectedInfo.interests} + labels={selectedInfo.labels} /> } onDeletePersonCardClicked(e, person._id)} firstMet= {person.first_met} image={person.image} + labels={person.labels} />
); diff --git a/forgettable-frontend/src/pages/edit/EditPerson.js b/forgettable-frontend/src/pages/edit/EditPerson.js index d16f162a..0e80b658 100644 --- a/forgettable-frontend/src/pages/edit/EditPerson.js +++ b/forgettable-frontend/src/pages/edit/EditPerson.js @@ -42,6 +42,7 @@ export default function EditPerson() { image: '', encounters: [], time_updated: '', + labels: [], }); (!create) && (useEffect(async () => { @@ -60,6 +61,7 @@ export default function EditPerson() { img: result.image, encounters: result.encounters || [], time_updated: result.time_updated, + labels: result.labels || [], }); }, [id])); @@ -160,6 +162,7 @@ export default function EditPerson() { const data = { ...formData, interests: formData.interests.split(/[-_,\s.|]+/), + labels: formData.labels.split(/[-_,\s.|]+/), image: profilePic, social_media: Object.fromEntries(socialMedias), }; @@ -217,6 +220,7 @@ export default function EditPerson() { +
{handleDisplaySocialMedia()}