-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
collection backend #944
collection backend #944
Conversation
[diff-counting] Significant lines: 615. |
Visit the preview URL for this PR (updated for commit 726dbe3): https://cornelldti-courseplan-dev--pr944-hannah-collection-b-y8xwrfff.web.app (expires Wed, 27 Nov 2024 03:25:37 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 6d4e0437c4559ed895272bbd63991394f1e0e933 |
- can save a course when press 'done' - course is saved to an empty collection - add functions for add & edit collection
- can save one course to multiple collections w/ checkbox - saved course will be removed from semester view and from fullfilled requirements - pop up notification
Checkbox Style | ||
Need a collections variable in firestore | ||
--> | ||
<div v-for="collection in collections" :key="collection"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We would guarantee that collection names are unique then — not tracking internally with IDs and whatnot? (Is a reasonable assumption to make.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking the same...I think this is a reasonable thing to assume for now.
:value="collection" | ||
v-model="checkedCollections" | ||
/> | ||
<label for="collection">{{ collection }}</label> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heads up, I noticed when testing that this label will always only toggle the very first collection when clicked. So e.g. the label for the fourth collection, when clicked, would toggle the checkmark for first collection.
I suspect that this is due to the non-uniqueness for id
and for
— could perhaps combine this with the indices or use "collections"
literal value?
Additionally, would it be possible to have a little margin between the checkbox and the label? I appreciate that this is a draft PR though 👍 .
}, | ||
data() { | ||
return { | ||
checkedCollections: [] as string[], // New data property to manage checked state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good work with the type safety here~
src/user-data.d.ts
Outdated
@@ -36,6 +36,7 @@ type FirestoreSemester = { | |||
}; | |||
|
|||
type FirestoreSemestersData = { | |||
// readonly collections: readonly Collection[]; Note: Not sure where to store collections |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm yes, this would be tricky. Happy to discuss with you and Nidhi sometime at dev sesh or work sesh!
src/store.ts
Outdated
@@ -326,6 +331,7 @@ export const initializeFirestoreListeners = (onLoad: () => void): (() => void) = | |||
const plan = getFirstPlan(data); | |||
store.commit('setPlans', data.plans); | |||
store.commit('setCurrentPlan', plan); | |||
// store.commit('setCollections', data.collections); Note: toggle this on and off to save collections progress after refresh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for haring this here and in the main PR information section. Tiny quality of life improvement could be to add another //
before the Note:
so you don't have to add that when toggling, but really just nitpicking.
| 'delete-course' // User deletes a course | ||
| 'delete-course-collection' // User deletes a course from a collection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice stuff, thank you for commenting all of these so semantically!
}, | ||
collections() { | ||
const collections = store.state.collections.map(collection => collection.name); | ||
return collections.length === 0 ? ['No collections added yet'] : collections; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clean way of doing things, nice approach! Took a minute to understand so perhaps a one-line piece of documentation could be useful, but definitely the most straightforward approach — doesn't really on any extra attributes or anything.
}, | ||
placeholder_name() { | ||
const oldcollections = store.state.collections.map(collection => collection.name); | ||
let newCollectionNum = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we store this in the state somehow? Iterating through oldcollections
like this is probably discouraged by eslint
for a reason. I know it goes counter to my advice from earlier, but in this case I feel like it would be reasonable to store the latest collection number.
Though that said, if this is just a placeholder route and a user would be forced to enter a name or something, then can leave as be (again, I appreciate that this is still a draft-level PR).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that storing this in state somehow would be better... also (for a very weird niche case that would be kind of annoying) if a renamed collection was named Collection 4 even if the collection was the second collection added, then the newCollectionNum wouldn't be updated correctly
if (toEdit !== undefined) { | ||
editCollection(oldname, updater); | ||
} | ||
this.confirmationText = `${oldname} has been renamed to ${name}!`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could force capitalization of the first letter here for UI purposes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For 'oldname'? Maybe we can ask design, but I'd think that we would have that be the exact same as the original name
year: number, | ||
season: FirestoreSemesterSeason, | ||
newCourse: FirestoreSemesterCourse, | ||
collectionIDs: string[], // Array of collection IDs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather redundant to have this comment~
}) | ||
); | ||
|
||
deleteCourseFromSemester(plan, year, season, newCourse.uniqueID); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be curious about why we are necessarily removing something from a collection when we add from the dashboard main area, feels a bit counterintuitive. First time I tried it was annoyed that I lost the course and had to go remember what it was and find it.
Not an implementation question, more system design, would be interested to hear why this approach was taken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work Hannah, great work on the draft PR. Added in some general comments and suggestions. I know that this is still a draft PR, so they are not definitive but hopefully helpful a bit at least — if you have any questions let me know.
My main issue / concern would be with clicking the labels and having those being incorrectly synced to the corresponding checkboxes.
- finished scrollable checkbox frontend - fixed the bug for selecting a singular checkbox - believed its stored in firestore when added to collection - renamed collection to savedCourses for firesetore clarity
- saveCourseModal allow user to name their new collections - moved scss into a separate file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for all of your hard work on this Hannah! looking forward to seeing how this aligns with the frontend :)
src/components/Course/Course.vue
Outdated
const course = { ...this.courseObj }; | ||
this.$emit('save-course', course, collections); | ||
}, | ||
/* only to rename the collection */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for adding these comments + details! your code is super clear - the add collection vs edit collection vs save course is very clearly divided. i know you're working on the merge right now but that should hopefully be pretty straightforward with your you divided all of the logic
}, | ||
data() { | ||
return { | ||
checkedCollections: [] as string[], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super nit-picky, could add a comment here on what checkedCollections means just for clarification
}, | ||
placeholder_name() { | ||
const oldcollections = store.state.collections.map(collection => collection.name); | ||
let newCollectionNum = 1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that storing this in state somehow would be better... also (for a very weird niche case that would be kind of annoying) if a renamed collection was named Collection 4 even if the collection was the second collection added, then the newCollectionNum wouldn't be updated correctly
if (toEdit !== undefined) { | ||
editCollection(oldname, updater); | ||
} | ||
this.confirmationText = `${oldname} has been renamed to ${name}!`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For 'oldname'? Maybe we can ask design, but I'd think that we would have that be the exact same as the original name
@@ -326,17 +332,21 @@ export const initializeFirestoreListeners = (onLoad: () => void): (() => void) = | |||
const plan = getFirstPlan(data); | |||
store.commit('setPlans', data.plans); | |||
store.commit('setCurrentPlan', plan); | |||
store.commit('setSavedCourses', data.savedCourses); // Note: toggle this on and off to save collections progress after refresh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the clarifying comment here!!
src/store.ts
Outdated
const { orderByNewest } = data; | ||
store.commit('setSemesters', plan.semesters); | ||
updateDoc(doc(fb.semestersCollection, simplifiedUser.email), { | ||
plans: data.plans, | ||
// savedCourses: data.savedCourses, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I saw the toggling comment from above... is there a more intuitive way (rather than toggling within the code) to handle the refresh progress? works for now, but something to consider.
- added updateDoc in backend functions - made edit Collections modal more functional with saveCourse
Summary
This pull request is the first step towards adding collection into Firebase for implementing the Save Courses Feature.
Implement functionality to save selected courses into collection(s) in Firebase.
updated documentation: https://www.notion.so/Saved-Courses-8154144312034ccc914a6a37ef5ff0a6
Breaking Changes with Backend
Every user has a
Plan 1
that's automatically added if the user has no plan, but the code doesn't seem to do this with the default CollectionAll
, so that was breaking my entire Courseplan account. I was hoping a migration can fix it I also added a quick script for that.add collection to firebase
when add a course to a collection, backend should be able to store that course into the collection
course is removed from semester view and removed from requirements
collection can be named by user before creation
front-end matches with figma design (fixed padding, highlighting and auto-boldening of the box)
Here's the latest demo:
Screen.Recording.2024-10-27.231911.mp4
Here's a Screenshot of the collections with a scrollbar and editability:
Here is a demo of adding one course into one newly created collection. (this is with the old front-end look, but the backend is the same)
Here is a demo of adding one course into multiple new created collections (this is with the old front-end look, but the backend is the same)
Remaining TODOs:
Depends on #{number of PR}
#921
Test Plan
Notes
Concluded to store savedCourses in FireStoreSemesterData.
Blockers
Breaking Changes
store
used to have collections now it's renamed to savedCourses for clarity.