Last active
April 12, 2022 09:52
-
-
Save ivan-kleshnin/b5cd180b02fb62fe19cfe3fc1b6ca297 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const experiences = [ | |
// all `nulls`s | |
{id: 1, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: null, endDateMonth: null}, | |
// three `null`s | |
{id: 2, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: null, endDateMonth: null}, | |
{id: 3, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: null, endDateMonth: null}, | |
{id: 4, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: 2022, endDateMonth: null}, | |
{id: 5, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: null, endDateMonth: 2}, | |
// two `null`s | |
{id: 6, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: 2022, endDateMonth: null}, | |
{id: 7, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: null, endDateMonth: 2}, | |
{id: 8, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: 2022, endDateMonth: null}, | |
{id: 9, name: "FOO", startDateYear: null, startDateMonth: null, endDateYear: 2022, endDateMonth: 2}, | |
{id: 10, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: null, endDateMonth: 2}, | |
{id: 11, name: "FOO", startDateYear: 2044, startDateMonth: 2, endDateYear: null, endDateMonth: null}, | |
// single `null` | |
{id: 12, name: "FOO", startDateYear: null, startDateMonth: 2, endDateYear: 2022, endDateMonth: 2}, | |
{id: 13, name: "FOO", startDateYear: 2022, startDateMonth: null, endDateYear: 2022, endDateMonth: 2}, | |
{id: 14, name: "FOO", startDateYear: 2022, startDateMonth: 2, endDateYear: 2021, endDateMonth: null}, | |
// no `null` | |
{id: 15, name: "FOO", startDateYear: 2022, startDateMonth: 2, endDateYear: 2032, endDateMonth: 2}, | |
{id: 16, name: "FOO", startDateYear: 2024, startDateMonth: 2, endDateYear: 2032, endDateMonth: 2}, | |
{id: 16, name: "FOO", startDateYear: 2020, startDateMonth: 2, endDateYear: 2021, endDateMonth: 2}, | |
{id: 16, name: "FOO", startDateYear: 2020, startDateMonth: 2, endDateYear: 2020, endDateMonth: 2}, | |
].flatMap(exp => [{...exp, endDateIsCurrent: true}, {...exp, id: exp.id + 10, endDateIsCurrent: false}]) | |
function isWorkExperience(experience) { | |
// IMPORTANT won't work if we start to return `undefined` instead of `null` | |
// In this case new prop `_type` should be injected | |
return "companyName" in experience | |
} | |
export function convertExperience(experience : TalentWorkExperience | TalentEducation) : Experience { | |
const expDates : ExperienceDates = { | |
// TODO check 1st month is 1 or 0!!! | |
...(experience.startDateYear && experience.startDateMonth) | |
? {startDate: new Date(experience.startDateYear, experience.startDateMonth)} | |
: {}, | |
...experience.endDateIsCurrent | |
? {endDate: true} | |
: (experience.endDateYear && experience.endDateMonth) ? {endDate: new Date(experience.endDateYear, experience.endDateMonth)} : {}, | |
} | |
return isWorkExperience(experience) ? { | |
...expDates, | |
id: experience.id, | |
name: experience.name, | |
companyName: experience.companyName, | |
link: experience.link, | |
description: experience.description, | |
} : { | |
...expDates, | |
id: experience.id, | |
name: experience.name, | |
description: experience.description, | |
} | |
} | |
type ComparisonResult = -1 | 0 | 1 // TODO use a global type | |
function compareIds(e1 : Experience, e2 : Experience) : ComparisonResult { | |
return (e1.id > e2.id) ? -1 : | |
(e1.id < e2.id) ? 1 : 0 | |
} | |
function compareDatesByField(field : "startDate" | "endDate") { | |
return function compareDates(e1 : Experience, e2 : Experience) : ComparisonResult { | |
if (e1[field] && e2[field]) { | |
return (e1[field]! > e2[field]!) ? -1 : | |
(e1[field]! < e2[field]!) ? 1 : compareIds(e1, e2) | |
} else if (e1[field]) { | |
return -1 | |
} else if (e2[field]) { | |
return 1 | |
} else { | |
return compareIds(e1, e2) | |
} | |
} | |
} | |
const compareStartDates = compareDatesByField("startDate") | |
const compareEndDates = compareDatesByField("endDate") | |
function compareExperiences(e1 : Experience, e2 : Experience) { | |
if (e1.endDate === true && e2.endDate === true) { | |
return compareStartDates(e1, e2) | |
} else if (e1.endDate === true) { | |
return -1 | |
} else if (e2.endDate === true) { | |
return 1 | |
} else { | |
return compareStartDates(e1, e2) || compareEndDates(e1, e2) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you for the review!
Because in this case I don't see much benefit of using an extra library. For date manipulations I personally prefer https://date-fns.org/ but it's quite large. Right now, to avoid wasting time on search & comparison & bundling something we don't really need there's just one extra function. Can be reconsidered in the future, of course, if we start using dayjs or something else.
Yep, I just didn't have time to setup test infrastructure yet. For TypeScript + React + NextJS it's not the quickest task. I spent days trying to make Jest work with TS and ESM modules and JSX in the (not so distant) past.
I plan to work on that, if someone with "Automation QA" skill will join us.