Skip to content

Commit

Permalink
fix: add copy, rename, and delete as unsaved actions properly (#1091)
Browse files Browse the repository at this point in the history
  • Loading branch information
jotalis authored Dec 30, 2024
1 parent 3a14648 commit 7560d46
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 27 deletions.
31 changes: 30 additions & 1 deletion apps/antalmanac/src/actions/ActionTypesStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,25 @@ export interface ClearScheduleAction {
type: 'clearSchedule';
}

export interface AddScheduleAction {
type: 'addSchedule';
newScheduleName: string;
}

export interface RenameScheduleAction {
type: 'renameSchedule';
scheduleIndex: number;
newScheduleName: string;
}

export interface DeleteScheduleAction {
type: 'deleteSchedule';
scheduleIndex: number;
}

export interface CopyScheduleAction {
type: 'copySchedule';
scheduleIndex: number;
newScheduleName: string;
}

Expand All @@ -77,6 +94,9 @@ export type ActionType =
| EditCustomEventAction
| ChangeCustomEventColorAction
| ClearScheduleAction
| AddScheduleAction
| RenameScheduleAction
| DeleteScheduleAction
| CopyScheduleAction
| ChangeCourseColorAction
| UndoAction;
Expand Down Expand Up @@ -158,8 +178,17 @@ class ActionTypesStore extends EventEmitter {
case 'clearSchedule':
AppStore.schedule.clearCurrentSchedule();
break;
case 'addSchedule':
AppStore.schedule.addNewSchedule(action.newScheduleName);
break;
case 'renameSchedule':
AppStore.schedule.renameSchedule(action.scheduleIndex, action.newScheduleName);
break;
case 'copySchedule':
AppStore.schedule.copySchedule(action.newScheduleName);
AppStore.schedule.copySchedule(action.scheduleIndex, action.newScheduleName);
break;
case 'deleteSchedule':
AppStore.schedule.deleteSchedule(action.scheduleIndex);
break;
default:
break;
Expand Down
8 changes: 4 additions & 4 deletions apps/antalmanac/src/actions/AppStoreActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,14 +250,14 @@ export const changeCourseColor = (sectionCode: string, term: string, newColor: s
AppStore.changeCourseColor(sectionCode, term, newColor);
};

export const copySchedule = (newScheduleName: string, options?: CopyScheduleOptions) => {
export const copySchedule = (scheduleIndex: number, newScheduleName: string, options?: CopyScheduleOptions) => {
logAnalytics({
category: analyticsEnum.addedClasses.title,
action: analyticsEnum.addedClasses.actions.COPY_SCHEDULE,
});

try {
AppStore.copySchedule(newScheduleName);
AppStore.copySchedule(scheduleIndex, newScheduleName);
options?.onSuccess(newScheduleName);
} catch (error) {
options?.onError(newScheduleName);
Expand All @@ -268,8 +268,8 @@ export const addSchedule = (scheduleName: string) => {
AppStore.addSchedule(scheduleName);
};

export const renameSchedule = (scheduleName: string, scheduleIndex: number) => {
AppStore.renameSchedule(scheduleName, scheduleIndex);
export const renameSchedule = (scheduleIndex: number, scheduleName: string) => {
AppStore.renameSchedule(scheduleIndex, scheduleName);
};

export const deleteSchedule = (scheduleIndex: number) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const ScheduleNameDialog = forwardRef((props: ScheduleNameDialogProps, ref) => {
onClose?.();

if (rename) {
renameSchedule(scheduleName, scheduleRenameIndex as number); // typecast works b/c this function only runs when `const rename = scheduleRenameIndex !== undefined` is true.
renameSchedule(scheduleRenameIndex as number, scheduleName); // typecast works b/c this function only runs when `const rename = scheduleRenameIndex !== undefined` is true.
} else {
addSchedule(scheduleName);
}
Expand Down
4 changes: 2 additions & 2 deletions apps/antalmanac/src/components/dialogs/AddSchedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ function AddScheduleDialog({ onClose, onKeyDown, ...props }: DialogProps) {
const isDark = useThemeStore((store) => store.isDark);

const [name, setName] = useState(
AppStore.getNextScheduleName(AppStore.getDefaultScheduleName(), AppStore.getScheduleNames().length)
AppStore.getNextScheduleName(() => AppStore.getScheduleNames().length, AppStore.getDefaultScheduleName())
);

const handleCancel = () => {
Expand Down Expand Up @@ -48,7 +48,7 @@ function AddScheduleDialog({ onClose, onKeyDown, ...props }: DialogProps) {
};

const handleScheduleNamesChange = useCallback(() => {
setName(AppStore.getNextScheduleName(AppStore.getDefaultScheduleName(), AppStore.getScheduleNames().length));
setName(AppStore.getNextScheduleName(AppStore.getScheduleNames().length, AppStore.getDefaultScheduleName()));
}, []);

useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion apps/antalmanac/src/components/dialogs/CopySchedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function CopyScheduleDialog(props: CopyScheduleDialogProps) {
}, [onClose]);

const handleCopy = useCallback(() => {
copySchedule(name);
copySchedule(index, name);
onClose?.({}, 'escapeKeyDown');
}, [onClose, name]);

Expand Down
2 changes: 1 addition & 1 deletion apps/antalmanac/src/components/dialogs/RenameSchedule.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function RenameScheduleDialog(props: ScheduleNameDialogProps) {
}, []);

const submitName = useCallback(() => {
renameSchedule(name, index);
renameSchedule(index, name);
onClose?.({}, 'escapeKeyDown');
}, [onClose, name, index]);

Expand Down
35 changes: 29 additions & 6 deletions apps/antalmanac/src/stores/AppStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import type {
ChangeCustomEventColorAction,
ClearScheduleAction,
CopyScheduleAction,
RenameScheduleAction,
DeleteScheduleAction,
ChangeCourseColorAction,
UndoAction,
AddScheduleAction,
} from '$actions/ActionTypesStore';
import { CalendarEvent, CourseEvent } from '$components/Calendar/CourseCalendarEvent';
import { SnackbarPosition } from '$components/NotificationSnackbar';
Expand Down Expand Up @@ -71,8 +74,8 @@ class AppStore extends EventEmitter {
}
}

getNextScheduleName(newScheduleName: string, scheduleIndex: number) {
return this.schedule.getNextScheduleName(newScheduleName, scheduleIndex);
getNextScheduleName(scheduleIndex: number, newScheduleName: string) {
return this.schedule.getNextScheduleName(scheduleIndex, newScheduleName);
}

getDefaultScheduleName() {
Expand Down Expand Up @@ -280,13 +283,26 @@ class AppStore extends EventEmitter {
// another key/value pair to keep track of the section codes for that schedule,
// and redirect the user to the new schedule
this.schedule.addNewSchedule(newScheduleName);
this.unsavedChanges = true;
const action: AddScheduleAction = {
type: 'addSchedule',
newScheduleName: newScheduleName,
};
actionTypesStore.autoSaveSchedule(action);
this.emit('scheduleNamesChange');
this.emit('currentScheduleIndexChange');
this.emit('scheduleNotesChange');
}

renameSchedule(scheduleName: string, scheduleIndex: number) {
this.schedule.renameSchedule(scheduleName, scheduleIndex);
renameSchedule(scheduleIndex: number, newScheduleName: string) {
this.schedule.renameSchedule(scheduleIndex, newScheduleName);
this.unsavedChanges = true;
const action: RenameScheduleAction = {
type: 'renameSchedule',
scheduleIndex: scheduleIndex,
newScheduleName: newScheduleName,
};
actionTypesStore.autoSaveSchedule(action);
this.emit('scheduleNamesChange');
}

Expand All @@ -295,11 +311,12 @@ class AppStore extends EventEmitter {
window.localStorage.removeItem('unsavedActions');
}

copySchedule(newScheduleName: string) {
this.schedule.copySchedule(newScheduleName);
copySchedule(scheduleIndex: number, newScheduleName: string) {
this.schedule.copySchedule(scheduleIndex, newScheduleName);
this.unsavedChanges = true;
const action: CopyScheduleAction = {
type: 'copySchedule',
scheduleIndex: scheduleIndex,
newScheduleName: newScheduleName,
};
actionTypesStore.autoSaveSchedule(action);
Expand Down Expand Up @@ -364,6 +381,12 @@ class AppStore extends EventEmitter {

deleteSchedule(scheduleIndex: number) {
this.schedule.deleteSchedule(scheduleIndex);
this.unsavedChanges = true;
const action: DeleteScheduleAction = {
type: 'deleteSchedule',
scheduleIndex: scheduleIndex,
};
actionTypesStore.autoSaveSchedule(action);
this.emit('scheduleNamesChange');
this.emit('currentScheduleIndexChange');
this.emit('addedCoursesChange');
Expand Down
24 changes: 13 additions & 11 deletions apps/antalmanac/src/stores/Schedules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export class Schedules {
this.skeletonSchedules = [];
}

getNextScheduleName(newScheduleName: string, scheduleIndex: number) {
getNextScheduleName(scheduleIndex: number, newScheduleName: string) {
const scheduleNames = this.getScheduleNames();
scheduleNames.splice(scheduleIndex, 1);
let nextScheduleName = newScheduleName;
Expand Down Expand Up @@ -108,7 +108,7 @@ export class Schedules {
this.addUndoState();
const scheduleNoteId = Math.random();
this.schedules.push({
scheduleName: this.getNextScheduleName(newScheduleName, this.getNumberOfSchedules()),
scheduleName: this.getNextScheduleName(this.getNumberOfSchedules(), newScheduleName),
courses: [],
customEvents: [],
scheduleNoteId: scheduleNoteId,
Expand All @@ -122,9 +122,9 @@ export class Schedules {
* Rename schedule with the specified index.
* @param newScheduleName The name of the new schedule. If a schedule with the same name already exists, a number will be appended to the name.
*/
renameSchedule(newScheduleName: string, scheduleIndex: number) {
renameSchedule(scheduleIndex: number, newScheduleName: string) {
this.addUndoState();
this.schedules[scheduleIndex].scheduleName = this.getNextScheduleName(newScheduleName, scheduleIndex);
this.schedules[scheduleIndex].scheduleName = this.getNextScheduleName(scheduleIndex, newScheduleName);
}

/**
Expand All @@ -146,22 +146,22 @@ export class Schedules {
}

/**
* Copy the current schedule to a newly created schedule with the specified name.
* Copy the schedule at the provided index to a newly created schedule with the specified name.
*/
copySchedule(newScheduleName: string) {
copySchedule(scheduleIndex: number, newScheduleName: string) {
this.addNewSchedule(newScheduleName);
this.currentScheduleIndex = this.previousStates[this.previousStates.length - 1].scheduleIndex; // return to previous schedule index for copying
this.currentScheduleIndex = scheduleIndex; // temporarily set current schedule to the one being copied
const to = this.getNumberOfSchedules() - 1;

for (const course of this.getCurrentCourses()) {
this.addCourse(course, to, false);
}

for (const customEvent of this.getCurrentCustomEvents()) {
this.addCustomEvent(customEvent, [to]);
this.addCustomEvent(customEvent, [to], false);
}
this.currentScheduleIndex = this.previousStates[this.previousStates.length - 1].scheduleIndex; // return to previously selected schedule index
}

getCurrentCourses() {
return this.schedules[this.currentScheduleIndex]?.courses || [];
}
Expand Down Expand Up @@ -339,8 +339,10 @@ export class Schedules {
/**
* Adds a new custom event to given indices
*/
addCustomEvent(newCustomEvent: RepeatingCustomEvent, scheduleIndices: number[]) {
this.addUndoState();
addCustomEvent(newCustomEvent: RepeatingCustomEvent, scheduleIndices: number[], addUndoState = true) {
if (addUndoState) {
this.addUndoState();
}
for (const scheduleIndex of scheduleIndices) {
if (!this.doesCustomEventExistInSchedule(newCustomEvent.customEventID, scheduleIndex)) {
this.schedules[scheduleIndex].customEvents.push(newCustomEvent);
Expand Down

0 comments on commit 7560d46

Please sign in to comment.