All files / client/src/views/all-program-items programListUtils.ts

92.3% Statements 36/39
91.66% Branches 22/24
77.77% Functions 7/9
92.3% Lines 36/39

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108                          521x 521x 521x 521x     521x               1012x         1012x   20x             1012x           1012x 991x 21x           21x     521x       1019x 1012x     7x 15x 18x 2x   16x 3x   13x 2x   11x 2x   9x       1x   8x               521x       4069x 4069x 4434x 567x   3867x   4069x    
import { Dayjs } from "dayjs";
import {
  AgeGroup,
  Language,
  ProgramItem,
  Tag,
} from "shared/types/models/programItem";
import { isPreConventionWeekProgramItem } from "shared/utils/isPreConventionWeekProgramItem";
import {
  getUpcomingProgramItems,
  isMainEventProgramVisible,
} from "client/utils/getUpcomingProgramItems";
 
export enum StartingTimeOption {
  UPCOMING = "upcoming",
  ALL = "all",
  REVOLVING_DOOR = "revolvingDoor",
}
 
export const getVisibleProgramItems = (
  programItems: readonly ProgramItem[],
  selectedView: StartingTimeOption,
  selectedTags: readonly string[],
  hideFull: boolean,
  fullProgramItemIds: ReadonlySet<string>,
  timeNow: Dayjs,
): readonly ProgramItem[] => {
  const tagFilteredProgramItems = getTagFilteredProgramItems(
    programItems,
    selectedTags,
  );
 
  const fullnessFiltered = hideFull
    ? tagFilteredProgramItems.filter(
        (item) => !fullProgramItemIds.has(item.programItemId),
      )
    : tagFilteredProgramItems;
 
  // Before the main event program is visible, only show pre-convention week program.
  // After it is visible, pre-convention week program is in the past so it drops out of
  // the upcoming list on its own
  const phaseFilteredProgramItems = isMainEventProgramVisible(timeNow)
    ? fullnessFiltered
    : fullnessFiltered.filter((programItem) =>
        isPreConventionWeekProgramItem(programItem),
      );
 
  if (selectedView === StartingTimeOption.UPCOMING) {
    return getUpcomingProgramItems(phaseFilteredProgramItems, timeNow);
  } else Iif (selectedView === StartingTimeOption.REVOLVING_DOOR) {
    return getUpcomingProgramItems(phaseFilteredProgramItems, timeNow).filter(
      (programItem) => programItem.revolvingDoor,
    );
  }
 
  return phaseFilteredProgramItems;
};
 
export const getTagFilteredProgramItems = (
  programItems: readonly ProgramItem[],
  selectedTags: readonly string[],
): readonly ProgramItem[] => {
  if (selectedTags.length === 0) {
    return programItems;
  }
  // Show items matching all of the selected tags (AND)
  return programItems.filter((programItem) =>
    selectedTags.every((selectedTag) => {
      if (programItem.programType.includes(selectedTag)) {
        return true;
      }
      if (programItem.tags.includes(selectedTag as Tag)) {
        return true;
      }
      if (programItem.ageGroups.includes(selectedTag as AgeGroup)) {
        return true;
      }
      if (programItem.languages.includes(selectedTag as Language)) {
        return true;
      }
      if (
        programItem.languages.includes(Language.LANGUAGE_FREE) &&
        Object.values(Language).includes(selectedTag as Language)
      ) {
        return true;
      }
      return false;
    }),
  );
};
 
// The header of the group currently at (or scrolled past) the top of the visible
// range — pinned to the top while its group scrolls. `stickyHeaderIndexes` is
// ascending, so the last one at or before `rangeStartIndex` is the active header
export const getActiveStickyHeaderIndex = (
  stickyHeaderIndexes: readonly number[],
  rangeStartIndex: number,
): number => {
  let activeIndex = 0;
  for (const headerIndex of stickyHeaderIndexes) {
    if (headerIndex > rangeStartIndex) {
      break;
    }
    activeIndex = headerIndex;
  }
  return activeIndex;
};