Skip to content

Commit

Permalink
Merge pull request #126 from adobecom/MWPW-140925
Browse files Browse the repository at this point in the history
MWPW-140925: add ability to filter by event timing in the filter panels
  • Loading branch information
sheridansunier authored Feb 28, 2024
2 parents 9028329 + 4cd40e7 commit bab981a
Show file tree
Hide file tree
Showing 9 changed files with 878 additions and 352 deletions.
2 changes: 1 addition & 1 deletion dist/app.css

Large diffs are not rendered by default.

938 changes: 672 additions & 266 deletions dist/main.js

Large diffs are not rendered by default.

42 changes: 21 additions & 21 deletions dist/main.min.js

Large diffs are not rendered by default.

82 changes: 41 additions & 41 deletions dist/main.source.js

Large diffs are not rendered by default.

30 changes: 15 additions & 15 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion react/src/js/components/Consonant/Container/Container.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import {
LAYOUT_CONTAINER,
ONE_SECOND_DELAY,
SORT_TYPES,
EVENT_TIMING_IDS,
} from '../Helpers/constants';
import {
ConfigContext,
Expand Down Expand Up @@ -725,10 +726,16 @@ const Container = (props) => {

const removeEmptyFilters = (allFilters, cardsFromJson) => {
const tags = [].concat(...cardsFromJson.map(card => card.tags.map(tag => tag.id)));
const timingTags = [
EVENT_TIMING_IDS.LIVE,
EVENT_TIMING_IDS.ONDEMAND,
EVENT_TIMING_IDS.UPCOMING,
];

return allFilters.map(filter => ({
...filter,
items: filter.items.filter(item => tags.includes(item.id)),
items: filter.items.filter(item => tags.includes(item.id) ||
timingTags.includes(item.id)),
})).filter(filter => filter.items.length > 0);
};

Expand Down
70 changes: 65 additions & 5 deletions react/src/js/components/Consonant/Helpers/Helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ import {
chainFromIterable,
removeDuplicatesByKey,
} from './general';
import { eventTiming } from './eventSort';
import { EVENT_TIMING_IDS } from './constants';
import {
eventTiming,
convertDateStrToMs,
defineIsOnDemand,
defineIsUpcoming,
} from './eventSort';

/**
* Needs to be explicitly called by immer - Needed for IE 11 support
Expand Down Expand Up @@ -116,6 +122,44 @@ const getUsingOrFilter = (filterType, filterTypes) => (
filterType === filterTypes.OR
);

/**
* Helper method to determine whether we are doing event filtering from the side bar tags
* @param {Set} activeFilterSet
* @returns {Boolean} - Whether collection has an event filter
*/
const getUsingTimingFilter = activeFiltersSet => (
activeFiltersSet.has(EVENT_TIMING_IDS.LIVE) ||
activeFiltersSet.has(EVENT_TIMING_IDS.ONDEMAND) ||
activeFiltersSet.has(EVENT_TIMING_IDS.UPCOMING)
);

/**
* Helper method to determine whether the card is within event timing
* @param {Object} card
* @param {Set} timing
* @returns {Boolean} - whether the card falls within selected timing options
*/
const checkEventTiming = (card, timing) => {
const curMs = Date.now();
// Times in milliseconds
const startMs = convertDateStrToMs(card.startDate);
const endMs = convertDateStrToMs(card.endDate);
// Timed categories
const isTimed = !!(startMs && endMs);
const isUpComing = isTimed ?
defineIsUpcoming(curMs, startMs) : false;
const isOnDemand = isTimed && !isUpComing ?
defineIsOnDemand(curMs, endMs) : false;
const isLive = !!(isTimed && !isUpComing && !isOnDemand && startMs);

// if you have timing filters active and there is no timing on the card it should be rejected
if (!isTimed) return false;
if (timing.has(EVENT_TIMING_IDS.UPCOMING) && isUpComing) return true;
else if (timing.has(EVENT_TIMING_IDS.ONDEMAND) && isOnDemand) return true;
else if (timing.has(EVENT_TIMING_IDS.LIVE) && isLive) return true;
return false;
};

/**
* Will return all cards that match a set of filters
* @param {Array} cards - All cards in the collection
Expand All @@ -127,17 +171,33 @@ const getUsingOrFilter = (filterType, filterTypes) => (
*/
export const getFilteredCards = (cards, activeFilters, activePanels, filterType, filterTypes) => {
const activeFiltersSet = new Set(activeFilters);

const timingSet = intersection(activeFiltersSet, new Set([
EVENT_TIMING_IDS.LIVE,
EVENT_TIMING_IDS.ONDEMAND,
EVENT_TIMING_IDS.UPCOMING,
]));
const usingXorAndFilter = getUsingXorAndFilter(filterType, filterTypes);
const usingOrFilter = getUsingOrFilter(filterType, filterTypes);
const usingTimingFilter = getUsingTimingFilter(activeFiltersSet);
// remove the time elements from the active filter set before you actually filter
timingSet.forEach(x => activeFiltersSet.delete(x));

if (activeFiltersSet.size === 0) return cards;
if (activeFiltersSet.size === 0 && !usingTimingFilter) return cards;

return cards.filter((card) => {
if (!card.tags) {
if (!card.tags && !usingTimingFilter) {
return false;
} else if (usingTimingFilter && !checkEventTiming(card, timingSet)) {
return false;
} else if (
usingTimingFilter &&
checkEventTiming(card, timingSet) &&
activeFiltersSet.size === 0
) {
// if the only filters being performed are about event timing
return true;
}

// you proceed to check the other tags in the cards after the time filter checks
const tagIds = new Set(card.tags.map(tag => tag.id));

if (usingXorAndFilter) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
function offsetString(num) {
if (`${num}`.length === 1) return `0${num}`;

return `${num}`;
}

function convertTimeZoneToHrsColonMin(dateStr) {
const num = dateStr.getTimezoneOffset() / 60;

if (`${num}`.length === 1) return `0${num}`;

const abs = Math.abs(num);
const floor = Math.floor(abs);
const decimal = num - floor;
const numToMinutes = decimal && decimal > 1 ? (60 * decimal) : 0;
const offSetHours = `${floor}`.length === 1 ? `0${floor}` : `${floor}`;
const timeZoneValue = `${numToMinutes}`.length === 1 ?
`${offSetHours}:0${numToMinutes}` : `${offSetHours}:${numToMinutes}`;

return num && num > 0 ? `-${timeZoneValue}` : `+${timeZoneValue}`;
}

const curNewDate = new Date();
const curDate = curNewDate.getTime();
const getDate = (ms) => {
const base = new Date(ms);
const yr = base.getFullYear();
const mo = offsetString(base.getMonth() + 1);
const dd = offsetString(base.getDate());
const hh = offsetString(base.getHours());
const mm = offsetString(base.getMinutes());
const sec = offsetString(base.getSeconds());
const tz = convertTimeZoneToHrsColonMin(base);


return `${yr}-${mo}-${dd}T${hh}:${mm}:${sec}.000${tz}`;
};

const shouldDisplayPaginator = [
// should return false && false && true
{
Expand Down Expand Up @@ -118,9 +156,10 @@ const getBookmarkedCards = [

const card1 = { id: 'card-id-1', tags: [{ id: 1 }, { id: 2 }] };
const card2 = { id: 'card-id-2', tags: [{ id: 1 }, { id: 2 }, { id: 3 }] };
const card3 = { id: 'card-id-3' };
const card3 = { id: 'card-id-3', };
const upcoming = { id: 'upcoming1', endDate: getDate((curDate + 240000)), startDate: getDate((curDate + 120000)),}

const cards = [card1, card2, card3];
const cards = [card1, card2, card3, upcoming];

const filterTypes = { OR: 'or', AND: 'and' };

Expand Down Expand Up @@ -157,6 +196,14 @@ const getFilteredCards = [
filterTypes,
expectedValue: [],
},
{
cards,
activeFilters: ['8as8/iabx'],
activePanels: new Set(),
filterType: 'or',
filterTypes,
expectedValue: [upcoming],
}
];

const getFilteredCardsThrowError = {
Expand Down
6 changes: 6 additions & 0 deletions react/src/js/components/Consonant/Helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ export const SORT_TYPES = {
RANDOM: 'random',
};

export const EVENT_TIMING_IDS = {
LIVE: '8as8/hafk',
ONDEMAND: '8as8/hyb6',
UPCOMING: '8as8/iabx',
};

/**
* Possible Locations of the Sort Popup
* @type {String}
Expand Down

0 comments on commit bab981a

Please sign in to comment.