Forked from an inaccessible project.
-
Isaac Evavold authoredIsaac Evavold authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
utils.ts 4.30 KiB
import { Observable, forkJoin } from 'rxjs';
import { map } from 'rxjs/operators';
import { PlannedTermEra, PlannedTerm } from '@app/core/models/planned-term';
import { YearMapping } from '@app/core/models/year';
import { YearCode, TermCode } from '@app/core/models/termcode';
export const isValidTermCode = (anything: any): anything is string => {
return /^\d{4}$/.test(anything);
};
export const pickTermName = (termOffset: string) => {
switch (termOffset) {
case '2':
case '3':
return 'fall';
case '4':
return 'spring';
case '6':
return 'summer';
default:
throw new Error(`'${termOffset}' is not a valid term offset`);
}
};
export const pickTermEra = (
termCode: TermCode,
activeTermCodes: ReadonlyArray<TermCode>,
): PlannedTermEra => {
const noActiveTermCodes = activeTermCodes.length === 0;
const isActiveTermCode = activeTermCodes.some(tc => tc.equals(termCode));
const beforeAllActiveTermCodes = activeTermCodes.every(tc =>
tc.comesAfter(termCode),
);
if (noActiveTermCodes || isActiveTermCode) {
return 'active';
} else if (beforeAllActiveTermCodes) {
return 'past';
} else {
return 'future';
}
};
export const pickYearEra = (
yearCode: YearCode,
activeTermCodes: ReadonlyArray<TermCode>,
): PlannedTermEra => {
const activeYearCodes = activeTermCodes.map(tc => tc.yearCode);
const noActiveYearCodes = activeYearCodes.length === 0;
const isActiveYearCode = activeYearCodes.some(yc => yc.equals(yearCode));
const beforeAllActiveYearCodes = activeYearCodes.every(yc =>
yc.comesAfter(yearCode),
);
if (noActiveYearCodes || isActiveYearCode) {
return 'active';
} else if (beforeAllActiveYearCodes) {
return 'past';
} else {
return 'future';
}
};
export const yearsToDropZoneIds = () => (years$: Observable<YearMapping>) => {
return years$.pipe(
map(years => {
const yearCodes = Object.keys(years);
const termCodes = yearCodes.reduce<string[]>((acc, yearCode) => {
if (years[yearCode].fall.era !== 'past') {
acc = acc.concat(years[yearCode].fall.termCode.toString());
}
if (years[yearCode].spring.era !== 'past') {
acc = acc.concat(years[yearCode].spring.termCode.toString());
}
if (years[yearCode].summer.era !== 'past') {
acc = acc.concat(years[yearCode].summer.termCode.toString());
}
return acc;
}, []);
const termIds = [
'saved-courses',
...termCodes.map(termCode => `term-${termCode}`),
];
return termIds;
}),
);
};
export const compareArrays = <T>(cmp: (a: T, b: T) => boolean) => {
return (a: T[], b: T[]): boolean => {
if (a.length === b.length) {
return a.every((elem, i) => cmp(elem, b[i]));
} else {
return false;
}
};
};
export const compareStringArrays = compareArrays<string>((a, b) => a === b);
export const yearsToYearCodes = () => (years$: Observable<YearMapping>) => {
return years$.pipe(
map(years => {
const yearCodes = Object.keys(years);
const sortedYearCodes = yearCodes.sort();
return sortedYearCodes;
}),
);
};
export const yearsToDroppableTermCodes = () => (
years$: Observable<YearMapping>,
) => {
return years$.pipe(
map(years => {
const yearCodes = Object.keys(years);
return yearCodes.reduce<string[]>((acc, yearCode) => {
if (years[yearCode].fall.era !== 'past') {
acc = acc.concat(years[yearCode].fall.termCode.toString());
}
if (years[yearCode].spring.era !== 'past') {
acc = acc.concat(years[yearCode].spring.termCode.toString());
}
if (years[yearCode].summer.era !== 'past') {
acc = acc.concat(years[yearCode].summer.termCode.toString());
}
return acc;
}, []);
}),
);
};
interface SimpleMap {
[name: string]: any;
}
type ObservableMap<T = SimpleMap> = { [K in keyof T]: Observable<T[K]> };
export const forkJoinWithKeys = <T = SimpleMap>(pairs: ObservableMap<T>) => {
const keys = Object.keys(pairs);
const observables = keys.map(key => pairs[key]);
return forkJoin(observables).pipe(
map<any[], T>(values => {
const valueMapping = {} as T;
keys.forEach((key, index) => {
valueMapping[key] = values[index];
});
return valueMapping;
}),
);
};