Skip to content

Commit

Permalink
SP24 Multiple Plans Release (#901)
Browse files Browse the repository at this point in the history
* updated contributors page (#890)

* chore: added engrc 3027 as valid engrc (#891)

* Add ENGRC 3025 as Engineering Communications (#900)

* add engrc 3025

* run req-gen

* multiple plans! (#877)

* refactor whole codebase to plans instead of semesters

* add functions that disappeared after merge

* Implemented multiple plans feature flag and added add plan button

* Multiple plans dropdown (#806)

* Implement dropdown frontend

- Add dropdown component
- Add cypress tests for open/close states.

* Add changing arrow direction

* Change plan when clicked

* Run checks

* Enable feature flag before running test

* Fix arrow resizing problem and address Zak changes

* Change colors to set colors, try to fix test

* Tests working + remove feature flag for time being

* Finally passing the cypress tests <33

* Hover state cursor -> pointer

* Refactor css into scss

* Add scss file lol

* migration script for multiple plans in firebase (#817)

* migration script for multiple plans in firebase

* Move Plan type to Migration Script

* Multiple plans functions (#816)

* Implement dropdown frontend

- Add dropdown component
- Add cypress tests for open/close states.

* Add changing arrow direction

* Change plan when clicked

* Run checks

* Enable feature flag before running test

* Fix arrow resizing problem and address Zak changes

* Change colors to set colors, try to fix test

* Tests working + remove feature flag for time being

* Finally passing the cypress tests <33

* Hover state cursor -> pointer

* Refactor css into scss

* Add scss file lol

* Implement Vuex and Firestore functions

* Update src/global-firestore-data/user-semesters.ts

Co-authored-by: zachary0kent <[email protected]>

* Update src/global-firestore-data/user-semesters.ts

Co-authored-by: zachary0kent <[email protected]>

* Update src/global-firestore-data/user-semesters.ts

Co-authored-by: zachary0kent <[email protected]>

* Update src/store.ts

Co-authored-by: zachary0kent <[email protected]>

* Run format

* Add computed property for plans and currentplan

---------

Co-authored-by: zachary0kent <[email protected]>

* Implement frontend for all modals to add, delete and edit plans.

* Run npm format

* call firestore functions for add blank plan

* Fix type issue in teleport modal

* fix issue with adding 2nd new plan

* add plan type

* add getter for current plan's semesters

* missed one use of getter

* delete duplicate functions

* multiple plans is multiple planning??

* confirmation modal when plans are added/deleted/edited

* fix bug to display correct plan

* cypress tests

* address edge cases in multiple plans (#895)

* Implemented multiple plans feature flag and added add plan button

* Multiple plans dropdown (#806)

* Implement dropdown frontend

- Add dropdown component
- Add cypress tests for open/close states.

* Add changing arrow direction

* Change plan when clicked

* Run checks

* Enable feature flag before running test

* Fix arrow resizing problem and address Zak changes

* Change colors to set colors, try to fix test

* Tests working + remove feature flag for time being

* Finally passing the cypress tests <33

* Hover state cursor -> pointer

* Refactor css into scss

* Add scss file lol

* migration script for multiple plans in firebase (#817)

* migration script for multiple plans in firebase

* Move Plan type to Migration Script

* Multiple plans functions (#816)

* Implement dropdown frontend

- Add dropdown component
- Add cypress tests for open/close states.

* Add changing arrow direction

* Change plan when clicked

* Run checks

* Enable feature flag before running test

* Fix arrow resizing problem and address Zak changes

* Change colors to set colors, try to fix test

* Tests working + remove feature flag for time being

* Finally passing the cypress tests <33

* Hover state cursor -> pointer

* Refactor css into scss

* Add scss file lol

* Implement Vuex and Firestore functions

* Update src/global-firestore-data/user-semesters.ts

Co-authored-by: zachary0kent <[email protected]>

* Update src/global-firestore-data/user-semesters.ts

Co-authored-by: zachary0kent <[email protected]>

* Update src/global-firestore-data/user-semesters.ts

Co-authored-by: zachary0kent <[email protected]>

* Update src/store.ts

Co-authored-by: zachary0kent <[email protected]>

* Run format

* Add computed property for plans and currentplan

---------

Co-authored-by: zachary0kent <[email protected]>

* Implement frontend for all modals to add, delete and edit plans.

* Run npm format

* call firestore functions for add blank plan

* Fix type issue in teleport modal

* fix issue with adding 2nd new plan

* refactor whole codebase to plans instead of semesters

* add functions that disappeared after merge

* add plan type

* add getter for current plan's semesters

* missed one use of getter

* delete duplicate functions

* multiple plans is multiple planning??

* confirmation modal when plans are added/deleted/edited

* fix bug to display correct plan

* cypress tests

* address edge cases in multiple plans

* disable buttons

* frontend fixes

* frontend fix again

* tour + refactoring

* Revert "frontend fixes"

This reverts commit 2e66263.

* Revert "tour + refactoring"

This reverts commit 49ee18d.

* change button radius

* refactoring again

* silly format fix

* frontend fixes

* auto name for copy

* sawNewFeature migration

* tour!

* firebase changes

* slay? only appear once?

* address edge cases in multiple plans

* disable buttons

* frontend fixes

* frontend fix again

* tour + refactoring

* Revert "frontend fixes"

This reverts commit 2e66263.

* Revert "tour + refactoring"

This reverts commit 49ee18d.

* change button radius

* refactoring again

* silly format fix

* frontend fixes

* auto name for copy

* sawNewFeature migration

* tour!

* firebase changes

* slay? only appear once?

* cypress

---------

Co-authored-by: zachary0kent <[email protected]>
Co-authored-by: andxu282 <[email protected]>

* get rid of console

* copy name

* fix

* fix

---------

Co-authored-by: zachary0kent <[email protected]>
Co-authored-by: andxu282 <[email protected]>

* recompute reqs (#902)

* add Viticulture and Enology major (#896)

* added vien.ts file and import statements

* imported vien to index

* Added Physical Science Core for major

* added chemistry requirement

* fixed physical science core requirements logic

* added Statistics requirement

* added Plant Science Requirement and fixed name for Statistics

* Add Viticulture & Encology Core

* Add Major Electives w/ description

* Add descriptions and Advisor

* fixed logic

* fixed order by (#903)

* fixed order by

* delete console

---------

Co-authored-by: Hannah Zhou <[email protected]>
Co-authored-by: Simon Ilincev <[email protected]>
Co-authored-by: Andrew Xu <[email protected]>
Co-authored-by: zachary0kent <[email protected]>
Co-authored-by: andxu282 <[email protected]>
  • Loading branch information
6 people authored Mar 16, 2024
1 parent 22be086 commit 5274fe3
Show file tree
Hide file tree
Showing 42 changed files with 2,524 additions and 148 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,25 @@ Then access http://localhost:8080/

## Contributors

## SP24
- **Hannah Zhou** - Developer
- **Nidhi Mylavarapu** - Developer
- **Simon Ilincev** - Developer
- **Zak Kent** - Dev Advisor
- **Joanna Chen** - Designer
- **Elizabeth Tang** - TPM
- **Andrew Xu** - TPM
- **Kaylin Chan** - PM
- **Ilyssa Yan** - APM

### FA23
- **Nidhi Mylavarapu** - Developer
- **Simon Ilincev** - Developer
- **Jerry Wang** - Developer
- **Miranda Yu** - Developer
- **Elizabeth Tang** - Developer
- **Pablo Raigoza** - Developer
- **Andrew Xu** - Developer
- **Michelle Dai** - Designer
- **Joanna Chen** - Designer
- **Jonathan Mak** - PMM
Expand Down
17 changes: 17 additions & 0 deletions cypress/integration/test.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ before('Visit site logged in', () => {
cy.wait(5000); // ensure the page has time to load
});

// Test to confirm that the new user walkthrough works as expected
// Click through the initial explanation, then the 4 following steps, and finally the finishing page
it('Click through new feature tour', () => {
cy.get('.introjs-nextbutton').click();
});

// Delete existing semesters to ensure existing data does not mess with tests
it('Delete all existing semesters, if any exist', () => {
const semesterMenus = '[data-cyId=semesterMenu]';
Expand Down Expand Up @@ -237,3 +243,14 @@ it('Minimize a semester', () => {
cy.get('[data-cyId=semester-course]').should('be.visible');
cy.get('[data-cyId=semester-addCourse]').should('be.visible');
});

it('Multiple plans dropdown open/close', () => {
// dropdown initially closed
cy.get('[data-cyId=multiplePlans-dropdown-content]').should('not.exist');
cy.get('[data-cyId=multiplePlans-dropdown-open]').click();
// dropdown opens
cy.get('[data-cyId=multiplePlans-dropdown-content]').should('be.visible');
cy.get('[data-cyId=multiplePlans-dropdown-close]').click();
// dropdown closed again
cy.get('[data-cyId=multiplePlans-dropdown-content]').should('not.exist');
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,4 @@
"not dead"
],
"license": "AGPL-3.0"
}
}
28 changes: 28 additions & 0 deletions scripts/migration/new-feature-migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* eslint-disable no-console */

import { usernameCollection, onboardingDataCollection } from '../firebase-config';

/**
* Perform migration of semester to plans with a list of semesters
*/
async function runOnUser(userEmail: string) {
await onboardingDataCollection.doc(userEmail).update({ sawNewFeature: false });
}

async function main() {
const userEmail = process.argv[2];
if (userEmail != null) {
await runOnUser(userEmail);
return;
}
const collection = await usernameCollection.get();
for (const { id } of collection.docs) {
console.group(`Running on ${id}...`);
// Intentionally await in a loop to have no interleaved console logs.
// eslint-disable-next-line no-await-in-loop
await runOnUser(id);
console.groupEnd();
}
}

main();
32 changes: 32 additions & 0 deletions scripts/migration/plans-migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable no-console */

import { usernameCollection, semestersCollection } from '../firebase-config';

/**
* Perform migration of semester to plans with a list of semesters
*/
async function runOnUser(userEmail: string) {
const semestersDoc = await semestersCollection.doc(userEmail).get();
const semesters = semestersDoc.data()?.semesters ?? [];
await semestersCollection.doc(userEmail).update({
plans: [{ name: 'Plan 1', semesters }],
});
}

async function main() {
const userEmail = process.argv[2];
if (userEmail != null) {
await runOnUser(userEmail);
return;
}
const collection = await usernameCollection.get();
for (const { id } of collection.docs) {
console.group(`Running on ${id}...`);
// Intentionally await in a loop to have no interleaved console logs.
// eslint-disable-next-line no-await-in-loop
await runOnUser(id);
console.groupEnd();
}
}

main();
6 changes: 3 additions & 3 deletions scripts/track-users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,11 +135,11 @@ async function trackUsers() {
return;
}

const semesters = getFirstPlan(doc.data());
const plan = getFirstPlan(doc.data());

let oldSemesterCount = 0;
let newSemesterCount = 0;
semesters.forEach((semester: { year: number; season: string }) => {
plan.semesters.forEach((semester: { year: number; season: string }) => {
if (isOld(semester)) {
oldSemesterCount += 1;
} else {
Expand All @@ -152,7 +152,7 @@ async function trackUsers() {
activeUsersCount += 1;
}

numSemestersPerUser.push(semesters.length);
numSemestersPerUser.push(plan.semesters.length);
oldSemesters.push(oldSemesterCount);
newSemesters.push(newSemesterCount);
});
Expand Down
4 changes: 4 additions & 0 deletions src/assets/images/editplan.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/components/Course/CourseCaution.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ const getCourseCautions = (
isPlaceholderCourse(course) &&
((!store.state.orderByNewest && semesterIndex !== course.startingSemester) ||
(store.state.orderByNewest &&
store.state.semesters.length - semesterIndex + 1 !== course.startingSemester));
store.getters.getCurrentPlanSemesters.length - semesterIndex + 1 !==
course.startingSemester));
return {
noMatchedRequirement,
typicallyOfferedWarning,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Modals/EditSemester.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default defineComponent({
},
computed: {
semesters(): readonly FirestoreSemester[] {
return store.state.semesters;
return store.getters.getCurrentPlanSemesters;
},
},
methods: {
Expand Down
71 changes: 71 additions & 0 deletions src/components/Modals/MultiplePlans/AddPlanModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<teleport-modal
title="Copy Plan?"
content-class="content-plan"
left-button-text="Create Blank"
right-button-text="Make a Copy"
@modal-closed="closeCurrentModal"
@left-button-clicked="blankPlan"
@right-button-clicked="copyPlan"
:isPlanModal="true"
>
Would you like to copy an existing plan or create a blank one?
</teleport-modal>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import store from '@/store';
import TeleportModal from '@/components/Modals/TeleportModal.vue';
export default defineComponent({
components: { TeleportModal },
emits: {
'close-plan-modal': () => true,
'open-copy-modal': () => true,
'add-plan': (name: string) => typeof name === 'string',
},
computed: {
placeholder_name() {
const oldplans = store.state.plans.map(plan => plan.name);
let newplannum = 1;
// eslint-disable-next-line no-loop-func
while (oldplans.find(p => p === `New Plan ${newplannum}`)) {
newplannum += 1;
}
return `New Plan ${newplannum}`;
},
},
data() {
return { isDisabled: false, isCopyPlanOpen: false };
},
methods: {
closeCurrentModal() {
this.$emit('close-plan-modal');
},
blankPlan() {
this.$emit('close-plan-modal');
this.$emit('add-plan', this.placeholder_name);
},
copyPlan() {
this.$emit('open-copy-modal');
this.$emit('close-plan-modal');
},
},
});
</script>

<style lang="scss">
.content-plan {
width: 20rem;
}
.modal {
&--block {
display: block;
}
&--flex {
display: flex;
}
}
</style>
124 changes: 124 additions & 0 deletions src/components/Modals/MultiplePlans/CopyPlanModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<template>
<teleport-modal
title="Copy a Plan"
content-class="content-plan"
left-button-text="Back"
right-button-text="Copy Plan"
@modal-closed="closeCurrentModal"
@left-button-clicked="backAddPlan"
@right-button-clicked="namePlan"
>
<div class="selectPlan">
<label class="selectPlan-label">Copy Plan</label>
<div class="selectPlan-dropdown">
<div class="multiplePlansModal-dropdown">
<div
class="multiplePlansModal-dropdown-placeholder wrapper"
@click="closeDropdownIfOpen()"
>
<div class="multiplePlansModal-dropdown-placeholder plan">{{ selectedPlan }}</div>
<img
class="multiplePlansModal-dropdown-placeholder up-arrow"
v-if="shown"
alt="close dropdown"
/>
<img
class="multiplePlansModal-dropdown-placeholder down-arrow"
v-else
alt="open dropdown"
/>
</div>
<div class="multiplePlansModal-dropdown-content" v-if="shown" :class="shown">
<div
v-for="otherPlan in otherPlans"
class="multiplePlansModal-dropdown-content item"
:key="otherPlan"
@click="planClicked(otherPlan)"
>
{{ otherPlan }}
</div>
</div>
</div>
</div>
</div>
</teleport-modal>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import TeleportModal from '@/components/Modals/TeleportModal.vue';
import store from '@/store';
export default defineComponent({
props: {
plan: { type: String, default: 'No additional plans yet' },
},
components: { TeleportModal },
emits: {
'close-copy-modal': () => true,
'open-plan-modal': () => true,
'open-name-modal': () => true,
'copy-plan': (selectedPlan: string) => typeof selectedPlan === 'string',
},
data() {
return { isDisabled: false, shown: false, selectedPlan: store.state.currentPlan.name };
},
methods: {
closeCurrentModal() {
this.$emit('close-copy-modal');
},
closeDropdownIfOpen() {
this.shown = !this.shown;
},
planClicked(plan: string) {
if (this.plans.length !== 1) this.selectedPlan = plan;
},
backAddPlan() {
this.$emit('open-plan-modal');
this.$emit('close-copy-modal');
},
namePlan() {
this.$emit('open-name-modal');
this.$emit('copy-plan', this.selectedPlan);
this.$emit('close-copy-modal');
},
},
computed: {
otherPlans() {
const filtered = this.plans.filter(plan => plan !== this.selectedPlan);
return filtered.length === 0 ? ['No additional plans yet'] : filtered;
},
plans() {
return store.state.plans.map(plan => plan.name);
},
},
});
</script>

<style lang="scss">
@import '@/components/Modals/MultiplePlans/PlanModalDropdown.scss';
.selectPlan {
height: 6rem;
&-label {
position: relative;
top: 0.5rem;
}
&-dropdown {
top: 0.5rem;
position: relative;
}
}
.content-plan {
width: 20rem;
}
.modal {
&--block {
display: block;
}
&--flex {
display: flex;
}
}
</style>
Loading

0 comments on commit 5274fe3

Please sign in to comment.