@universityofmaryland/web-feeds-library 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/composite/events/common/display.d.ts +1 -0
- package/dist/composite/events/common/display.d.ts.map +1 -1
- package/dist/composite/events/common/display.js +2 -1
- package/dist/composite/events/common/display.js.map +1 -1
- package/dist/composite/events/common/display.mjs +2 -1
- package/dist/composite/events/common/display.mjs.map +1 -1
- package/dist/composite/events/common/fetch.d.ts +3 -0
- package/dist/composite/events/common/fetch.d.ts.map +1 -1
- package/dist/composite/events/common/fetch.js +17 -7
- package/dist/composite/events/common/fetch.js.map +1 -1
- package/dist/composite/events/common/fetch.mjs +17 -7
- package/dist/composite/events/common/fetch.mjs.map +1 -1
- package/dist/composite/events/common/queries.d.ts +4 -2
- package/dist/composite/events/common/queries.d.ts.map +1 -1
- package/dist/composite/events/common/queries.js +10 -4
- package/dist/composite/events/common/queries.js.map +1 -1
- package/dist/composite/events/common/queries.mjs +11 -5
- package/dist/composite/events/common/queries.mjs.map +1 -1
- package/dist/composite/events/grouped.d.ts.map +1 -1
- package/dist/composite/events/grouped.js +78 -9
- package/dist/composite/events/grouped.js.map +1 -1
- package/dist/composite/events/grouped.mjs +78 -9
- package/dist/composite/events/grouped.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# University of Maryland Feeds Library
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/@universityofmaryland/web-feeds-library)
|
|
4
4
|
|
|
5
5
|
Dynamic content feed components for displaying University of Maryland news, events, and academic information with automatic updates, caching, and brand-compliant styling.
|
|
6
6
|
|
|
@@ -4,6 +4,7 @@ interface DisplayLoadProps extends DisplayProps {
|
|
|
4
4
|
element: HTMLElement;
|
|
5
5
|
styles: string;
|
|
6
6
|
}[];
|
|
7
|
+
query?: string;
|
|
7
8
|
}
|
|
8
9
|
export declare const ID_GRID_LAYOUT_CONTAINER = "umd-grid-gap-layout-container";
|
|
9
10
|
export declare const setShadowStyles: ({ shadowRoot, styles, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../../../source/composite/events/common/display.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,YAAY,EACb,MAAM,WAAW,CAAC;AAEnB,UAAU,gBAAiB,SAAQ,YAAY;IAC7C,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../../../../source/composite/events/common/display.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,YAAY,EACb,MAAM,WAAW,CAAC;AAEnB,UAAU,gBAAiB,SAAQ,YAAY;IAC7C,OAAO,EAAE;QAAE,OAAO,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,wBAAwB,kCAAkC,CAAC;AAExE,eAAO,MAAM,eAAe,GAAU,yBAGnC;IACD,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB,kBAOA,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,iGASvB,cAAc,SAiChB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,OAAO,gBAAgB,KAAG,OAAO,CAAC,IAAI,CAgCtE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,OAAO,wBAAwB,SAqC1D,CAAC"}
|
|
@@ -93,10 +93,11 @@ const resultLoad = async (props) => {
|
|
|
93
93
|
grid.appendChild(entry.element);
|
|
94
94
|
setStyles(entry.styles);
|
|
95
95
|
});
|
|
96
|
+
const callback = () => fetch.load(props);
|
|
96
97
|
const lazyLoadButton = lazyLoad.create(
|
|
97
98
|
data.lazyLoadVariables({
|
|
98
99
|
...props,
|
|
99
|
-
callback
|
|
100
|
+
callback
|
|
100
101
|
})
|
|
101
102
|
);
|
|
102
103
|
if (lazyLoadButton) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.js","sources":["../../../../source/composite/events/common/display.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './fetch';\nimport * as dataComposed from './data';\nimport { events } from '../../../utilities';\nimport {\n NoResultsProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface DisplayLoadProps extends DisplayProps {\n entries: { element: HTMLElement; styles: string }[];\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\nexport const setShadowStyles = async ({\n shadowRoot,\n styles,\n}: {\n shadowRoot: ShadowRoot;\n styles: string;\n}) => {\n const styleElement = document.createElement('style');\n const optimizedCss = await Styles.utilities.transform.css.removeDuplicates(\n styles,\n );\n styleElement.textContent = optimizedCss;\n shadowRoot.appendChild(styleElement);\n};\n\nexport const noResults = ({\n getContainer,\n getStyles,\n getShadowRoot,\n setStyles,\n isThemeDark,\n message = 'No events found',\n linkUrl = 'https://calendar.umd.edu',\n linkText = 'View all events',\n}: NoResultsProps) => {\n const container = getContainer();\n const shadowRoot = getShadowRoot();\n const noResultsContent = feedMacros.noResults({\n message,\n linkUrl,\n linkText,\n isThemeDark,\n });\n const ariaLiveContent = feedMacros.ariaLive.create({\n message,\n });\n\n container.innerHTML = '';\n\n container.appendChild(noResultsContent.element);\n container.appendChild(ariaLiveContent);\n setStyles(noResultsContent.styles);\n\n events.dispatch(container, events.eventNames.FEED_ERROR, {\n error: 'No results found',\n message,\n });\n\n setTimeout(() => {\n const styles = getStyles();\n if (shadowRoot) {\n setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n }, 100);\n};\n\nexport const resultLoad = async (props: DisplayLoadProps): Promise<void> => {\n const { entries, getContainer, setStyles, setOffset } = props;\n const container = getContainer();\n const grid = container.querySelector(\n `#${ID_GRID_LAYOUT_CONTAINER}`,\n ) as HTMLDivElement;\n\n feedMacros.loader.remove({ container });\n feedMacros.buttonLazyLoad.remove({ container });\n setOffset(entries.length);\n\n return new Promise<void>((resolve) => {\n entries.forEach((entry) => {\n grid.appendChild(entry.element);\n setStyles(entry.styles);\n });\n\n const lazyLoadButton = feedMacros.buttonLazyLoad.create(\n dataComposed.lazyLoadVariables({\n ...props,\n callback
|
|
1
|
+
{"version":3,"file":"display.js","sources":["../../../../source/composite/events/common/display.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './fetch';\nimport * as dataComposed from './data';\nimport { events } from '../../../utilities';\nimport {\n NoResultsProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface DisplayLoadProps extends DisplayProps {\n entries: { element: HTMLElement; styles: string }[];\n query?: string;\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\nexport const setShadowStyles = async ({\n shadowRoot,\n styles,\n}: {\n shadowRoot: ShadowRoot;\n styles: string;\n}) => {\n const styleElement = document.createElement('style');\n const optimizedCss = await Styles.utilities.transform.css.removeDuplicates(\n styles,\n );\n styleElement.textContent = optimizedCss;\n shadowRoot.appendChild(styleElement);\n};\n\nexport const noResults = ({\n getContainer,\n getStyles,\n getShadowRoot,\n setStyles,\n isThemeDark,\n message = 'No events found',\n linkUrl = 'https://calendar.umd.edu',\n linkText = 'View all events',\n}: NoResultsProps) => {\n const container = getContainer();\n const shadowRoot = getShadowRoot();\n const noResultsContent = feedMacros.noResults({\n message,\n linkUrl,\n linkText,\n isThemeDark,\n });\n const ariaLiveContent = feedMacros.ariaLive.create({\n message,\n });\n\n container.innerHTML = '';\n\n container.appendChild(noResultsContent.element);\n container.appendChild(ariaLiveContent);\n setStyles(noResultsContent.styles);\n\n events.dispatch(container, events.eventNames.FEED_ERROR, {\n error: 'No results found',\n message,\n });\n\n setTimeout(() => {\n const styles = getStyles();\n if (shadowRoot) {\n setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n }, 100);\n};\n\nexport const resultLoad = async (props: DisplayLoadProps): Promise<void> => {\n const { entries, getContainer, setStyles, setOffset } = props;\n const container = getContainer();\n const grid = container.querySelector(\n `#${ID_GRID_LAYOUT_CONTAINER}`,\n ) as HTMLDivElement;\n\n feedMacros.loader.remove({ container });\n feedMacros.buttonLazyLoad.remove({ container });\n setOffset(entries.length);\n\n return new Promise<void>((resolve) => {\n entries.forEach((entry) => {\n grid.appendChild(entry.element);\n setStyles(entry.styles);\n });\n\n const callback = () => feedFetch.load(props);\n const lazyLoadButton = feedMacros.buttonLazyLoad.create(\n dataComposed.lazyLoadVariables({\n ...props,\n callback,\n }),\n );\n\n if (lazyLoadButton) {\n container.appendChild(lazyLoadButton.element);\n setStyles(lazyLoadButton.styles);\n }\n\n resolve();\n });\n};\n\nexport const resultStart = (props: DisplayStartResultsProps) => {\n const {\n feedData,\n numberOfColumnsToShow = 1,\n numberOfRowsToStart,\n isLazyLoad,\n displayResults,\n getContainer,\n getTotalEntries,\n setOffset,\n setStyles,\n layoutElement,\n } = props;\n\n const container = getContainer();\n const totalEntries = getTotalEntries();\n const showAmount = numberOfColumnsToShow || 1 * numberOfRowsToStart;\n const message = isLazyLoad\n ? `Showing ${showAmount} of ${totalEntries} articles`\n : `Showing ${showAmount} articles`;\n\n layoutElement.element.setAttribute('id', ID_GRID_LAYOUT_CONTAINER);\n container.appendChild(layoutElement.element);\n setStyles(layoutElement.styles);\n\n events.dispatch(container, events.eventNames.FEED_LOADED, {\n items: feedData,\n count: feedData.length,\n total: totalEntries || feedData.length,\n });\n\n displayResults({ feedData });\n container.appendChild(\n feedMacros.ariaLive.create({\n message,\n }),\n );\n};\n"],"names":["Styles","feedMacros.noResults","feedMacros.ariaLive","events.dispatch","events.eventNames","feedMacros.loader","feedMacros.buttonLazyLoad","feedFetch.load","dataComposed.lazyLoadVariables"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgBO,MAAM,2BAA2B;AAEjC,MAAM,kBAAkB,OAAO;AAAA,EACpC;AAAA,EACA;AACF,MAGM;AACJ,QAAM,eAAe,SAAS,cAAc,OAAO;AACnD,QAAM,eAAe,MAAMA,kBAAO,UAAU,UAAU,IAAI;AAAA,IACxD;AAAA,EAAA;AAEF,eAAa,cAAc;AAC3B,aAAW,YAAY,YAAY;AACrC;AAEO,MAAM,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AACb,MAAsB;AACpB,QAAM,YAAY,aAAA;AAClB,QAAM,aAAa,cAAA;AACnB,QAAM,mBAAmBC,YAAqB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AACD,QAAM,kBAAkBC,SAAoB,OAAO;AAAA,IACjD;AAAA,EAAA,CACD;AAED,YAAU,YAAY;AAEtB,YAAU,YAAY,iBAAiB,OAAO;AAC9C,YAAU,YAAY,eAAe;AACrC,YAAU,iBAAiB,MAAM;AAEjCC,iBAAgB,WAAWC,MAAAA,WAAkB,YAAY;AAAA,IACvD,OAAO;AAAA,IACP;AAAA,EAAA,CACD;AAED,aAAW,MAAM;AACf,UAAM,SAAS,UAAA;AACf,QAAI,YAAY;AACd,sBAAgB;AAAA,QACd;AAAA,QACA;AAAA,MAAA,CACD;AAAA,IACH;AAAA,EACF,GAAG,GAAG;AACR;AAEO,MAAM,aAAa,OAAO,UAA2C;AAC1E,QAAM,EAAE,SAAS,cAAc,WAAW,cAAc;AACxD,QAAM,YAAY,aAAA;AAClB,QAAM,OAAO,UAAU;AAAA,IACrB,IAAI,wBAAwB;AAAA,EAAA;AAG9BC,SAAkB,OAAO,EAAE,WAAW;AACtCC,WAA0B,OAAO,EAAE,WAAW;AAC9C,YAAU,QAAQ,MAAM;AAExB,SAAO,IAAI,QAAc,CAAC,YAAY;AACpC,YAAQ,QAAQ,CAAC,UAAU;AACzB,WAAK,YAAY,MAAM,OAAO;AAC9B,gBAAU,MAAM,MAAM;AAAA,IACxB,CAAC;AAED,UAAM,WAAW,MAAMC,MAAAA,KAAe,KAAK;AAC3C,UAAM,iBAAiBD,SAA0B;AAAA,MAC/CE,uBAA+B;AAAA,QAC7B,GAAG;AAAA,QACH;AAAA,MAAA,CACD;AAAA,IAAA;AAGH,QAAI,gBAAgB;AAClB,gBAAU,YAAY,eAAe,OAAO;AAC5C,gBAAU,eAAe,MAAM;AAAA,IACjC;AAEA,YAAA;AAAA,EACF,CAAC;AACH;AAEO,MAAM,cAAc,CAAC,UAAoC;AAC9D,QAAM;AAAA,IACJ;AAAA,IACA,wBAAwB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAEJ,QAAM,YAAY,aAAA;AAClB,QAAM,eAAe,gBAAA;AACrB,QAAM,aAAa,yBAAyB,IAAI;AAChD,QAAM,UAAU,aACZ,WAAW,UAAU,OAAO,YAAY,cACxC,WAAW,UAAU;AAEzB,gBAAc,QAAQ,aAAa,MAAM,wBAAwB;AACjE,YAAU,YAAY,cAAc,OAAO;AAC3C,YAAU,cAAc,MAAM;AAE9BL,iBAAgB,WAAWC,MAAAA,WAAkB,aAAa;AAAA,IACxD,OAAO;AAAA,IACP,OAAO,SAAS;AAAA,IAChB,OAAO,gBAAgB,SAAS;AAAA,EAAA,CACjC;AAED,iBAAe,EAAE,UAAU;AAC3B,YAAU;AAAA,IACRF,SAAoB,OAAO;AAAA,MACzB;AAAA,IAAA,CACD;AAAA,EAAA;AAEL;;;;;;"}
|
|
@@ -74,10 +74,11 @@ const resultLoad = async (props) => {
|
|
|
74
74
|
grid.appendChild(entry.element);
|
|
75
75
|
setStyles(entry.styles);
|
|
76
76
|
});
|
|
77
|
+
const callback = () => load(props);
|
|
77
78
|
const lazyLoadButton = lazyLoad.create(
|
|
78
79
|
lazyLoadVariables({
|
|
79
80
|
...props,
|
|
80
|
-
callback
|
|
81
|
+
callback
|
|
81
82
|
})
|
|
82
83
|
);
|
|
83
84
|
if (lazyLoadButton) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.mjs","sources":["../../../../source/composite/events/common/display.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './fetch';\nimport * as dataComposed from './data';\nimport { events } from '../../../utilities';\nimport {\n NoResultsProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface DisplayLoadProps extends DisplayProps {\n entries: { element: HTMLElement; styles: string }[];\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\nexport const setShadowStyles = async ({\n shadowRoot,\n styles,\n}: {\n shadowRoot: ShadowRoot;\n styles: string;\n}) => {\n const styleElement = document.createElement('style');\n const optimizedCss = await Styles.utilities.transform.css.removeDuplicates(\n styles,\n );\n styleElement.textContent = optimizedCss;\n shadowRoot.appendChild(styleElement);\n};\n\nexport const noResults = ({\n getContainer,\n getStyles,\n getShadowRoot,\n setStyles,\n isThemeDark,\n message = 'No events found',\n linkUrl = 'https://calendar.umd.edu',\n linkText = 'View all events',\n}: NoResultsProps) => {\n const container = getContainer();\n const shadowRoot = getShadowRoot();\n const noResultsContent = feedMacros.noResults({\n message,\n linkUrl,\n linkText,\n isThemeDark,\n });\n const ariaLiveContent = feedMacros.ariaLive.create({\n message,\n });\n\n container.innerHTML = '';\n\n container.appendChild(noResultsContent.element);\n container.appendChild(ariaLiveContent);\n setStyles(noResultsContent.styles);\n\n events.dispatch(container, events.eventNames.FEED_ERROR, {\n error: 'No results found',\n message,\n });\n\n setTimeout(() => {\n const styles = getStyles();\n if (shadowRoot) {\n setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n }, 100);\n};\n\nexport const resultLoad = async (props: DisplayLoadProps): Promise<void> => {\n const { entries, getContainer, setStyles, setOffset } = props;\n const container = getContainer();\n const grid = container.querySelector(\n `#${ID_GRID_LAYOUT_CONTAINER}`,\n ) as HTMLDivElement;\n\n feedMacros.loader.remove({ container });\n feedMacros.buttonLazyLoad.remove({ container });\n setOffset(entries.length);\n\n return new Promise<void>((resolve) => {\n entries.forEach((entry) => {\n grid.appendChild(entry.element);\n setStyles(entry.styles);\n });\n\n const lazyLoadButton = feedMacros.buttonLazyLoad.create(\n dataComposed.lazyLoadVariables({\n ...props,\n callback
|
|
1
|
+
{"version":3,"file":"display.mjs","sources":["../../../../source/composite/events/common/display.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './fetch';\nimport * as dataComposed from './data';\nimport { events } from '../../../utilities';\nimport {\n NoResultsProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface DisplayLoadProps extends DisplayProps {\n entries: { element: HTMLElement; styles: string }[];\n query?: string;\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\nexport const setShadowStyles = async ({\n shadowRoot,\n styles,\n}: {\n shadowRoot: ShadowRoot;\n styles: string;\n}) => {\n const styleElement = document.createElement('style');\n const optimizedCss = await Styles.utilities.transform.css.removeDuplicates(\n styles,\n );\n styleElement.textContent = optimizedCss;\n shadowRoot.appendChild(styleElement);\n};\n\nexport const noResults = ({\n getContainer,\n getStyles,\n getShadowRoot,\n setStyles,\n isThemeDark,\n message = 'No events found',\n linkUrl = 'https://calendar.umd.edu',\n linkText = 'View all events',\n}: NoResultsProps) => {\n const container = getContainer();\n const shadowRoot = getShadowRoot();\n const noResultsContent = feedMacros.noResults({\n message,\n linkUrl,\n linkText,\n isThemeDark,\n });\n const ariaLiveContent = feedMacros.ariaLive.create({\n message,\n });\n\n container.innerHTML = '';\n\n container.appendChild(noResultsContent.element);\n container.appendChild(ariaLiveContent);\n setStyles(noResultsContent.styles);\n\n events.dispatch(container, events.eventNames.FEED_ERROR, {\n error: 'No results found',\n message,\n });\n\n setTimeout(() => {\n const styles = getStyles();\n if (shadowRoot) {\n setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n }, 100);\n};\n\nexport const resultLoad = async (props: DisplayLoadProps): Promise<void> => {\n const { entries, getContainer, setStyles, setOffset } = props;\n const container = getContainer();\n const grid = container.querySelector(\n `#${ID_GRID_LAYOUT_CONTAINER}`,\n ) as HTMLDivElement;\n\n feedMacros.loader.remove({ container });\n feedMacros.buttonLazyLoad.remove({ container });\n setOffset(entries.length);\n\n return new Promise<void>((resolve) => {\n entries.forEach((entry) => {\n grid.appendChild(entry.element);\n setStyles(entry.styles);\n });\n\n const callback = () => feedFetch.load(props);\n const lazyLoadButton = feedMacros.buttonLazyLoad.create(\n dataComposed.lazyLoadVariables({\n ...props,\n callback,\n }),\n );\n\n if (lazyLoadButton) {\n container.appendChild(lazyLoadButton.element);\n setStyles(lazyLoadButton.styles);\n }\n\n resolve();\n });\n};\n\nexport const resultStart = (props: DisplayStartResultsProps) => {\n const {\n feedData,\n numberOfColumnsToShow = 1,\n numberOfRowsToStart,\n isLazyLoad,\n displayResults,\n getContainer,\n getTotalEntries,\n setOffset,\n setStyles,\n layoutElement,\n } = props;\n\n const container = getContainer();\n const totalEntries = getTotalEntries();\n const showAmount = numberOfColumnsToShow || 1 * numberOfRowsToStart;\n const message = isLazyLoad\n ? `Showing ${showAmount} of ${totalEntries} articles`\n : `Showing ${showAmount} articles`;\n\n layoutElement.element.setAttribute('id', ID_GRID_LAYOUT_CONTAINER);\n container.appendChild(layoutElement.element);\n setStyles(layoutElement.styles);\n\n events.dispatch(container, events.eventNames.FEED_LOADED, {\n items: feedData,\n count: feedData.length,\n total: totalEntries || feedData.length,\n });\n\n displayResults({ feedData });\n container.appendChild(\n feedMacros.ariaLive.create({\n message,\n }),\n );\n};\n"],"names":["feedMacros.noResults","feedMacros.ariaLive","events.dispatch","events.eventNames","feedMacros.loader","feedMacros.buttonLazyLoad","feedFetch.load","dataComposed.lazyLoadVariables"],"mappings":";;;;;;;;;;;AAgBO,MAAM,2BAA2B;AAEjC,MAAM,kBAAkB,OAAO;AAAA,EACpC;AAAA,EACA;AACF,MAGM;AACJ,QAAM,eAAe,SAAS,cAAc,OAAO;AACnD,QAAM,eAAe,MAAM,OAAO,UAAU,UAAU,IAAI;AAAA,IACxD;AAAA,EAAA;AAEF,eAAa,cAAc;AAC3B,aAAW,YAAY,YAAY;AACrC;AAEO,MAAM,YAAY,CAAC;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,UAAU;AAAA,EACV,UAAU;AAAA,EACV,WAAW;AACb,MAAsB;AACpB,QAAM,YAAY,aAAA;AAClB,QAAM,aAAa,cAAA;AACnB,QAAM,mBAAmBA,YAAqB;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AACD,QAAM,kBAAkBC,SAAoB,OAAO;AAAA,IACjD;AAAA,EAAA,CACD;AAED,YAAU,YAAY;AAEtB,YAAU,YAAY,iBAAiB,OAAO;AAC9C,YAAU,YAAY,eAAe;AACrC,YAAU,iBAAiB,MAAM;AAEjCC,WAAgB,WAAWC,WAAkB,YAAY;AAAA,IACvD,OAAO;AAAA,IACP;AAAA,EAAA,CACD;AAED,aAAW,MAAM;AACf,UAAM,SAAS,UAAA;AACf,QAAI,YAAY;AACd,sBAAgB;AAAA,QACd;AAAA,QACA;AAAA,MAAA,CACD;AAAA,IACH;AAAA,EACF,GAAG,GAAG;AACR;AAEO,MAAM,aAAa,OAAO,UAA2C;AAC1E,QAAM,EAAE,SAAS,cAAc,WAAW,cAAc;AACxD,QAAM,YAAY,aAAA;AAClB,QAAM,OAAO,UAAU;AAAA,IACrB,IAAI,wBAAwB;AAAA,EAAA;AAG9BC,SAAkB,OAAO,EAAE,WAAW;AACtCC,WAA0B,OAAO,EAAE,WAAW;AAC9C,YAAU,QAAQ,MAAM;AAExB,SAAO,IAAI,QAAc,CAAC,YAAY;AACpC,YAAQ,QAAQ,CAAC,UAAU;AACzB,WAAK,YAAY,MAAM,OAAO;AAC9B,gBAAU,MAAM,MAAM;AAAA,IACxB,CAAC;AAED,UAAM,WAAW,MAAMC,KAAe,KAAK;AAC3C,UAAM,iBAAiBD,SAA0B;AAAA,MAC/CE,kBAA+B;AAAA,QAC7B,GAAG;AAAA,QACH;AAAA,MAAA,CACD;AAAA,IAAA;AAGH,QAAI,gBAAgB;AAClB,gBAAU,YAAY,eAAe,OAAO;AAC5C,gBAAU,eAAe,MAAM;AAAA,IACjC;AAEA,YAAA;AAAA,EACF,CAAC;AACH;AAEO,MAAM,cAAc,CAAC,UAAoC;AAC9D,QAAM;AAAA,IACJ;AAAA,IACA,wBAAwB;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,IACE;AAEJ,QAAM,YAAY,aAAA;AAClB,QAAM,eAAe,gBAAA;AACrB,QAAM,aAAa,yBAAyB,IAAI;AAChD,QAAM,UAAU,aACZ,WAAW,UAAU,OAAO,YAAY,cACxC,WAAW,UAAU;AAEzB,gBAAc,QAAQ,aAAa,MAAM,wBAAwB;AACjE,YAAU,YAAY,cAAc,OAAO;AAC3C,YAAU,cAAc,MAAM;AAE9BL,WAAgB,WAAWC,WAAkB,aAAa;AAAA,IACxD,OAAO;AAAA,IACP,OAAO,SAAS;AAAA,IAChB,OAAO,gBAAgB,SAAS;AAAA,EAAA,CACjC;AAED,iBAAe,EAAE,UAAU;AAC3B,YAAU;AAAA,IACRF,SAAoB,OAAO;AAAA,MACzB;AAAA,IAAA,CACD;AAAA,EAAA;AAEL;"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { NoResultsProps, DisplayStartProps, DisplayStartResultsProps, DisplayProps } from '../_types';
|
|
2
2
|
interface LoadMoreProps extends DisplayProps {
|
|
3
|
+
query?: string;
|
|
3
4
|
}
|
|
4
5
|
interface CreateProps extends DisplayStartProps {
|
|
5
6
|
displayResultStart: (props: DisplayStartResultsProps) => void;
|
|
6
7
|
displayNoResults: (props: NoResultsProps) => void;
|
|
8
|
+
query?: string;
|
|
9
|
+
countQuery?: string;
|
|
7
10
|
}
|
|
8
11
|
export declare const ID_GRID_LAYOUT_CONTAINER = "umd-grid-gap-layout-container";
|
|
9
12
|
type TypeFetchVariables = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../../source/composite/events/common/fetch.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,EACb,MAAM,WAAW,CAAC;AAEnB,UAAU,aAAc,SAAQ,YAAY;
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../../source/composite/events/common/fetch.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,wBAAwB,EACxB,YAAY,EACb,MAAM,WAAW,CAAC;AAEnB,UAAU,aAAc,SAAQ,YAAY;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,WAAY,SAAQ,iBAAiB;IAC7C,kBAAkB,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC9D,gBAAgB,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,wBAAwB,kCAAkC,CAAC;AAExE,KAAK,kBAAkB,GAAG;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GAAG;IACtD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CAAC;AAoFF,eAAO,MAAM,IAAI,GAAU,OAAO,aAAa,kBAsB9C,CAAC;AAEF,eAAO,MAAM,KAAK,GAAU,OAAO,WAAW,kBA6B7C,CAAC"}
|
|
@@ -31,10 +31,13 @@ const fetchFeed = async ({
|
|
|
31
31
|
variables
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
|
-
const getCount = async ({
|
|
34
|
+
const getCount = async ({
|
|
35
|
+
variables,
|
|
36
|
+
query
|
|
37
|
+
}) => {
|
|
35
38
|
const feedData = await fetchFeed({
|
|
36
39
|
...variables,
|
|
37
|
-
query: queries.EVENTS_COUNT_QUERY
|
|
40
|
+
query: query || queries.EVENTS_COUNT_QUERY
|
|
38
41
|
});
|
|
39
42
|
if (!feedData || !feedData.data || feedData.message) {
|
|
40
43
|
if (feedData.message) console.error(feedData.message);
|
|
@@ -43,9 +46,13 @@ const getCount = async ({ variables }) => {
|
|
|
43
46
|
return feedData?.data?.count?.events?.length || 0;
|
|
44
47
|
};
|
|
45
48
|
const getEntries = async ({
|
|
46
|
-
variables
|
|
49
|
+
variables,
|
|
50
|
+
query
|
|
47
51
|
}) => {
|
|
48
|
-
const feedData = await fetchFeed({
|
|
52
|
+
const feedData = await fetchFeed({
|
|
53
|
+
...variables,
|
|
54
|
+
query: query || queries.EVENTS_QUERY
|
|
55
|
+
});
|
|
49
56
|
const graceFail = ({ message }) => {
|
|
50
57
|
throw new Error(message);
|
|
51
58
|
};
|
|
@@ -69,7 +76,8 @@ const load = async (props) => {
|
|
|
69
76
|
lazyLoad.remove({ container });
|
|
70
77
|
loader.display({ container });
|
|
71
78
|
getEntries({
|
|
72
|
-
variables: data.apiVariables(props)
|
|
79
|
+
variables: data.apiVariables(props),
|
|
80
|
+
query: props.query
|
|
73
81
|
}).then((feedData) => {
|
|
74
82
|
displayResults({ feedData });
|
|
75
83
|
ariaLive.update({
|
|
@@ -81,7 +89,8 @@ const load = async (props) => {
|
|
|
81
89
|
const start = async (props) => {
|
|
82
90
|
const { displayNoResults, displayResultStart, setTotalEntries } = props;
|
|
83
91
|
await getCount({
|
|
84
|
-
variables: data.apiVariables(props)
|
|
92
|
+
variables: data.apiVariables(props),
|
|
93
|
+
query: props.countQuery
|
|
85
94
|
}).then((count) => {
|
|
86
95
|
if (count === 0) {
|
|
87
96
|
displayNoResults({ ...props });
|
|
@@ -99,7 +108,8 @@ const start = async (props) => {
|
|
|
99
108
|
}
|
|
100
109
|
});
|
|
101
110
|
getEntries({
|
|
102
|
-
variables: data.apiVariables(props)
|
|
111
|
+
variables: data.apiVariables(props),
|
|
112
|
+
query: props.query
|
|
103
113
|
}).then((feedData) => displayResultStart({ ...props, feedData }));
|
|
104
114
|
};
|
|
105
115
|
exports.load = load;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.js","sources":["../../../../source/composite/events/common/fetch.ts"],"sourcesContent":["import { fetchGraphQL } from '@universityofmaryland/web-utilities-library/network';\nimport * as feedMacros from 'macros';\nimport { EVENTS_COUNT_QUERY, EVENTS_QUERY } from './queries';\nimport * as dataComposed from './data';\nimport {\n NoResultsProps,\n DisplayStartProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface LoadMoreProps extends DisplayProps {}\n\ninterface CreateProps extends DisplayStartProps {\n displayResultStart: (props: DisplayStartResultsProps) => void;\n displayNoResults: (props: NoResultsProps) => void;\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\ntype TypeFetchVariables = {\n startDate?: string;\n related?: string[];\n limit?: number;\n offset?: number;\n};\n\nexport type TypeAPIFeedVariables = TypeFetchVariables & {\n token: string | null;\n};\n\ntype TypeFetchObject = TypeAPIFeedVariables & {\n query: string;\n};\n\nconst fetchFeed = async ({\n limit,\n related,\n offset,\n token,\n query,\n}: TypeFetchObject) => {\n if (!token) throw new Error('Token not found');\n\n const variables: TypeFetchVariables = {\n startDate: new Date().toDateString(),\n limit,\n related,\n offset,\n };\n\n return await fetchGraphQL({\n query,\n url: 'https://calendar.umd.edu/graphql',\n token: token,\n variables,\n });\n};\n\nconst getCount = async ({
|
|
1
|
+
{"version":3,"file":"fetch.js","sources":["../../../../source/composite/events/common/fetch.ts"],"sourcesContent":["import { fetchGraphQL } from '@universityofmaryland/web-utilities-library/network';\nimport * as feedMacros from 'macros';\nimport { EVENTS_COUNT_QUERY, EVENTS_QUERY } from './queries';\nimport * as dataComposed from './data';\nimport {\n NoResultsProps,\n DisplayStartProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface LoadMoreProps extends DisplayProps {\n query?: string;\n}\n\ninterface CreateProps extends DisplayStartProps {\n displayResultStart: (props: DisplayStartResultsProps) => void;\n displayNoResults: (props: NoResultsProps) => void;\n query?: string;\n countQuery?: string;\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\ntype TypeFetchVariables = {\n startDate?: string;\n related?: string[];\n limit?: number;\n offset?: number;\n};\n\nexport type TypeAPIFeedVariables = TypeFetchVariables & {\n token: string | null;\n};\n\ntype TypeFetchObject = TypeAPIFeedVariables & {\n query: string;\n};\n\nconst fetchFeed = async ({\n limit,\n related,\n offset,\n token,\n query,\n}: TypeFetchObject) => {\n if (!token) throw new Error('Token not found');\n\n const variables: TypeFetchVariables = {\n startDate: new Date().toDateString(),\n limit,\n related,\n offset,\n };\n\n return await fetchGraphQL({\n query,\n url: 'https://calendar.umd.edu/graphql',\n token: token,\n variables,\n });\n};\n\nconst getCount = async ({\n variables,\n query,\n}: {\n variables: TypeAPIFeedVariables;\n query?: string;\n}) => {\n const feedData = await fetchFeed({\n ...variables,\n query: query || EVENTS_COUNT_QUERY,\n });\n\n if (!feedData || !feedData.data || feedData.message) {\n if (feedData.message) console.error(feedData.message);\n return null;\n }\n\n return feedData?.data?.count?.events?.length || 0;\n};\n\nconst getEntries = async ({\n variables,\n query,\n}: {\n variables: TypeAPIFeedVariables;\n query?: string;\n}) => {\n const feedData = await fetchFeed({\n ...variables,\n query: query || EVENTS_QUERY,\n });\n const graceFail = ({ message }: { message: string }) => {\n throw new Error(message);\n };\n\n if (\n !feedData ||\n !feedData.data ||\n !feedData.data.entries ||\n feedData.message\n ) {\n if (!feedData) graceFail({ message: 'Feed not found' });\n if (!feedData.data) graceFail({ message: 'Feed data not found' });\n if (!feedData.data.entries)\n graceFail({ message: 'Feed entries not found' });\n if (!feedData.data.entries.events)\n graceFail({ message: 'Feed events not found' });\n if (!feedData.message)\n graceFail({ message: `Feed data errors: ${feedData.message}` });\n }\n\n return feedData.data.entries.events;\n};\n\nexport const load = async (props: LoadMoreProps) => {\n const { getContainer, getOffset, displayResults, getTotalEntries } = props;\n const container = getContainer();\n const currentCount = getOffset();\n const totalEntries = getTotalEntries();\n\n feedMacros.buttonLazyLoad.remove({ container });\n feedMacros.loader.display({ container });\n\n getEntries({\n variables: dataComposed.apiVariables(props),\n query: props.query,\n }).then((feedData) => {\n displayResults({ feedData });\n\n feedMacros.ariaLive.update({\n container,\n message: `Showing ${\n currentCount + feedData.length\n } of ${totalEntries} articles`,\n });\n });\n};\n\nexport const start = async (props: CreateProps) => {\n const { displayNoResults, displayResultStart, setTotalEntries } = props;\n\n await getCount({\n variables: dataComposed.apiVariables(props),\n query: props.countQuery,\n }).then((count) => {\n if (count === 0) {\n displayNoResults({ ...props });\n return;\n }\n\n if (count) {\n setTotalEntries(count);\n }\n\n if (count === null) {\n displayNoResults({\n ...props,\n message: 'An error occurred while fetching the data.',\n });\n return;\n }\n });\n\n getEntries({\n variables: dataComposed.apiVariables(props),\n query: props.query,\n }).then((feedData) => displayResultStart({ ...props, feedData }));\n};\n"],"names":["fetchGraphQL","EVENTS_COUNT_QUERY","EVENTS_QUERY","feedMacros.buttonLazyLoad","feedMacros.loader","dataComposed.apiVariables","feedMacros.ariaLive"],"mappings":"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"}
|
|
@@ -29,10 +29,13 @@ const fetchFeed = async ({
|
|
|
29
29
|
variables
|
|
30
30
|
});
|
|
31
31
|
};
|
|
32
|
-
const getCount = async ({
|
|
32
|
+
const getCount = async ({
|
|
33
|
+
variables,
|
|
34
|
+
query
|
|
35
|
+
}) => {
|
|
33
36
|
const feedData = await fetchFeed({
|
|
34
37
|
...variables,
|
|
35
|
-
query: EVENTS_COUNT_QUERY
|
|
38
|
+
query: query || EVENTS_COUNT_QUERY
|
|
36
39
|
});
|
|
37
40
|
if (!feedData || !feedData.data || feedData.message) {
|
|
38
41
|
if (feedData.message) console.error(feedData.message);
|
|
@@ -41,9 +44,13 @@ const getCount = async ({ variables }) => {
|
|
|
41
44
|
return feedData?.data?.count?.events?.length || 0;
|
|
42
45
|
};
|
|
43
46
|
const getEntries = async ({
|
|
44
|
-
variables
|
|
47
|
+
variables,
|
|
48
|
+
query
|
|
45
49
|
}) => {
|
|
46
|
-
const feedData = await fetchFeed({
|
|
50
|
+
const feedData = await fetchFeed({
|
|
51
|
+
...variables,
|
|
52
|
+
query: query || EVENTS_QUERY
|
|
53
|
+
});
|
|
47
54
|
const graceFail = ({ message }) => {
|
|
48
55
|
throw new Error(message);
|
|
49
56
|
};
|
|
@@ -67,7 +74,8 @@ const load = async (props) => {
|
|
|
67
74
|
lazyLoad.remove({ container });
|
|
68
75
|
loader.display({ container });
|
|
69
76
|
getEntries({
|
|
70
|
-
variables: apiVariables(props)
|
|
77
|
+
variables: apiVariables(props),
|
|
78
|
+
query: props.query
|
|
71
79
|
}).then((feedData) => {
|
|
72
80
|
displayResults({ feedData });
|
|
73
81
|
ariaLive.update({
|
|
@@ -79,7 +87,8 @@ const load = async (props) => {
|
|
|
79
87
|
const start = async (props) => {
|
|
80
88
|
const { displayNoResults, displayResultStart, setTotalEntries } = props;
|
|
81
89
|
await getCount({
|
|
82
|
-
variables: apiVariables(props)
|
|
90
|
+
variables: apiVariables(props),
|
|
91
|
+
query: props.countQuery
|
|
83
92
|
}).then((count) => {
|
|
84
93
|
if (count === 0) {
|
|
85
94
|
displayNoResults({ ...props });
|
|
@@ -97,7 +106,8 @@ const start = async (props) => {
|
|
|
97
106
|
}
|
|
98
107
|
});
|
|
99
108
|
getEntries({
|
|
100
|
-
variables: apiVariables(props)
|
|
109
|
+
variables: apiVariables(props),
|
|
110
|
+
query: props.query
|
|
101
111
|
}).then((feedData) => displayResultStart({ ...props, feedData }));
|
|
102
112
|
};
|
|
103
113
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.mjs","sources":["../../../../source/composite/events/common/fetch.ts"],"sourcesContent":["import { fetchGraphQL } from '@universityofmaryland/web-utilities-library/network';\nimport * as feedMacros from 'macros';\nimport { EVENTS_COUNT_QUERY, EVENTS_QUERY } from './queries';\nimport * as dataComposed from './data';\nimport {\n NoResultsProps,\n DisplayStartProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface LoadMoreProps extends DisplayProps {}\n\ninterface CreateProps extends DisplayStartProps {\n displayResultStart: (props: DisplayStartResultsProps) => void;\n displayNoResults: (props: NoResultsProps) => void;\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\ntype TypeFetchVariables = {\n startDate?: string;\n related?: string[];\n limit?: number;\n offset?: number;\n};\n\nexport type TypeAPIFeedVariables = TypeFetchVariables & {\n token: string | null;\n};\n\ntype TypeFetchObject = TypeAPIFeedVariables & {\n query: string;\n};\n\nconst fetchFeed = async ({\n limit,\n related,\n offset,\n token,\n query,\n}: TypeFetchObject) => {\n if (!token) throw new Error('Token not found');\n\n const variables: TypeFetchVariables = {\n startDate: new Date().toDateString(),\n limit,\n related,\n offset,\n };\n\n return await fetchGraphQL({\n query,\n url: 'https://calendar.umd.edu/graphql',\n token: token,\n variables,\n });\n};\n\nconst getCount = async ({
|
|
1
|
+
{"version":3,"file":"fetch.mjs","sources":["../../../../source/composite/events/common/fetch.ts"],"sourcesContent":["import { fetchGraphQL } from '@universityofmaryland/web-utilities-library/network';\nimport * as feedMacros from 'macros';\nimport { EVENTS_COUNT_QUERY, EVENTS_QUERY } from './queries';\nimport * as dataComposed from './data';\nimport {\n NoResultsProps,\n DisplayStartProps,\n DisplayStartResultsProps,\n DisplayProps,\n} from '../_types';\n\ninterface LoadMoreProps extends DisplayProps {\n query?: string;\n}\n\ninterface CreateProps extends DisplayStartProps {\n displayResultStart: (props: DisplayStartResultsProps) => void;\n displayNoResults: (props: NoResultsProps) => void;\n query?: string;\n countQuery?: string;\n}\n\nexport const ID_GRID_LAYOUT_CONTAINER = 'umd-grid-gap-layout-container';\n\ntype TypeFetchVariables = {\n startDate?: string;\n related?: string[];\n limit?: number;\n offset?: number;\n};\n\nexport type TypeAPIFeedVariables = TypeFetchVariables & {\n token: string | null;\n};\n\ntype TypeFetchObject = TypeAPIFeedVariables & {\n query: string;\n};\n\nconst fetchFeed = async ({\n limit,\n related,\n offset,\n token,\n query,\n}: TypeFetchObject) => {\n if (!token) throw new Error('Token not found');\n\n const variables: TypeFetchVariables = {\n startDate: new Date().toDateString(),\n limit,\n related,\n offset,\n };\n\n return await fetchGraphQL({\n query,\n url: 'https://calendar.umd.edu/graphql',\n token: token,\n variables,\n });\n};\n\nconst getCount = async ({\n variables,\n query,\n}: {\n variables: TypeAPIFeedVariables;\n query?: string;\n}) => {\n const feedData = await fetchFeed({\n ...variables,\n query: query || EVENTS_COUNT_QUERY,\n });\n\n if (!feedData || !feedData.data || feedData.message) {\n if (feedData.message) console.error(feedData.message);\n return null;\n }\n\n return feedData?.data?.count?.events?.length || 0;\n};\n\nconst getEntries = async ({\n variables,\n query,\n}: {\n variables: TypeAPIFeedVariables;\n query?: string;\n}) => {\n const feedData = await fetchFeed({\n ...variables,\n query: query || EVENTS_QUERY,\n });\n const graceFail = ({ message }: { message: string }) => {\n throw new Error(message);\n };\n\n if (\n !feedData ||\n !feedData.data ||\n !feedData.data.entries ||\n feedData.message\n ) {\n if (!feedData) graceFail({ message: 'Feed not found' });\n if (!feedData.data) graceFail({ message: 'Feed data not found' });\n if (!feedData.data.entries)\n graceFail({ message: 'Feed entries not found' });\n if (!feedData.data.entries.events)\n graceFail({ message: 'Feed events not found' });\n if (!feedData.message)\n graceFail({ message: `Feed data errors: ${feedData.message}` });\n }\n\n return feedData.data.entries.events;\n};\n\nexport const load = async (props: LoadMoreProps) => {\n const { getContainer, getOffset, displayResults, getTotalEntries } = props;\n const container = getContainer();\n const currentCount = getOffset();\n const totalEntries = getTotalEntries();\n\n feedMacros.buttonLazyLoad.remove({ container });\n feedMacros.loader.display({ container });\n\n getEntries({\n variables: dataComposed.apiVariables(props),\n query: props.query,\n }).then((feedData) => {\n displayResults({ feedData });\n\n feedMacros.ariaLive.update({\n container,\n message: `Showing ${\n currentCount + feedData.length\n } of ${totalEntries} articles`,\n });\n });\n};\n\nexport const start = async (props: CreateProps) => {\n const { displayNoResults, displayResultStart, setTotalEntries } = props;\n\n await getCount({\n variables: dataComposed.apiVariables(props),\n query: props.countQuery,\n }).then((count) => {\n if (count === 0) {\n displayNoResults({ ...props });\n return;\n }\n\n if (count) {\n setTotalEntries(count);\n }\n\n if (count === null) {\n displayNoResults({\n ...props,\n message: 'An error occurred while fetching the data.',\n });\n return;\n }\n });\n\n getEntries({\n variables: dataComposed.apiVariables(props),\n query: props.query,\n }).then((feedData) => displayResultStart({ ...props, feedData }));\n};\n"],"names":["feedMacros.buttonLazyLoad","feedMacros.loader","dataComposed.apiVariables","feedMacros.ariaLive"],"mappings":"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"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export declare const EVENTS_COUNT_QUERY
|
|
2
|
-
export declare const
|
|
1
|
+
export declare const EVENTS_COUNT_QUERY: string;
|
|
2
|
+
export declare const EVENTS_COUNT_RANGE_QUERY: string;
|
|
3
|
+
export declare const EVENTS_QUERY: string;
|
|
4
|
+
export declare const EVENTS_RANGE_QUERY: string;
|
|
3
5
|
//# sourceMappingURL=queries.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../../source/composite/events/common/queries.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../../source/composite/events/common/queries.ts"],"names":[],"mappings":"AA4GA,eAAO,MAAM,kBAAkB,QAA0B,CAAC;AAC1D,eAAO,MAAM,wBAAwB,QAAsC,CAAC;AAE5E,eAAO,MAAM,YAAY,QAAqB,CAAC;AAC/C,eAAO,MAAM,kBAAkB,QAAiC,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const
|
|
3
|
+
const buildEventsCountQuery = (dateFilter = "startsAfterOrAt") => `
|
|
4
4
|
query getEventsCount($startDate: String!, $related: [QueryArgument]) {
|
|
5
5
|
count: solspace_calendar {
|
|
6
|
-
events(relatedTo: $related, loadOccurrences: true,
|
|
6
|
+
events(relatedTo: $related, loadOccurrences: true, ${dateFilter}: $startDate) {
|
|
7
7
|
... on communications_Event {
|
|
8
8
|
id
|
|
9
9
|
}
|
|
@@ -14,13 +14,13 @@ query getEventsCount($startDate: String!, $related: [QueryArgument]) {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
`;
|
|
17
|
-
const
|
|
17
|
+
const buildEventsQuery = (dateFilter = "startsAfterOrAt") => `
|
|
18
18
|
query getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $offset: Int) {
|
|
19
19
|
entries: solspace_calendar {
|
|
20
20
|
events(
|
|
21
21
|
relatedTo: $related
|
|
22
22
|
loadOccurrences: true
|
|
23
|
-
|
|
23
|
+
${dateFilter}: $startDate
|
|
24
24
|
limit: $limit
|
|
25
25
|
offset: $offset
|
|
26
26
|
) {
|
|
@@ -102,6 +102,12 @@ query getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $of
|
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
104
|
`;
|
|
105
|
+
const EVENTS_COUNT_QUERY = buildEventsCountQuery();
|
|
106
|
+
const EVENTS_COUNT_RANGE_QUERY = buildEventsCountQuery("rangeStart");
|
|
107
|
+
const EVENTS_QUERY = buildEventsQuery();
|
|
108
|
+
const EVENTS_RANGE_QUERY = buildEventsQuery("rangeStart");
|
|
105
109
|
exports.EVENTS_COUNT_QUERY = EVENTS_COUNT_QUERY;
|
|
110
|
+
exports.EVENTS_COUNT_RANGE_QUERY = EVENTS_COUNT_RANGE_QUERY;
|
|
106
111
|
exports.EVENTS_QUERY = EVENTS_QUERY;
|
|
112
|
+
exports.EVENTS_RANGE_QUERY = EVENTS_RANGE_QUERY;
|
|
107
113
|
//# sourceMappingURL=queries.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.js","sources":["../../../../source/composite/events/common/queries.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"queries.js","sources":["../../../../source/composite/events/common/queries.ts"],"sourcesContent":["type DateFilterType = 'startsAfterOrAt' | 'rangeStart';\n\nconst buildEventsCountQuery = (\n dateFilter: DateFilterType = 'startsAfterOrAt',\n) => `\nquery getEventsCount($startDate: String!, $related: [QueryArgument]) {\n count: solspace_calendar {\n events(relatedTo: $related, loadOccurrences: true, ${dateFilter}: $startDate) {\n ... on communications_Event {\n id\n }\n ... on submission_Event {\n id\n }\n }\n }\n}\n`;\n\nconst buildEventsQuery = (dateFilter: DateFilterType = 'startsAfterOrAt') => `\nquery getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $offset: Int) {\n entries: solspace_calendar {\n events(\n relatedTo: $related\n loadOccurrences: true\n ${dateFilter}: $startDate\n limit: $limit\n offset: $offset\n ) {\n ... on communications_Event {\n id\n title\n url\n startDayOfWeek: startDate @formatDateTime(format: \"D\")\n startMonth: startDate @formatDateTime(format: \"M\")\n startDay: startDate @formatDateTime(format: \"d\")\n startStamp: startDate @formatDateTime(format: \"Y-m-d\")\n startTime: startDate @formatDateTime(format: \"g:ia\")\n endDayOfWeek: endDate @formatDateTime(format: \"D\")\n endMonth: endDate @formatDateTime(format: \"M\")\n endDay: endDate @formatDateTime(format: \"d\")\n endTime: endDate @formatDateTime(format: \"g:ia\")\n allDay\n desciption: commonRichText\n summary: commonRichTextTwo\n image: commonAssetHeroImageSingle {\n title\n commonPlainTextTwo: alt\n url\n }\n location: categoriesCampusBuildingSingle {\n title\n }\n link: commonEntriesLinkSingle {\n ... on links_links_Entry {\n type: linksDropdownSelector\n externalUrl: commonPlainTextThree\n altTitle: commonPlainTextTwo\n title\n internalLinks: calendarEntriesEvent {\n id\n url\n }\n }\n }\n }\n ... on submission_Event {\n id\n title\n url\n startDayOfWeek: startDate @formatDateTime(format: \"D\")\n startMonth: startDate @formatDateTime(format: \"M\")\n startDay: startDate @formatDateTime(format: \"d\")\n startStamp: startDate @formatDateTime(format: \"Y-m-d\")\n startTime: startDate @formatDateTime(format: \"g:ia\")\n endDayOfWeek: endDate @formatDateTime(format: \"D\")\n endMonth: endDate @formatDateTime(format: \"M\")\n endDay: endDate @formatDateTime(format: \"d\")\n endTime: endDate @formatDateTime(format: \"g:ia\")\n allDay\n desciption: commonRichText\n summary: commonRichTextTwo\n image: commonAssetHeroImageSingle {\n title\n commonPlainTextTwo: alt\n url\n }\n location: categoriesCampusBuildingSingle {\n title\n }\n link: commonEntriesLinkSingle {\n ... on links_links_Entry {\n type: linksDropdownSelector\n externalUrl: commonPlainTextThree\n altTitle: commonPlainTextTwo\n title\n internalLinks: calendarEntriesEvent {\n id\n url\n }\n }\n }\n }\n }\n }\n}\n`;\n\nexport const EVENTS_COUNT_QUERY = buildEventsCountQuery();\nexport const EVENTS_COUNT_RANGE_QUERY = buildEventsCountQuery('rangeStart');\n\nexport const EVENTS_QUERY = buildEventsQuery();\nexport const EVENTS_RANGE_QUERY = buildEventsQuery('rangeStart');\n"],"names":[],"mappings":";;AAEA,MAAM,wBAAwB,CAC5B,aAA6B,sBAC1B;AAAA;AAAA;AAAA,yDAGoD,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYnE,MAAM,mBAAmB,CAAC,aAA6B,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMrE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmFX,MAAM,qBAAqB,sBAAA;AAC3B,MAAM,2BAA2B,sBAAsB,YAAY;AAEnE,MAAM,eAAe,iBAAA;AACrB,MAAM,qBAAqB,iBAAiB,YAAY;;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const
|
|
1
|
+
const buildEventsCountQuery = (dateFilter = "startsAfterOrAt") => `
|
|
2
2
|
query getEventsCount($startDate: String!, $related: [QueryArgument]) {
|
|
3
3
|
count: solspace_calendar {
|
|
4
|
-
events(relatedTo: $related, loadOccurrences: true,
|
|
4
|
+
events(relatedTo: $related, loadOccurrences: true, ${dateFilter}: $startDate) {
|
|
5
5
|
... on communications_Event {
|
|
6
6
|
id
|
|
7
7
|
}
|
|
@@ -12,13 +12,13 @@ query getEventsCount($startDate: String!, $related: [QueryArgument]) {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
`;
|
|
15
|
-
const
|
|
15
|
+
const buildEventsQuery = (dateFilter = "startsAfterOrAt") => `
|
|
16
16
|
query getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $offset: Int) {
|
|
17
17
|
entries: solspace_calendar {
|
|
18
18
|
events(
|
|
19
19
|
relatedTo: $related
|
|
20
20
|
loadOccurrences: true
|
|
21
|
-
|
|
21
|
+
${dateFilter}: $startDate
|
|
22
22
|
limit: $limit
|
|
23
23
|
offset: $offset
|
|
24
24
|
) {
|
|
@@ -100,8 +100,14 @@ query getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $of
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
`;
|
|
103
|
+
const EVENTS_COUNT_QUERY = buildEventsCountQuery();
|
|
104
|
+
const EVENTS_COUNT_RANGE_QUERY = buildEventsCountQuery("rangeStart");
|
|
105
|
+
const EVENTS_QUERY = buildEventsQuery();
|
|
106
|
+
const EVENTS_RANGE_QUERY = buildEventsQuery("rangeStart");
|
|
103
107
|
export {
|
|
104
108
|
EVENTS_COUNT_QUERY,
|
|
105
|
-
|
|
109
|
+
EVENTS_COUNT_RANGE_QUERY,
|
|
110
|
+
EVENTS_QUERY,
|
|
111
|
+
EVENTS_RANGE_QUERY
|
|
106
112
|
};
|
|
107
113
|
//# sourceMappingURL=queries.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.mjs","sources":["../../../../source/composite/events/common/queries.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"queries.mjs","sources":["../../../../source/composite/events/common/queries.ts"],"sourcesContent":["type DateFilterType = 'startsAfterOrAt' | 'rangeStart';\n\nconst buildEventsCountQuery = (\n dateFilter: DateFilterType = 'startsAfterOrAt',\n) => `\nquery getEventsCount($startDate: String!, $related: [QueryArgument]) {\n count: solspace_calendar {\n events(relatedTo: $related, loadOccurrences: true, ${dateFilter}: $startDate) {\n ... on communications_Event {\n id\n }\n ... on submission_Event {\n id\n }\n }\n }\n}\n`;\n\nconst buildEventsQuery = (dateFilter: DateFilterType = 'startsAfterOrAt') => `\nquery getEvents($startDate: String!, $related: [QueryArgument], $limit: Int, $offset: Int) {\n entries: solspace_calendar {\n events(\n relatedTo: $related\n loadOccurrences: true\n ${dateFilter}: $startDate\n limit: $limit\n offset: $offset\n ) {\n ... on communications_Event {\n id\n title\n url\n startDayOfWeek: startDate @formatDateTime(format: \"D\")\n startMonth: startDate @formatDateTime(format: \"M\")\n startDay: startDate @formatDateTime(format: \"d\")\n startStamp: startDate @formatDateTime(format: \"Y-m-d\")\n startTime: startDate @formatDateTime(format: \"g:ia\")\n endDayOfWeek: endDate @formatDateTime(format: \"D\")\n endMonth: endDate @formatDateTime(format: \"M\")\n endDay: endDate @formatDateTime(format: \"d\")\n endTime: endDate @formatDateTime(format: \"g:ia\")\n allDay\n desciption: commonRichText\n summary: commonRichTextTwo\n image: commonAssetHeroImageSingle {\n title\n commonPlainTextTwo: alt\n url\n }\n location: categoriesCampusBuildingSingle {\n title\n }\n link: commonEntriesLinkSingle {\n ... on links_links_Entry {\n type: linksDropdownSelector\n externalUrl: commonPlainTextThree\n altTitle: commonPlainTextTwo\n title\n internalLinks: calendarEntriesEvent {\n id\n url\n }\n }\n }\n }\n ... on submission_Event {\n id\n title\n url\n startDayOfWeek: startDate @formatDateTime(format: \"D\")\n startMonth: startDate @formatDateTime(format: \"M\")\n startDay: startDate @formatDateTime(format: \"d\")\n startStamp: startDate @formatDateTime(format: \"Y-m-d\")\n startTime: startDate @formatDateTime(format: \"g:ia\")\n endDayOfWeek: endDate @formatDateTime(format: \"D\")\n endMonth: endDate @formatDateTime(format: \"M\")\n endDay: endDate @formatDateTime(format: \"d\")\n endTime: endDate @formatDateTime(format: \"g:ia\")\n allDay\n desciption: commonRichText\n summary: commonRichTextTwo\n image: commonAssetHeroImageSingle {\n title\n commonPlainTextTwo: alt\n url\n }\n location: categoriesCampusBuildingSingle {\n title\n }\n link: commonEntriesLinkSingle {\n ... on links_links_Entry {\n type: linksDropdownSelector\n externalUrl: commonPlainTextThree\n altTitle: commonPlainTextTwo\n title\n internalLinks: calendarEntriesEvent {\n id\n url\n }\n }\n }\n }\n }\n }\n}\n`;\n\nexport const EVENTS_COUNT_QUERY = buildEventsCountQuery();\nexport const EVENTS_COUNT_RANGE_QUERY = buildEventsCountQuery('rangeStart');\n\nexport const EVENTS_QUERY = buildEventsQuery();\nexport const EVENTS_RANGE_QUERY = buildEventsQuery('rangeStart');\n"],"names":[],"mappings":"AAEA,MAAM,wBAAwB,CAC5B,aAA6B,sBAC1B;AAAA;AAAA;AAAA,yDAGoD,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYnE,MAAM,mBAAmB,CAAC,aAA6B,sBAAsB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAMrE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmFX,MAAM,qBAAqB,sBAAA;AAC3B,MAAM,2BAA2B,sBAAsB,YAAY;AAEnE,MAAM,eAAe,iBAAA;AACrB,MAAM,qBAAqB,iBAAiB,YAAY;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grouped.d.ts","sourceRoot":"","sources":["../../../source/composite/events/grouped.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"grouped.d.ts","sourceRoot":"","sources":["../../../source/composite/events/grouped.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,SAAS,EAAoC,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;yBAwLjC,OAAO,SAAS,KAAG,YAAY;AAA/C,wBAiKO"}
|
|
@@ -9,6 +9,7 @@ require("@universityofmaryland/web-elements-library/atomic");
|
|
|
9
9
|
const fetch = require("./common/fetch.js");
|
|
10
10
|
const display = require("./common/display.js");
|
|
11
11
|
const data = require("./common/data.js");
|
|
12
|
+
const queries = require("./common/queries.js");
|
|
12
13
|
function _interopNamespaceDefault(e) {
|
|
13
14
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
14
15
|
if (e) {
|
|
@@ -77,18 +78,81 @@ const getDateBanner = (dateStamp) => {
|
|
|
77
78
|
];
|
|
78
79
|
return `${days[eventDate.getDay()]}, ${months[eventDate.getMonth()]} ${eventDate.getDate()}`;
|
|
79
80
|
};
|
|
81
|
+
const MONTH_MAP = {
|
|
82
|
+
Jan: "01",
|
|
83
|
+
Feb: "02",
|
|
84
|
+
Mar: "03",
|
|
85
|
+
Apr: "04",
|
|
86
|
+
May: "05",
|
|
87
|
+
Jun: "06",
|
|
88
|
+
Jul: "07",
|
|
89
|
+
Aug: "08",
|
|
90
|
+
Sep: "09",
|
|
91
|
+
Oct: "10",
|
|
92
|
+
Nov: "11",
|
|
93
|
+
Dec: "12"
|
|
94
|
+
};
|
|
95
|
+
const parseLocalDate = (dateString) => {
|
|
96
|
+
const parts = dateString.split("-");
|
|
97
|
+
const date = new Date(
|
|
98
|
+
parseInt(parts[0], 10),
|
|
99
|
+
parseInt(parts[1], 10) - 1,
|
|
100
|
+
parseInt(parts[2], 10)
|
|
101
|
+
);
|
|
102
|
+
date.setHours(0, 0, 0, 0);
|
|
103
|
+
return date;
|
|
104
|
+
};
|
|
105
|
+
const getEventStartDate = (event) => {
|
|
106
|
+
return parseLocalDate(event.startStamp.split("T")[0]);
|
|
107
|
+
};
|
|
108
|
+
const isMultiDayEvent = (event) => {
|
|
109
|
+
const startParts = event.startStamp.split("T")[0].split("-");
|
|
110
|
+
const startMonth = startParts[1];
|
|
111
|
+
const startDay = startParts[2];
|
|
112
|
+
const endMonth = MONTH_MAP[event.endMonth];
|
|
113
|
+
const endDay = event.endDay.padStart(2, "0");
|
|
114
|
+
return !(startMonth === endMonth && startDay === endDay);
|
|
115
|
+
};
|
|
116
|
+
const eventStartsOnDate = (event, targetDate) => {
|
|
117
|
+
const eventStartDate = getEventStartDate(event);
|
|
118
|
+
return eventStartDate.getTime() === targetDate.getTime();
|
|
119
|
+
};
|
|
120
|
+
const getEventPriority = (event, groupDate) => {
|
|
121
|
+
const isMulti = isMultiDayEvent(event);
|
|
122
|
+
const startsOnDate = eventStartsOnDate(event, groupDate);
|
|
123
|
+
if (isMulti && startsOnDate) return 1;
|
|
124
|
+
if (!isMulti) return 2;
|
|
125
|
+
return 3;
|
|
126
|
+
};
|
|
127
|
+
const sortEventsByPriority = (events, groupDate) => {
|
|
128
|
+
return [...events].sort((a, b) => {
|
|
129
|
+
const aPriority = getEventPriority(a, groupDate);
|
|
130
|
+
const bPriority = getEventPriority(b, groupDate);
|
|
131
|
+
return aPriority - bPriority;
|
|
132
|
+
});
|
|
133
|
+
};
|
|
80
134
|
const groupEventsByDate = (events) => {
|
|
135
|
+
const currentDate = /* @__PURE__ */ new Date();
|
|
136
|
+
currentDate.setHours(0, 0, 0, 0);
|
|
81
137
|
const grouped2 = events.reduce((acc, event) => {
|
|
82
|
-
const
|
|
138
|
+
const eventDate = getEventStartDate(event);
|
|
139
|
+
const dateKey = eventDate < currentDate ? currentDate.toISOString().split("T")[0] : event.startStamp;
|
|
83
140
|
if (!acc[dateKey]) {
|
|
84
141
|
acc[dateKey] = {
|
|
85
|
-
date: getDateBanner(
|
|
142
|
+
date: getDateBanner(dateKey),
|
|
86
143
|
events: []
|
|
87
144
|
};
|
|
88
145
|
}
|
|
89
146
|
acc[dateKey].events.push(event);
|
|
90
147
|
return acc;
|
|
91
148
|
}, {});
|
|
149
|
+
Object.keys(grouped2).forEach((dateKey) => {
|
|
150
|
+
const groupDate = parseLocalDate(dateKey);
|
|
151
|
+
grouped2[dateKey].events = sortEventsByPriority(
|
|
152
|
+
grouped2[dateKey].events,
|
|
153
|
+
groupDate
|
|
154
|
+
);
|
|
155
|
+
});
|
|
92
156
|
return Object.values(grouped2).sort((a, b) => {
|
|
93
157
|
const dateA = new Date(
|
|
94
158
|
Object.keys(grouped2).find((key) => grouped2[key] === a) || ""
|
|
@@ -165,7 +229,7 @@ const grouped = (props) => (() => {
|
|
|
165
229
|
dateSign: webElementsLibrary.Atomic.events.sign({
|
|
166
230
|
...entry,
|
|
167
231
|
isThemeDark,
|
|
168
|
-
isLargeSize:
|
|
232
|
+
isLargeSize: true
|
|
169
233
|
}),
|
|
170
234
|
image: asset.standard({
|
|
171
235
|
images: entry.image,
|
|
@@ -182,12 +246,14 @@ const grouped = (props) => (() => {
|
|
|
182
246
|
elementStyles: {
|
|
183
247
|
element: {
|
|
184
248
|
[` > *:not(:last-child)`]: {
|
|
185
|
-
paddingBottom: Styles__namespace.token.spacing.
|
|
186
|
-
marginBottom: Styles__namespace.token.spacing.
|
|
249
|
+
paddingBottom: Styles__namespace.token.spacing.md,
|
|
250
|
+
marginBottom: Styles__namespace.token.spacing.md,
|
|
251
|
+
borderBottom: `1px solid ${isThemeDark ? Styles__namespace.token.color.gray.dark : Styles__namespace.token.color.gray.light}`
|
|
187
252
|
},
|
|
188
253
|
[`+ .umd-feed-events-grouped-entries`]: {
|
|
189
|
-
paddingTop: Styles__namespace.token.spacing.
|
|
190
|
-
marginTop: Styles__namespace.token.spacing.
|
|
254
|
+
paddingTop: Styles__namespace.token.spacing.md,
|
|
255
|
+
marginTop: Styles__namespace.token.spacing.md,
|
|
256
|
+
borderTop: `1px solid ${isThemeDark ? Styles__namespace.token.color.gray.dark : Styles__namespace.token.color.gray.light}`
|
|
191
257
|
}
|
|
192
258
|
}
|
|
193
259
|
}
|
|
@@ -200,7 +266,8 @@ const grouped = (props) => (() => {
|
|
|
200
266
|
...props,
|
|
201
267
|
...helperFunctions,
|
|
202
268
|
displayResults,
|
|
203
|
-
entries
|
|
269
|
+
entries,
|
|
270
|
+
query: queries.EVENTS_RANGE_QUERY
|
|
204
271
|
});
|
|
205
272
|
helperFunctions.setOffset = originalSetOffset;
|
|
206
273
|
if (shadowRoot) {
|
|
@@ -217,7 +284,9 @@ const grouped = (props) => (() => {
|
|
|
217
284
|
displayResults,
|
|
218
285
|
displayResultStart: display.resultStart,
|
|
219
286
|
displayNoResults: display.noResults,
|
|
220
|
-
layoutElement: groupLayout()
|
|
287
|
+
layoutElement: groupLayout(),
|
|
288
|
+
query: queries.EVENTS_RANGE_QUERY,
|
|
289
|
+
countQuery: queries.EVENTS_COUNT_RANGE_QUERY
|
|
221
290
|
});
|
|
222
291
|
return {
|
|
223
292
|
element: container,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grouped.js","sources":["../../../source/composite/events/grouped.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport {\n Atomic,\n Composite,\n Model,\n} from '@universityofmaryland/web-elements-library';\nimport * as feedElements from 'elements';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './common/fetch';\nimport * as feedDisplay from './common/display';\nimport * as dataComposed from './common/data';\nimport { type ListProps, type FeedDisplay, type EventType } from './_types';\nimport { type ElementModel } from '../../_types';\n\ninterface GroupedEvent {\n date: string;\n events: EventType[];\n}\n\nconst getDateBanner = (dateStamp: string): string => {\n // Parse the date string more reliably\n // Handle both \"YYYY-MM-DD\" and ISO format strings\n const dateParts = dateStamp.split('T')[0].split('-');\n const year = parseInt(dateParts[0], 10);\n const month = parseInt(dateParts[1], 10) - 1; // Month is 0-indexed\n const day = parseInt(dateParts[2], 10);\n\n // Create dates using local timezone to avoid timezone shifts\n const eventDate = new Date(year, month, day);\n const currentDate = new Date();\n currentDate.setHours(0, 0, 0, 0);\n\n const weekFromNow = new Date();\n weekFromNow.setDate(currentDate.getDate() + 7);\n weekFromNow.setHours(0, 0, 0, 0);\n\n // Check if it's today\n if (\n eventDate.getFullYear() === currentDate.getFullYear() &&\n eventDate.getMonth() === currentDate.getMonth() &&\n eventDate.getDate() === currentDate.getDate()\n ) {\n return 'Today';\n }\n\n // Check if it's within the next 7 days\n if (\n eventDate.getTime() > currentDate.getTime() &&\n eventDate.getTime() <= weekFromNow.getTime()\n ) {\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n return days[eventDate.getDay()];\n }\n\n // Otherwise return day of week, month and day\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n return `${days[eventDate.getDay()]}, ${\n months[eventDate.getMonth()]\n } ${eventDate.getDate()}`;\n};\n\nconst groupEventsByDate = (events: EventType[]): GroupedEvent[] => {\n const grouped = events.reduce((acc, event) => {\n const dateKey = event.startStamp;\n if (!acc[dateKey]) {\n acc[dateKey] = {\n date: getDateBanner(event.startStamp),\n events: [],\n };\n }\n acc[dateKey].events.push(event);\n return acc;\n }, {} as Record<string, GroupedEvent>);\n\n return Object.values(grouped).sort((a, b) => {\n const dateA = new Date(\n Object.keys(grouped).find((key) => grouped[key] === a) || '',\n );\n const dateB = new Date(\n Object.keys(grouped).find((key) => grouped[key] === b) || '',\n );\n return dateA.getTime() - dateB.getTime();\n });\n};\n\nexport default (props: ListProps): ElementModel =>\n (() => {\n const { isThemeDark } = props;\n const loader = feedMacros.loader.create({ isThemeDark });\n const container = document.createElement('div');\n const setTotalEntries = (count: number) => (totalEntries = count);\n const setOffset = (count: number) => (offset = offset + count);\n const setStyles = (additonalStyles: string) => (styles += additonalStyles);\n const getContainer = () => container;\n const getTotalEntries = () => totalEntries;\n const getOffset = () => offset;\n const getStyles = () => styles;\n const getShadowRoot = () => shadowRoot;\n let totalEntries = 0;\n let offset = 0;\n let styles = `\n ${loader.styles}\n `;\n let shadowRoot: ShadowRoot | null = null;\n let lastDateHeadline: string | null = null;\n\n const helperFunctions = {\n setTotalEntries,\n setOffset,\n setStyles,\n getContainer,\n getOffset,\n getTotalEntries,\n getStyles,\n getShadowRoot,\n };\n\n const callback = (shadow: ShadowRoot) => {\n shadowRoot = shadow;\n };\n\n const groupLayout = (): { element: HTMLElement; styles: string } => {\n return Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped',\n elementStyles: {\n element: {},\n },\n });\n };\n\n const displayResults = async ({ feedData }: FeedDisplay) => {\n const groupedEvents = groupEventsByDate(feedData);\n const entries: { element: HTMLElement; styles: string }[] = [];\n let actualEventCount = 0;\n\n groupedEvents.forEach((group) => {\n if (group.date !== lastDateHeadline) {\n const dateHeadline = document.createElement('p');\n dateHeadline.textContent = group.date;\n\n entries.push(\n Model.ElementModel.text.ribbon({\n element: dateHeadline,\n elementStyles: {\n element: {\n margin: `${Styles.token.spacing.lg} 0`,\n },\n },\n }),\n );\n\n lastDateHeadline = group.date;\n }\n\n const dateEntries = group.events.map((entry) =>\n Composite.card.list({\n ...dataComposed.display({ entry, isThemeDark }),\n dateSign: Atomic.events.sign({\n ...entry,\n isThemeDark,\n isLargeSize: false,\n }),\n image: feedElements.asset.standard({\n images: entry.image,\n url: entry.url,\n }),\n isAligned: false,\n }),\n );\n\n actualEventCount += group.events.length;\n\n entries.push(\n Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped-entries',\n children: [...dateEntries],\n elementStyles: {\n element: {\n [` > *:not(:last-child)`]: {\n paddingBottom: Styles.token.spacing.lg,\n marginBottom: Styles.token.spacing.lg,\n },\n\n [`+ .umd-feed-events-grouped-entries`]: {\n paddingTop: Styles.token.spacing.lg,\n marginTop: Styles.token.spacing.lg,\n },\n },\n },\n }),\n );\n });\n\n // Override the offset with actual event count to fix lazy load\n const originalSetOffset = helperFunctions.setOffset;\n helperFunctions.setOffset = () => originalSetOffset(actualEventCount);\n\n await feedDisplay.resultLoad({\n ...props,\n ...helperFunctions,\n displayResults,\n entries,\n });\n\n // Restore original setOffset\n helperFunctions.setOffset = originalSetOffset;\n\n if (shadowRoot) {\n feedDisplay.setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n };\n\n container.appendChild(loader.element);\n\n feedFetch.start({\n ...props,\n ...helperFunctions,\n displayResults,\n displayResultStart: feedDisplay.resultStart,\n displayNoResults: feedDisplay.noResults,\n layoutElement: groupLayout(),\n });\n\n return {\n element: container,\n styles,\n events: {\n callback,\n },\n };\n })();\n"],"names":["days","grouped","loader","feedMacros.loader","Model","Styles","Composite","dataComposed.display","Atomic","feedElements.asset.standard","feedDisplay.resultLoad","feedDisplay.setShadowStyles","feedFetch.start","feedDisplay.resultStart","feedDisplay.noResults"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grouped.js","sources":["../../../source/composite/events/grouped.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport {\n Atomic,\n Composite,\n Model,\n} from '@universityofmaryland/web-elements-library';\nimport * as feedElements from 'elements';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './common/fetch';\nimport * as feedDisplay from './common/display';\nimport * as dataComposed from './common/data';\nimport { EVENTS_RANGE_QUERY, EVENTS_COUNT_RANGE_QUERY } from './common/queries';\nimport { type ListProps, type FeedDisplay, type EventType } from './_types';\nimport { type ElementModel } from '../../_types';\n\ninterface GroupedEvent {\n date: string;\n events: EventType[];\n}\n\nconst getDateBanner = (dateStamp: string): string => {\n // Parse the date string more reliably\n // Handle both \"YYYY-MM-DD\" and ISO format strings\n const dateParts = dateStamp.split('T')[0].split('-');\n const year = parseInt(dateParts[0], 10);\n const month = parseInt(dateParts[1], 10) - 1; // Month is 0-indexed\n const day = parseInt(dateParts[2], 10);\n\n // Create dates using local timezone to avoid timezone shifts\n const eventDate = new Date(year, month, day);\n const currentDate = new Date();\n currentDate.setHours(0, 0, 0, 0);\n\n const weekFromNow = new Date();\n weekFromNow.setDate(currentDate.getDate() + 7);\n weekFromNow.setHours(0, 0, 0, 0);\n\n // Check if it's today\n if (\n eventDate.getFullYear() === currentDate.getFullYear() &&\n eventDate.getMonth() === currentDate.getMonth() &&\n eventDate.getDate() === currentDate.getDate()\n ) {\n return 'Today';\n }\n\n // Check if it's within the next 7 days\n if (\n eventDate.getTime() > currentDate.getTime() &&\n eventDate.getTime() <= weekFromNow.getTime()\n ) {\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n return days[eventDate.getDay()];\n }\n\n // Otherwise return day of week, month and day\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n return `${days[eventDate.getDay()]}, ${\n months[eventDate.getMonth()]\n } ${eventDate.getDate()}`;\n};\n\nconst MONTH_MAP: Record<string, string> = {\n Jan: '01',\n Feb: '02',\n Mar: '03',\n Apr: '04',\n May: '05',\n Jun: '06',\n Jul: '07',\n Aug: '08',\n Sep: '09',\n Oct: '10',\n Nov: '11',\n Dec: '12',\n};\n\nconst parseLocalDate = (dateString: string): Date => {\n const parts = dateString.split('-');\n const date = new Date(\n parseInt(parts[0], 10),\n parseInt(parts[1], 10) - 1,\n parseInt(parts[2], 10),\n );\n date.setHours(0, 0, 0, 0);\n return date;\n};\n\nconst getEventStartDate = (event: EventType): Date => {\n return parseLocalDate(event.startStamp.split('T')[0]);\n};\n\nconst isMultiDayEvent = (event: EventType): boolean => {\n const startParts = event.startStamp.split('T')[0].split('-');\n const startMonth = startParts[1];\n const startDay = startParts[2];\n const endMonth = MONTH_MAP[event.endMonth];\n const endDay = event.endDay.padStart(2, '0');\n\n return !(startMonth === endMonth && startDay === endDay);\n};\n\nconst eventStartsOnDate = (event: EventType, targetDate: Date): boolean => {\n const eventStartDate = getEventStartDate(event);\n return eventStartDate.getTime() === targetDate.getTime();\n};\n\nconst getEventPriority = (event: EventType, groupDate: Date): number => {\n const isMulti = isMultiDayEvent(event);\n const startsOnDate = eventStartsOnDate(event, groupDate);\n\n if (isMulti && startsOnDate) return 1;\n if (!isMulti) return 2;\n return 3;\n};\n\nconst sortEventsByPriority = (\n events: EventType[],\n groupDate: Date,\n): EventType[] => {\n return [...events].sort((a, b) => {\n const aPriority = getEventPriority(a, groupDate);\n const bPriority = getEventPriority(b, groupDate);\n return aPriority - bPriority;\n });\n};\n\nconst groupEventsByDate = (events: EventType[]): GroupedEvent[] => {\n const currentDate = new Date();\n currentDate.setHours(0, 0, 0, 0);\n\n const grouped = events.reduce((acc, event) => {\n const eventDate = getEventStartDate(event);\n const dateKey =\n eventDate < currentDate\n ? currentDate.toISOString().split('T')[0]\n : event.startStamp;\n\n if (!acc[dateKey]) {\n acc[dateKey] = {\n date: getDateBanner(dateKey),\n events: [],\n };\n }\n acc[dateKey].events.push(event);\n return acc;\n }, {} as Record<string, GroupedEvent>);\n\n Object.keys(grouped).forEach((dateKey) => {\n const groupDate = parseLocalDate(dateKey);\n grouped[dateKey].events = sortEventsByPriority(\n grouped[dateKey].events,\n groupDate,\n );\n });\n\n return Object.values(grouped).sort((a, b) => {\n const dateA = new Date(\n Object.keys(grouped).find((key) => grouped[key] === a) || '',\n );\n const dateB = new Date(\n Object.keys(grouped).find((key) => grouped[key] === b) || '',\n );\n return dateA.getTime() - dateB.getTime();\n });\n};\n\nexport default (props: ListProps): ElementModel =>\n (() => {\n const { isThemeDark } = props;\n const loader = feedMacros.loader.create({ isThemeDark });\n const container = document.createElement('div');\n const setTotalEntries = (count: number) => (totalEntries = count);\n const setOffset = (count: number) => (offset = offset + count);\n const setStyles = (additonalStyles: string) => (styles += additonalStyles);\n const getContainer = () => container;\n const getTotalEntries = () => totalEntries;\n const getOffset = () => offset;\n const getStyles = () => styles;\n const getShadowRoot = () => shadowRoot;\n let totalEntries = 0;\n let offset = 0;\n let styles = `\n ${loader.styles}\n `;\n let shadowRoot: ShadowRoot | null = null;\n let lastDateHeadline: string | null = null;\n\n const helperFunctions = {\n setTotalEntries,\n setOffset,\n setStyles,\n getContainer,\n getOffset,\n getTotalEntries,\n getStyles,\n getShadowRoot,\n };\n\n const callback = (shadow: ShadowRoot) => {\n shadowRoot = shadow;\n };\n\n const groupLayout = (): { element: HTMLElement; styles: string } => {\n return Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped',\n elementStyles: {\n element: {},\n },\n });\n };\n\n const displayResults = async ({ feedData }: FeedDisplay) => {\n const groupedEvents = groupEventsByDate(feedData);\n const entries: { element: HTMLElement; styles: string }[] = [];\n let actualEventCount = 0;\n\n groupedEvents.forEach((group) => {\n if (group.date !== lastDateHeadline) {\n const dateHeadline = document.createElement('p');\n dateHeadline.textContent = group.date;\n\n entries.push(\n Model.ElementModel.text.ribbon({\n element: dateHeadline,\n elementStyles: {\n element: {\n margin: `${Styles.token.spacing.lg} 0`,\n },\n },\n }),\n );\n\n lastDateHeadline = group.date;\n }\n\n const dateEntries = group.events.map((entry) =>\n Composite.card.list({\n ...dataComposed.display({ entry, isThemeDark }),\n dateSign: Atomic.events.sign({\n ...entry,\n isThemeDark,\n isLargeSize: true,\n }),\n image: feedElements.asset.standard({\n images: entry.image,\n url: entry.url,\n }),\n isAligned: false,\n }),\n );\n\n actualEventCount += group.events.length;\n\n entries.push(\n Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped-entries',\n children: [...dateEntries],\n elementStyles: {\n element: {\n [` > *:not(:last-child)`]: {\n paddingBottom: Styles.token.spacing.md,\n marginBottom: Styles.token.spacing.md,\n borderBottom: `1px solid ${\n isThemeDark\n ? Styles.token.color.gray.dark\n : Styles.token.color.gray.light\n }`,\n },\n\n [`+ .umd-feed-events-grouped-entries`]: {\n paddingTop: Styles.token.spacing.md,\n marginTop: Styles.token.spacing.md,\n borderTop: `1px solid ${\n isThemeDark\n ? Styles.token.color.gray.dark\n : Styles.token.color.gray.light\n }`,\n },\n },\n },\n }),\n );\n });\n\n // Override the offset with actual event count to fix lazy load\n const originalSetOffset = helperFunctions.setOffset;\n helperFunctions.setOffset = () => originalSetOffset(actualEventCount);\n\n await feedDisplay.resultLoad({\n ...props,\n ...helperFunctions,\n displayResults,\n entries,\n query: EVENTS_RANGE_QUERY,\n });\n\n // Restore original setOffset\n helperFunctions.setOffset = originalSetOffset;\n\n if (shadowRoot) {\n feedDisplay.setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n };\n\n container.appendChild(loader.element);\n\n feedFetch.start({\n ...props,\n ...helperFunctions,\n displayResults,\n displayResultStart: feedDisplay.resultStart,\n displayNoResults: feedDisplay.noResults,\n layoutElement: groupLayout(),\n query: EVENTS_RANGE_QUERY,\n countQuery: EVENTS_COUNT_RANGE_QUERY,\n });\n\n return {\n element: container,\n styles,\n events: {\n callback,\n },\n };\n })();\n"],"names":["days","grouped","loader","feedMacros.loader","Model","Styles","Composite","dataComposed.display","Atomic","feedElements.asset.standard","feedDisplay.resultLoad","EVENTS_RANGE_QUERY","feedDisplay.setShadowStyles","feedFetch.start","feedDisplay.resultStart","feedDisplay.noResults","EVENTS_COUNT_RANGE_QUERY"],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ import "@universityofmaryland/web-elements-library/atomic";
|
|
|
8
8
|
import { start } from "./common/fetch.mjs";
|
|
9
9
|
import { noResults, resultStart, resultLoad, setShadowStyles } from "./common/display.mjs";
|
|
10
10
|
import { display } from "./common/data.mjs";
|
|
11
|
+
import { EVENTS_COUNT_RANGE_QUERY, EVENTS_RANGE_QUERY } from "./common/queries.mjs";
|
|
11
12
|
const getDateBanner = (dateStamp) => {
|
|
12
13
|
const dateParts = dateStamp.split("T")[0].split("-");
|
|
13
14
|
const year = parseInt(dateParts[0], 10);
|
|
@@ -59,18 +60,81 @@ const getDateBanner = (dateStamp) => {
|
|
|
59
60
|
];
|
|
60
61
|
return `${days[eventDate.getDay()]}, ${months[eventDate.getMonth()]} ${eventDate.getDate()}`;
|
|
61
62
|
};
|
|
63
|
+
const MONTH_MAP = {
|
|
64
|
+
Jan: "01",
|
|
65
|
+
Feb: "02",
|
|
66
|
+
Mar: "03",
|
|
67
|
+
Apr: "04",
|
|
68
|
+
May: "05",
|
|
69
|
+
Jun: "06",
|
|
70
|
+
Jul: "07",
|
|
71
|
+
Aug: "08",
|
|
72
|
+
Sep: "09",
|
|
73
|
+
Oct: "10",
|
|
74
|
+
Nov: "11",
|
|
75
|
+
Dec: "12"
|
|
76
|
+
};
|
|
77
|
+
const parseLocalDate = (dateString) => {
|
|
78
|
+
const parts = dateString.split("-");
|
|
79
|
+
const date = new Date(
|
|
80
|
+
parseInt(parts[0], 10),
|
|
81
|
+
parseInt(parts[1], 10) - 1,
|
|
82
|
+
parseInt(parts[2], 10)
|
|
83
|
+
);
|
|
84
|
+
date.setHours(0, 0, 0, 0);
|
|
85
|
+
return date;
|
|
86
|
+
};
|
|
87
|
+
const getEventStartDate = (event) => {
|
|
88
|
+
return parseLocalDate(event.startStamp.split("T")[0]);
|
|
89
|
+
};
|
|
90
|
+
const isMultiDayEvent = (event) => {
|
|
91
|
+
const startParts = event.startStamp.split("T")[0].split("-");
|
|
92
|
+
const startMonth = startParts[1];
|
|
93
|
+
const startDay = startParts[2];
|
|
94
|
+
const endMonth = MONTH_MAP[event.endMonth];
|
|
95
|
+
const endDay = event.endDay.padStart(2, "0");
|
|
96
|
+
return !(startMonth === endMonth && startDay === endDay);
|
|
97
|
+
};
|
|
98
|
+
const eventStartsOnDate = (event, targetDate) => {
|
|
99
|
+
const eventStartDate = getEventStartDate(event);
|
|
100
|
+
return eventStartDate.getTime() === targetDate.getTime();
|
|
101
|
+
};
|
|
102
|
+
const getEventPriority = (event, groupDate) => {
|
|
103
|
+
const isMulti = isMultiDayEvent(event);
|
|
104
|
+
const startsOnDate = eventStartsOnDate(event, groupDate);
|
|
105
|
+
if (isMulti && startsOnDate) return 1;
|
|
106
|
+
if (!isMulti) return 2;
|
|
107
|
+
return 3;
|
|
108
|
+
};
|
|
109
|
+
const sortEventsByPriority = (events, groupDate) => {
|
|
110
|
+
return [...events].sort((a, b) => {
|
|
111
|
+
const aPriority = getEventPriority(a, groupDate);
|
|
112
|
+
const bPriority = getEventPriority(b, groupDate);
|
|
113
|
+
return aPriority - bPriority;
|
|
114
|
+
});
|
|
115
|
+
};
|
|
62
116
|
const groupEventsByDate = (events) => {
|
|
117
|
+
const currentDate = /* @__PURE__ */ new Date();
|
|
118
|
+
currentDate.setHours(0, 0, 0, 0);
|
|
63
119
|
const grouped2 = events.reduce((acc, event) => {
|
|
64
|
-
const
|
|
120
|
+
const eventDate = getEventStartDate(event);
|
|
121
|
+
const dateKey = eventDate < currentDate ? currentDate.toISOString().split("T")[0] : event.startStamp;
|
|
65
122
|
if (!acc[dateKey]) {
|
|
66
123
|
acc[dateKey] = {
|
|
67
|
-
date: getDateBanner(
|
|
124
|
+
date: getDateBanner(dateKey),
|
|
68
125
|
events: []
|
|
69
126
|
};
|
|
70
127
|
}
|
|
71
128
|
acc[dateKey].events.push(event);
|
|
72
129
|
return acc;
|
|
73
130
|
}, {});
|
|
131
|
+
Object.keys(grouped2).forEach((dateKey) => {
|
|
132
|
+
const groupDate = parseLocalDate(dateKey);
|
|
133
|
+
grouped2[dateKey].events = sortEventsByPriority(
|
|
134
|
+
grouped2[dateKey].events,
|
|
135
|
+
groupDate
|
|
136
|
+
);
|
|
137
|
+
});
|
|
74
138
|
return Object.values(grouped2).sort((a, b) => {
|
|
75
139
|
const dateA = new Date(
|
|
76
140
|
Object.keys(grouped2).find((key) => grouped2[key] === a) || ""
|
|
@@ -147,7 +211,7 @@ const grouped = (props) => (() => {
|
|
|
147
211
|
dateSign: Atomic.events.sign({
|
|
148
212
|
...entry,
|
|
149
213
|
isThemeDark,
|
|
150
|
-
isLargeSize:
|
|
214
|
+
isLargeSize: true
|
|
151
215
|
}),
|
|
152
216
|
image: standard({
|
|
153
217
|
images: entry.image,
|
|
@@ -164,12 +228,14 @@ const grouped = (props) => (() => {
|
|
|
164
228
|
elementStyles: {
|
|
165
229
|
element: {
|
|
166
230
|
[` > *:not(:last-child)`]: {
|
|
167
|
-
paddingBottom: Styles.token.spacing.
|
|
168
|
-
marginBottom: Styles.token.spacing.
|
|
231
|
+
paddingBottom: Styles.token.spacing.md,
|
|
232
|
+
marginBottom: Styles.token.spacing.md,
|
|
233
|
+
borderBottom: `1px solid ${isThemeDark ? Styles.token.color.gray.dark : Styles.token.color.gray.light}`
|
|
169
234
|
},
|
|
170
235
|
[`+ .umd-feed-events-grouped-entries`]: {
|
|
171
|
-
paddingTop: Styles.token.spacing.
|
|
172
|
-
marginTop: Styles.token.spacing.
|
|
236
|
+
paddingTop: Styles.token.spacing.md,
|
|
237
|
+
marginTop: Styles.token.spacing.md,
|
|
238
|
+
borderTop: `1px solid ${isThemeDark ? Styles.token.color.gray.dark : Styles.token.color.gray.light}`
|
|
173
239
|
}
|
|
174
240
|
}
|
|
175
241
|
}
|
|
@@ -182,7 +248,8 @@ const grouped = (props) => (() => {
|
|
|
182
248
|
...props,
|
|
183
249
|
...helperFunctions,
|
|
184
250
|
displayResults,
|
|
185
|
-
entries
|
|
251
|
+
entries,
|
|
252
|
+
query: EVENTS_RANGE_QUERY
|
|
186
253
|
});
|
|
187
254
|
helperFunctions.setOffset = originalSetOffset;
|
|
188
255
|
if (shadowRoot) {
|
|
@@ -199,7 +266,9 @@ const grouped = (props) => (() => {
|
|
|
199
266
|
displayResults,
|
|
200
267
|
displayResultStart: resultStart,
|
|
201
268
|
displayNoResults: noResults,
|
|
202
|
-
layoutElement: groupLayout()
|
|
269
|
+
layoutElement: groupLayout(),
|
|
270
|
+
query: EVENTS_RANGE_QUERY,
|
|
271
|
+
countQuery: EVENTS_COUNT_RANGE_QUERY
|
|
203
272
|
});
|
|
204
273
|
return {
|
|
205
274
|
element: container,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grouped.mjs","sources":["../../../source/composite/events/grouped.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport {\n Atomic,\n Composite,\n Model,\n} from '@universityofmaryland/web-elements-library';\nimport * as feedElements from 'elements';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './common/fetch';\nimport * as feedDisplay from './common/display';\nimport * as dataComposed from './common/data';\nimport { type ListProps, type FeedDisplay, type EventType } from './_types';\nimport { type ElementModel } from '../../_types';\n\ninterface GroupedEvent {\n date: string;\n events: EventType[];\n}\n\nconst getDateBanner = (dateStamp: string): string => {\n // Parse the date string more reliably\n // Handle both \"YYYY-MM-DD\" and ISO format strings\n const dateParts = dateStamp.split('T')[0].split('-');\n const year = parseInt(dateParts[0], 10);\n const month = parseInt(dateParts[1], 10) - 1; // Month is 0-indexed\n const day = parseInt(dateParts[2], 10);\n\n // Create dates using local timezone to avoid timezone shifts\n const eventDate = new Date(year, month, day);\n const currentDate = new Date();\n currentDate.setHours(0, 0, 0, 0);\n\n const weekFromNow = new Date();\n weekFromNow.setDate(currentDate.getDate() + 7);\n weekFromNow.setHours(0, 0, 0, 0);\n\n // Check if it's today\n if (\n eventDate.getFullYear() === currentDate.getFullYear() &&\n eventDate.getMonth() === currentDate.getMonth() &&\n eventDate.getDate() === currentDate.getDate()\n ) {\n return 'Today';\n }\n\n // Check if it's within the next 7 days\n if (\n eventDate.getTime() > currentDate.getTime() &&\n eventDate.getTime() <= weekFromNow.getTime()\n ) {\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n return days[eventDate.getDay()];\n }\n\n // Otherwise return day of week, month and day\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n return `${days[eventDate.getDay()]}, ${\n months[eventDate.getMonth()]\n } ${eventDate.getDate()}`;\n};\n\nconst groupEventsByDate = (events: EventType[]): GroupedEvent[] => {\n const grouped = events.reduce((acc, event) => {\n const dateKey = event.startStamp;\n if (!acc[dateKey]) {\n acc[dateKey] = {\n date: getDateBanner(event.startStamp),\n events: [],\n };\n }\n acc[dateKey].events.push(event);\n return acc;\n }, {} as Record<string, GroupedEvent>);\n\n return Object.values(grouped).sort((a, b) => {\n const dateA = new Date(\n Object.keys(grouped).find((key) => grouped[key] === a) || '',\n );\n const dateB = new Date(\n Object.keys(grouped).find((key) => grouped[key] === b) || '',\n );\n return dateA.getTime() - dateB.getTime();\n });\n};\n\nexport default (props: ListProps): ElementModel =>\n (() => {\n const { isThemeDark } = props;\n const loader = feedMacros.loader.create({ isThemeDark });\n const container = document.createElement('div');\n const setTotalEntries = (count: number) => (totalEntries = count);\n const setOffset = (count: number) => (offset = offset + count);\n const setStyles = (additonalStyles: string) => (styles += additonalStyles);\n const getContainer = () => container;\n const getTotalEntries = () => totalEntries;\n const getOffset = () => offset;\n const getStyles = () => styles;\n const getShadowRoot = () => shadowRoot;\n let totalEntries = 0;\n let offset = 0;\n let styles = `\n ${loader.styles}\n `;\n let shadowRoot: ShadowRoot | null = null;\n let lastDateHeadline: string | null = null;\n\n const helperFunctions = {\n setTotalEntries,\n setOffset,\n setStyles,\n getContainer,\n getOffset,\n getTotalEntries,\n getStyles,\n getShadowRoot,\n };\n\n const callback = (shadow: ShadowRoot) => {\n shadowRoot = shadow;\n };\n\n const groupLayout = (): { element: HTMLElement; styles: string } => {\n return Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped',\n elementStyles: {\n element: {},\n },\n });\n };\n\n const displayResults = async ({ feedData }: FeedDisplay) => {\n const groupedEvents = groupEventsByDate(feedData);\n const entries: { element: HTMLElement; styles: string }[] = [];\n let actualEventCount = 0;\n\n groupedEvents.forEach((group) => {\n if (group.date !== lastDateHeadline) {\n const dateHeadline = document.createElement('p');\n dateHeadline.textContent = group.date;\n\n entries.push(\n Model.ElementModel.text.ribbon({\n element: dateHeadline,\n elementStyles: {\n element: {\n margin: `${Styles.token.spacing.lg} 0`,\n },\n },\n }),\n );\n\n lastDateHeadline = group.date;\n }\n\n const dateEntries = group.events.map((entry) =>\n Composite.card.list({\n ...dataComposed.display({ entry, isThemeDark }),\n dateSign: Atomic.events.sign({\n ...entry,\n isThemeDark,\n isLargeSize: false,\n }),\n image: feedElements.asset.standard({\n images: entry.image,\n url: entry.url,\n }),\n isAligned: false,\n }),\n );\n\n actualEventCount += group.events.length;\n\n entries.push(\n Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped-entries',\n children: [...dateEntries],\n elementStyles: {\n element: {\n [` > *:not(:last-child)`]: {\n paddingBottom: Styles.token.spacing.lg,\n marginBottom: Styles.token.spacing.lg,\n },\n\n [`+ .umd-feed-events-grouped-entries`]: {\n paddingTop: Styles.token.spacing.lg,\n marginTop: Styles.token.spacing.lg,\n },\n },\n },\n }),\n );\n });\n\n // Override the offset with actual event count to fix lazy load\n const originalSetOffset = helperFunctions.setOffset;\n helperFunctions.setOffset = () => originalSetOffset(actualEventCount);\n\n await feedDisplay.resultLoad({\n ...props,\n ...helperFunctions,\n displayResults,\n entries,\n });\n\n // Restore original setOffset\n helperFunctions.setOffset = originalSetOffset;\n\n if (shadowRoot) {\n feedDisplay.setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n };\n\n container.appendChild(loader.element);\n\n feedFetch.start({\n ...props,\n ...helperFunctions,\n displayResults,\n displayResultStart: feedDisplay.resultStart,\n displayNoResults: feedDisplay.noResults,\n layoutElement: groupLayout(),\n });\n\n return {\n element: container,\n styles,\n events: {\n callback,\n },\n };\n })();\n"],"names":["days","grouped","loader","feedMacros.loader","dataComposed.display","feedElements.asset.standard","feedDisplay.resultLoad","feedDisplay.setShadowStyles","feedFetch.start","feedDisplay.resultStart","feedDisplay.noResults"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grouped.mjs","sources":["../../../source/composite/events/grouped.ts"],"sourcesContent":["import * as Styles from '@universityofmaryland/web-styles-library';\nimport {\n Atomic,\n Composite,\n Model,\n} from '@universityofmaryland/web-elements-library';\nimport * as feedElements from 'elements';\nimport * as feedMacros from 'macros';\nimport * as feedFetch from './common/fetch';\nimport * as feedDisplay from './common/display';\nimport * as dataComposed from './common/data';\nimport { EVENTS_RANGE_QUERY, EVENTS_COUNT_RANGE_QUERY } from './common/queries';\nimport { type ListProps, type FeedDisplay, type EventType } from './_types';\nimport { type ElementModel } from '../../_types';\n\ninterface GroupedEvent {\n date: string;\n events: EventType[];\n}\n\nconst getDateBanner = (dateStamp: string): string => {\n // Parse the date string more reliably\n // Handle both \"YYYY-MM-DD\" and ISO format strings\n const dateParts = dateStamp.split('T')[0].split('-');\n const year = parseInt(dateParts[0], 10);\n const month = parseInt(dateParts[1], 10) - 1; // Month is 0-indexed\n const day = parseInt(dateParts[2], 10);\n\n // Create dates using local timezone to avoid timezone shifts\n const eventDate = new Date(year, month, day);\n const currentDate = new Date();\n currentDate.setHours(0, 0, 0, 0);\n\n const weekFromNow = new Date();\n weekFromNow.setDate(currentDate.getDate() + 7);\n weekFromNow.setHours(0, 0, 0, 0);\n\n // Check if it's today\n if (\n eventDate.getFullYear() === currentDate.getFullYear() &&\n eventDate.getMonth() === currentDate.getMonth() &&\n eventDate.getDate() === currentDate.getDate()\n ) {\n return 'Today';\n }\n\n // Check if it's within the next 7 days\n if (\n eventDate.getTime() > currentDate.getTime() &&\n eventDate.getTime() <= weekFromNow.getTime()\n ) {\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n return days[eventDate.getDay()];\n }\n\n // Otherwise return day of week, month and day\n const days = [\n 'Sunday',\n 'Monday',\n 'Tuesday',\n 'Wednesday',\n 'Thursday',\n 'Friday',\n 'Saturday',\n ];\n const months = [\n 'Jan',\n 'Feb',\n 'Mar',\n 'Apr',\n 'May',\n 'Jun',\n 'Jul',\n 'Aug',\n 'Sep',\n 'Oct',\n 'Nov',\n 'Dec',\n ];\n return `${days[eventDate.getDay()]}, ${\n months[eventDate.getMonth()]\n } ${eventDate.getDate()}`;\n};\n\nconst MONTH_MAP: Record<string, string> = {\n Jan: '01',\n Feb: '02',\n Mar: '03',\n Apr: '04',\n May: '05',\n Jun: '06',\n Jul: '07',\n Aug: '08',\n Sep: '09',\n Oct: '10',\n Nov: '11',\n Dec: '12',\n};\n\nconst parseLocalDate = (dateString: string): Date => {\n const parts = dateString.split('-');\n const date = new Date(\n parseInt(parts[0], 10),\n parseInt(parts[1], 10) - 1,\n parseInt(parts[2], 10),\n );\n date.setHours(0, 0, 0, 0);\n return date;\n};\n\nconst getEventStartDate = (event: EventType): Date => {\n return parseLocalDate(event.startStamp.split('T')[0]);\n};\n\nconst isMultiDayEvent = (event: EventType): boolean => {\n const startParts = event.startStamp.split('T')[0].split('-');\n const startMonth = startParts[1];\n const startDay = startParts[2];\n const endMonth = MONTH_MAP[event.endMonth];\n const endDay = event.endDay.padStart(2, '0');\n\n return !(startMonth === endMonth && startDay === endDay);\n};\n\nconst eventStartsOnDate = (event: EventType, targetDate: Date): boolean => {\n const eventStartDate = getEventStartDate(event);\n return eventStartDate.getTime() === targetDate.getTime();\n};\n\nconst getEventPriority = (event: EventType, groupDate: Date): number => {\n const isMulti = isMultiDayEvent(event);\n const startsOnDate = eventStartsOnDate(event, groupDate);\n\n if (isMulti && startsOnDate) return 1;\n if (!isMulti) return 2;\n return 3;\n};\n\nconst sortEventsByPriority = (\n events: EventType[],\n groupDate: Date,\n): EventType[] => {\n return [...events].sort((a, b) => {\n const aPriority = getEventPriority(a, groupDate);\n const bPriority = getEventPriority(b, groupDate);\n return aPriority - bPriority;\n });\n};\n\nconst groupEventsByDate = (events: EventType[]): GroupedEvent[] => {\n const currentDate = new Date();\n currentDate.setHours(0, 0, 0, 0);\n\n const grouped = events.reduce((acc, event) => {\n const eventDate = getEventStartDate(event);\n const dateKey =\n eventDate < currentDate\n ? currentDate.toISOString().split('T')[0]\n : event.startStamp;\n\n if (!acc[dateKey]) {\n acc[dateKey] = {\n date: getDateBanner(dateKey),\n events: [],\n };\n }\n acc[dateKey].events.push(event);\n return acc;\n }, {} as Record<string, GroupedEvent>);\n\n Object.keys(grouped).forEach((dateKey) => {\n const groupDate = parseLocalDate(dateKey);\n grouped[dateKey].events = sortEventsByPriority(\n grouped[dateKey].events,\n groupDate,\n );\n });\n\n return Object.values(grouped).sort((a, b) => {\n const dateA = new Date(\n Object.keys(grouped).find((key) => grouped[key] === a) || '',\n );\n const dateB = new Date(\n Object.keys(grouped).find((key) => grouped[key] === b) || '',\n );\n return dateA.getTime() - dateB.getTime();\n });\n};\n\nexport default (props: ListProps): ElementModel =>\n (() => {\n const { isThemeDark } = props;\n const loader = feedMacros.loader.create({ isThemeDark });\n const container = document.createElement('div');\n const setTotalEntries = (count: number) => (totalEntries = count);\n const setOffset = (count: number) => (offset = offset + count);\n const setStyles = (additonalStyles: string) => (styles += additonalStyles);\n const getContainer = () => container;\n const getTotalEntries = () => totalEntries;\n const getOffset = () => offset;\n const getStyles = () => styles;\n const getShadowRoot = () => shadowRoot;\n let totalEntries = 0;\n let offset = 0;\n let styles = `\n ${loader.styles}\n `;\n let shadowRoot: ShadowRoot | null = null;\n let lastDateHeadline: string | null = null;\n\n const helperFunctions = {\n setTotalEntries,\n setOffset,\n setStyles,\n getContainer,\n getOffset,\n getTotalEntries,\n getStyles,\n getShadowRoot,\n };\n\n const callback = (shadow: ShadowRoot) => {\n shadowRoot = shadow;\n };\n\n const groupLayout = (): { element: HTMLElement; styles: string } => {\n return Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped',\n elementStyles: {\n element: {},\n },\n });\n };\n\n const displayResults = async ({ feedData }: FeedDisplay) => {\n const groupedEvents = groupEventsByDate(feedData);\n const entries: { element: HTMLElement; styles: string }[] = [];\n let actualEventCount = 0;\n\n groupedEvents.forEach((group) => {\n if (group.date !== lastDateHeadline) {\n const dateHeadline = document.createElement('p');\n dateHeadline.textContent = group.date;\n\n entries.push(\n Model.ElementModel.text.ribbon({\n element: dateHeadline,\n elementStyles: {\n element: {\n margin: `${Styles.token.spacing.lg} 0`,\n },\n },\n }),\n );\n\n lastDateHeadline = group.date;\n }\n\n const dateEntries = group.events.map((entry) =>\n Composite.card.list({\n ...dataComposed.display({ entry, isThemeDark }),\n dateSign: Atomic.events.sign({\n ...entry,\n isThemeDark,\n isLargeSize: true,\n }),\n image: feedElements.asset.standard({\n images: entry.image,\n url: entry.url,\n }),\n isAligned: false,\n }),\n );\n\n actualEventCount += group.events.length;\n\n entries.push(\n Model.ElementModel.createDiv({\n className: 'umd-feed-events-grouped-entries',\n children: [...dateEntries],\n elementStyles: {\n element: {\n [` > *:not(:last-child)`]: {\n paddingBottom: Styles.token.spacing.md,\n marginBottom: Styles.token.spacing.md,\n borderBottom: `1px solid ${\n isThemeDark\n ? Styles.token.color.gray.dark\n : Styles.token.color.gray.light\n }`,\n },\n\n [`+ .umd-feed-events-grouped-entries`]: {\n paddingTop: Styles.token.spacing.md,\n marginTop: Styles.token.spacing.md,\n borderTop: `1px solid ${\n isThemeDark\n ? Styles.token.color.gray.dark\n : Styles.token.color.gray.light\n }`,\n },\n },\n },\n }),\n );\n });\n\n // Override the offset with actual event count to fix lazy load\n const originalSetOffset = helperFunctions.setOffset;\n helperFunctions.setOffset = () => originalSetOffset(actualEventCount);\n\n await feedDisplay.resultLoad({\n ...props,\n ...helperFunctions,\n displayResults,\n entries,\n query: EVENTS_RANGE_QUERY,\n });\n\n // Restore original setOffset\n helperFunctions.setOffset = originalSetOffset;\n\n if (shadowRoot) {\n feedDisplay.setShadowStyles({\n shadowRoot,\n styles,\n });\n }\n };\n\n container.appendChild(loader.element);\n\n feedFetch.start({\n ...props,\n ...helperFunctions,\n displayResults,\n displayResultStart: feedDisplay.resultStart,\n displayNoResults: feedDisplay.noResults,\n layoutElement: groupLayout(),\n query: EVENTS_RANGE_QUERY,\n countQuery: EVENTS_COUNT_RANGE_QUERY,\n });\n\n return {\n element: container,\n styles,\n events: {\n callback,\n },\n };\n })();\n"],"names":["days","grouped","loader","feedMacros.loader","dataComposed.display","feedElements.asset.standard","feedDisplay.resultLoad","feedDisplay.setShadowStyles","feedFetch.start","feedDisplay.resultStart","feedDisplay.noResults"],"mappings":"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"}
|