Skip to content
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

Merged
merged 6 commits into from
Oct 29, 2024
Merged

collection backend #944

merged 6 commits into from
Oct 29, 2024

Conversation

plumshum
Copy link
Contributor

@plumshum plumshum commented Oct 2, 2024

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 Collection All, 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:
image
image

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)
image

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)
image

Remaining TODOs:

  • debugging saved courses (hopefully migration script can fix it!!)

Depends on #{number of PR}
#921

Test Plan

Notes

Concluded to store savedCourses in FireStoreSemesterData.

Blockers

  • A newly discovered dependency that hasn’t been addressed

Breaking Changes

  • store used to have collections now it's renamed to savedCourses for clarity.
  • Database schema change (anything that changes Firestore collection structure)
  • Other change that could cause problems (Detailed in notes)

@plumshum plumshum self-assigned this Oct 2, 2024
@dti-github-bot
Copy link
Member

dti-github-bot commented Oct 2, 2024

[diff-counting] Significant lines: 615.

Copy link
Contributor

github-actions bot commented Oct 2, 2024

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
@Destaq Destaq marked this pull request as ready for review October 6, 2024 16:15
@Destaq Destaq requested a review from a team as a code owner October 6, 2024 16:15
@Destaq Destaq marked this pull request as draft October 6, 2024 16:15
Checkbox Style
Need a collections variable in firestore
-->
<div v-for="collection in collections" :key="collection">
Copy link
Member

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.)

Copy link
Contributor

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>
Copy link
Member

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
Copy link
Member

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~

@@ -36,6 +36,7 @@ type FirestoreSemester = {
};

type FirestoreSemestersData = {
// readonly collections: readonly Collection[]; Note: Not sure where to store collections
Copy link
Member

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
Copy link
Member

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
Copy link
Member

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;
Copy link
Member

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;
Copy link
Member

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).

Copy link
Contributor

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}!`;
Copy link
Member

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.

Copy link
Contributor

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
Copy link
Member

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);
Copy link
Member

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.

Copy link
Member

@Destaq Destaq left a 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
@plumshum plumshum marked this pull request as ready for review October 23, 2024 21:49
Copy link
Contributor

@nidhi-mylavarapu nidhi-mylavarapu left a 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 :)

const course = { ...this.courseObj };
this.$emit('save-course', course, collections);
},
/* only to rename the collection */
Copy link
Contributor

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[],
Copy link
Contributor

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;
Copy link
Contributor

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}!`;
Copy link
Contributor

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
Copy link
Contributor

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,
Copy link
Contributor

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.

@plumshum plumshum marked this pull request as draft October 27, 2024 19:17
- added updateDoc in backend functions
- made edit Collections modal more functional with saveCourse
@plumshum plumshum marked this pull request as ready for review October 28, 2024 03:24
@plumshum plumshum marked this pull request as draft October 28, 2024 03:32
@plumshum plumshum merged commit f376e2c into saved-courses Oct 29, 2024
10 of 14 checks passed
@plumshum plumshum deleted the hannah--collection-backend branch October 29, 2024 21:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants