@explorer-1/vue 0.2.38 → 0.2.40
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/package.json +2 -2
- package/src/components/BaseCarousel/BaseCarousel.vue +152 -0
- package/src/components/BlockLinkCard/BlockLinkCard.vue +15 -5
- package/src/components/BlockLinkCardList/BlockLinkCardList.vue +0 -2
- package/src/components/CalendarChip/CalendarChip.vue +5 -2
- package/src/components/HeroListingIndex/HeroListingIndex.stories.js +92 -100
- package/src/components/HeroListingIndex/HeroListingIndex.vue +13 -15
- package/src/components/HeroMedium/HeroMedium.vue +1 -1
- package/src/components/Icons/IconCalendar.vue +2 -2
- package/src/components/MetadataEduResource/MetadataEduResource.vue +8 -2
- package/src/components/MetadataEvent/MetadataEvent.stories.js +1 -0
- package/src/components/MetadataEvent/MetadataEvent.vue +24 -8
- package/src/components/NavDesktop/NavDesktop.vue +6 -4
- package/src/components/NavDesktopEdu/NavDesktopEdu.vue +7 -3
- package/src/components/NavMobile/NavMobile.vue +5 -3
- package/src/components/NewsDetailMediaContact/NewsDetailMediaContact.vue +5 -3
- package/src/components/SearchFilterGroup/SearchFilterGroup.vue +26 -24
- package/src/components/SearchResultCard/SearchResultCard.vue +18 -2
- package/src/components/SearchResultGridItem/SearchResultGridItem.vue +25 -1
- package/src/components/SearchResultsList/SearchResultsList.vue +32 -4
- package/src/interfaces.ts +4 -0
- package/src/templates/www/PageTimeline/PageTimeline.vue +5 -1
- package/src/utils/mixins.ts +13 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@explorer-1/vue",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.40",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"vue-bind-once": "^0.2.1",
|
|
31
31
|
"vue-observe-visibility": "^1.0.0",
|
|
32
32
|
"vue3-compare-image": "^1.2.5",
|
|
33
|
-
"@explorer-1/common": "1.1.
|
|
33
|
+
"@explorer-1/common": "1.1.11"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@vitejs/plugin-vue": "^5.0.4",
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="BaseCarousel w-full overflow-hidden relative">
|
|
3
|
+
<div
|
|
4
|
+
ref="BaseCarousel"
|
|
5
|
+
class="swiper relative"
|
|
6
|
+
>
|
|
7
|
+
<div class="swiper-wrapper">
|
|
8
|
+
<slot />
|
|
9
|
+
</div>
|
|
10
|
+
<div class="swiper-nav lg:block absolute bottom-0 right-0 z-100">
|
|
11
|
+
<div class="relative z-10 flex">
|
|
12
|
+
<BaseButton
|
|
13
|
+
class="swiper-prev xl:text-xl border-collapse"
|
|
14
|
+
aria-label="Previous slide"
|
|
15
|
+
>
|
|
16
|
+
<template #icon>
|
|
17
|
+
<IconPrev />
|
|
18
|
+
</template>
|
|
19
|
+
</BaseButton>
|
|
20
|
+
<BaseButton
|
|
21
|
+
class="swiper-next xl:text-xl border-collapse"
|
|
22
|
+
aria-label="Next slide"
|
|
23
|
+
>
|
|
24
|
+
<template #icon>
|
|
25
|
+
<IconNext />
|
|
26
|
+
</template>
|
|
27
|
+
</BaseButton>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
<script lang="ts">
|
|
34
|
+
import { defineComponent } from 'vue'
|
|
35
|
+
import Swiper from 'swiper'
|
|
36
|
+
import { A11y, Navigation } from 'swiper/modules'
|
|
37
|
+
import type { SwiperOptions } from 'swiper/types'
|
|
38
|
+
import swiperOptions from '@explorer-1/common/src/js/_swiperOptions'
|
|
39
|
+
import IconPrev from './../Icons/IconPrev.vue'
|
|
40
|
+
import IconNext from './../Icons/IconNext.vue'
|
|
41
|
+
import BaseButton from './../BaseButton/BaseButton.vue'
|
|
42
|
+
const BaseCarouselOptions = swiperOptions.BlockImageCarousel
|
|
43
|
+
|
|
44
|
+
Swiper.use([Navigation, A11y])
|
|
45
|
+
|
|
46
|
+
export default defineComponent({
|
|
47
|
+
name: 'BaseCarousel',
|
|
48
|
+
components: {
|
|
49
|
+
BaseButton,
|
|
50
|
+
IconPrev,
|
|
51
|
+
IconNext
|
|
52
|
+
},
|
|
53
|
+
props: {
|
|
54
|
+
loop: {
|
|
55
|
+
type: Boolean,
|
|
56
|
+
default: false
|
|
57
|
+
},
|
|
58
|
+
itemRole: {
|
|
59
|
+
type: String,
|
|
60
|
+
default: undefined
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
data(): {
|
|
64
|
+
currentIndex: number
|
|
65
|
+
slider: Swiper | null
|
|
66
|
+
currentCaption: string
|
|
67
|
+
sliderOptions: SwiperOptions
|
|
68
|
+
} {
|
|
69
|
+
return {
|
|
70
|
+
currentIndex: 0,
|
|
71
|
+
currentCaption: '',
|
|
72
|
+
slider: null,
|
|
73
|
+
sliderOptions: {
|
|
74
|
+
...BaseCarouselOptions,
|
|
75
|
+
loop: this.loop,
|
|
76
|
+
// this component has custom pagination
|
|
77
|
+
pagination: false,
|
|
78
|
+
a11y: {
|
|
79
|
+
slideRole: this.itemRole as string | undefined
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
computed: {},
|
|
85
|
+
watch: {
|
|
86
|
+
slide(value) {
|
|
87
|
+
this.slideTo(value)
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
mounted() {
|
|
91
|
+
this.init()
|
|
92
|
+
},
|
|
93
|
+
methods: {
|
|
94
|
+
init() {
|
|
95
|
+
this.slider = new Swiper(this.$refs.BaseCarousel as HTMLElement, this.sliderOptions)
|
|
96
|
+
this.currentIndex = this.slider.realIndex
|
|
97
|
+
},
|
|
98
|
+
updateIndex(val: number) {
|
|
99
|
+
this.currentIndex = val
|
|
100
|
+
},
|
|
101
|
+
slideTo(val: number) {
|
|
102
|
+
if (this.slider) {
|
|
103
|
+
this.slider.slideTo(val)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
</script>
|
|
109
|
+
<style lang="scss">
|
|
110
|
+
@import 'swiper/swiper-bundle.css';
|
|
111
|
+
.BaseCarousel {
|
|
112
|
+
.swiper {
|
|
113
|
+
.swiper-prev {
|
|
114
|
+
@apply mr-px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.swiper-prev,
|
|
118
|
+
.swiper-next {
|
|
119
|
+
&.swiper-button-disabled {
|
|
120
|
+
@apply opacity-75 cursor-default bg-none;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.swiper-nav {
|
|
126
|
+
padding-top: 56.25%;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// .swiper-dots {
|
|
130
|
+
// padding-top: 56.25%;
|
|
131
|
+
// @apply pointer-events-none;
|
|
132
|
+
|
|
133
|
+
// .swiper-dot {
|
|
134
|
+
// @apply inline-block px-1 py-3 cursor-pointer pointer-events-auto;
|
|
135
|
+
|
|
136
|
+
// &:focus {
|
|
137
|
+
// @apply outline-none ring-1;
|
|
138
|
+
// }
|
|
139
|
+
|
|
140
|
+
// > span {
|
|
141
|
+
// @apply inline-block w-3 h-3 rounded-full bg-gray-light-mid;
|
|
142
|
+
// }
|
|
143
|
+
|
|
144
|
+
// &.swiper-dot-active {
|
|
145
|
+
// > span {
|
|
146
|
+
// @apply bg-primary;
|
|
147
|
+
// }
|
|
148
|
+
// }
|
|
149
|
+
// }
|
|
150
|
+
// }
|
|
151
|
+
}
|
|
152
|
+
</style>
|
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
:to="theItem.url ? theItem.url : undefined"
|
|
6
6
|
:href="theItem.externalLink ? theItem.externalLink : undefined"
|
|
7
7
|
class="BlockLinkCard group"
|
|
8
|
-
:link-class="`block ${small ? 'pb-3' : 'pb-5'} ${large ? 'sm:flex flex-row' : ''}`"
|
|
8
|
+
:link-class="`block ${small ? 'pb-3' : 'pb-5'} ${large ? 'sm:flex flex-row border-b border-gray-light-mid pb-5 mb-5' : ''}`"
|
|
9
9
|
external-target-blank
|
|
10
10
|
>
|
|
11
11
|
<BaseImagePlaceholder
|
|
12
12
|
:aspect-ratio="large ? '3:2' : '16:9'"
|
|
13
|
-
class="bg-gray-dark relative
|
|
14
|
-
:class="{ 'lg:mb-10': medium, 'sm:w-1/3': large }"
|
|
13
|
+
class="bg-gray-dark h-full relative overflow-hidden mb-6"
|
|
14
|
+
:class="{ 'lg:mb-10': medium, 'sm:w-1/3 lg:mb-0': large }"
|
|
15
15
|
dark-mode
|
|
16
16
|
no-logo
|
|
17
17
|
>
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
{{ theItem.title }}
|
|
98
98
|
</component>
|
|
99
99
|
<p
|
|
100
|
-
v-if="theItem.date"
|
|
100
|
+
v-if="theItem.date && !themeStore.isEdu"
|
|
101
101
|
class="text-gray-mid-dark mt-2"
|
|
102
102
|
:class="{ 'mt-2': !large, 'mt-4': large }"
|
|
103
103
|
>
|
|
@@ -106,9 +106,19 @@
|
|
|
106
106
|
<p
|
|
107
107
|
v-if="large && theItem.summary"
|
|
108
108
|
class="mt-4 text-gray-mid-dark"
|
|
109
|
+
:class="{
|
|
110
|
+
'line-clamp-2 sm:line-clamp-1 lg:line-clamp-2 xl:line-clamp-3': themeStore.isEdu
|
|
111
|
+
}"
|
|
109
112
|
>
|
|
110
113
|
{{ theItem.summary }}
|
|
111
114
|
</p>
|
|
115
|
+
<p
|
|
116
|
+
v-if="theItem.date && themeStore.isEdu"
|
|
117
|
+
class="text-gray-mid-dark mt-2"
|
|
118
|
+
:class="{ 'mt-2': !large, 'mt-4': large }"
|
|
119
|
+
>
|
|
120
|
+
{{ theItem.date }}
|
|
121
|
+
</p>
|
|
112
122
|
<div
|
|
113
123
|
v-if="metadataAttrs"
|
|
114
124
|
:class="{ 'mt-4': large, 'mt-2 mb-1': medium, 'mt-1 mb-0': small }"
|
|
@@ -117,13 +127,13 @@
|
|
|
117
127
|
v-if="metadataType === 'EDUEventPage'"
|
|
118
128
|
:event="theItem"
|
|
119
129
|
:show-time="large"
|
|
120
|
-
:show-location="false"
|
|
121
130
|
compact
|
|
122
131
|
/>
|
|
123
132
|
<MetadataEduResource
|
|
124
133
|
v-else-if="metadataAttrs.type === 'resource'"
|
|
125
134
|
:resource="theItem as EduResourceCardObject"
|
|
126
135
|
:variant="metadataAttrs.icons"
|
|
136
|
+
:show-time="true"
|
|
127
137
|
compact
|
|
128
138
|
/>
|
|
129
139
|
</div>
|
|
@@ -16,8 +16,6 @@ const props = withDefaults(defineProps<BlockLinkCardListProps>(), {
|
|
|
16
16
|
<BlockLinkCard
|
|
17
17
|
v-for="(item, index) in props.items"
|
|
18
18
|
:key="index"
|
|
19
|
-
class="border-b border-gray-light-mid mb-5"
|
|
20
|
-
:class="{ 'pt-3': index !== 0 }"
|
|
21
19
|
:data="item"
|
|
22
20
|
size="lg"
|
|
23
21
|
show-calendar-chip
|
|
@@ -33,8 +33,11 @@ const splitDate = computed(() => {
|
|
|
33
33
|
<div class="text-subtitle">Ongoing</div>
|
|
34
34
|
</template>
|
|
35
35
|
<template v-else-if="themeStore.isEdu && splitDate">
|
|
36
|
-
<div
|
|
37
|
-
|
|
36
|
+
<div
|
|
37
|
+
v-if="splitDate.month"
|
|
38
|
+
class="font-extrabold text-6xl leading-tight tracking-wider uppercase"
|
|
39
|
+
>
|
|
40
|
+
{{ splitDate.month.substring(0, 3) }}
|
|
38
41
|
</div>
|
|
39
42
|
<div class="text-subtitle">
|
|
40
43
|
{{ splitDate.year }}
|
|
@@ -11,26 +11,24 @@ export default {
|
|
|
11
11
|
|
|
12
12
|
// data
|
|
13
13
|
export const HeroListingIndexData = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
url: 'https://picsum.photos/id/247/640/900'
|
|
33
|
-
}
|
|
14
|
+
featuredPage: {
|
|
15
|
+
__typename: 'EDUExplainerArticlePage',
|
|
16
|
+
topicLabel: 'Mars',
|
|
17
|
+
url: '/news/new-maps-open-roads-to-research/',
|
|
18
|
+
title: 'Creating Robots to go Where Humans Can’t',
|
|
19
|
+
image: {
|
|
20
|
+
src: {
|
|
21
|
+
url: 'https://picsum.photos/id/973/1800/1200',
|
|
22
|
+
width: 1800,
|
|
23
|
+
height: 1200
|
|
24
|
+
},
|
|
25
|
+
srcSet:
|
|
26
|
+
'https://picsum.photos/id/865/768/548 768w, https://picsum.photos/id/865/1024/684 1024w, https://picsum.photos/id/865/1440/770 1440w, https://picsum.photos/id/865/1800/963 1800w',
|
|
27
|
+
screenMd: {
|
|
28
|
+
url: 'https://picsum.photos/id/921/800/640'
|
|
29
|
+
},
|
|
30
|
+
screenSm: {
|
|
31
|
+
url: 'https://picsum.photos/id/247/640/900'
|
|
34
32
|
}
|
|
35
33
|
}
|
|
36
34
|
}
|
|
@@ -42,7 +40,7 @@ export const BaseStory = {
|
|
|
42
40
|
name: 'HeroListingIndex',
|
|
43
41
|
args: {
|
|
44
42
|
customLabel: 'Featured',
|
|
45
|
-
pageData: HeroListingIndexData.
|
|
43
|
+
pageData: HeroListingIndexData.featuredPage
|
|
46
44
|
}
|
|
47
45
|
}
|
|
48
46
|
|
|
@@ -50,31 +48,29 @@ export const NewsImageHero = {
|
|
|
50
48
|
args: {
|
|
51
49
|
customLabel: 'Featured',
|
|
52
50
|
pageData: {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
url: 'https://picsum.photos/id/247/640/900'
|
|
73
|
-
}
|
|
51
|
+
topicLabel: 'Mars',
|
|
52
|
+
url: '/news/new-maps-open-roads-to-research/',
|
|
53
|
+
title: 'Creating Robots to go Where Humans Can’t',
|
|
54
|
+
heroBlocks: [
|
|
55
|
+
{
|
|
56
|
+
blockType: 'ImageChooserBlock',
|
|
57
|
+
listingPageHeroImage: {
|
|
58
|
+
src: {
|
|
59
|
+
url: 'https://picsum.photos/id/973/1800/1200',
|
|
60
|
+
width: 1800,
|
|
61
|
+
height: 1200
|
|
62
|
+
},
|
|
63
|
+
srcSet:
|
|
64
|
+
'https://picsum.photos/id/865/768/548 768w, https://picsum.photos/id/865/1024/684 1024w, https://picsum.photos/id/865/1440/770 1440w, https://picsum.photos/id/865/1800/963 1800w',
|
|
65
|
+
screenMd: {
|
|
66
|
+
url: 'https://picsum.photos/id/921/800/640'
|
|
67
|
+
},
|
|
68
|
+
screenSm: {
|
|
69
|
+
url: 'https://picsum.photos/id/247/640/900'
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
}
|
|
73
|
+
]
|
|
78
74
|
}
|
|
79
75
|
}
|
|
80
76
|
}
|
|
@@ -83,20 +79,18 @@ export const NewsVideoHero = {
|
|
|
83
79
|
args: {
|
|
84
80
|
customLabel: 'Featured',
|
|
85
81
|
pageData: {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
fileWebm: '/videos/NASA-Mars-Helicopter-IngenuityAnimations-7sec.webm'
|
|
96
|
-
}
|
|
82
|
+
topicLabel: 'Mars',
|
|
83
|
+
url: '/news/new-maps-open-roads-to-research/',
|
|
84
|
+
title: 'Creating Robots to go Where Humans Can’t',
|
|
85
|
+
heroBlocks: [
|
|
86
|
+
{
|
|
87
|
+
blockType: 'VideoBlock',
|
|
88
|
+
video: {
|
|
89
|
+
file: '/videos/NASA-Mars-Helicopter-IngenuityAnimations-7sec.mp4',
|
|
90
|
+
fileWebm: '/videos/NASA-Mars-Helicopter-IngenuityAnimations-7sec.webm'
|
|
97
91
|
}
|
|
98
|
-
|
|
99
|
-
|
|
92
|
+
}
|
|
93
|
+
]
|
|
100
94
|
}
|
|
101
95
|
}
|
|
102
96
|
}
|
|
@@ -105,52 +99,50 @@ export const NewsCarouselHero = {
|
|
|
105
99
|
args: {
|
|
106
100
|
customLabel: 'Featured',
|
|
107
101
|
pageData: {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
{
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
url: 'https://picsum.photos/id/247/640/900'
|
|
130
|
-
}
|
|
102
|
+
topicLabel: 'Mars',
|
|
103
|
+
url: '/news/new-maps-open-roads-to-research/',
|
|
104
|
+
title: 'Creating Robots to go Where Humans Can’t',
|
|
105
|
+
heroBlocks: [
|
|
106
|
+
{
|
|
107
|
+
blockType: 'CarouselBlock',
|
|
108
|
+
blocks: [
|
|
109
|
+
{
|
|
110
|
+
listingPageHeroImage: {
|
|
111
|
+
src: {
|
|
112
|
+
url: 'https://picsum.photos/id/973/1800/1200',
|
|
113
|
+
width: 1800,
|
|
114
|
+
height: 1200
|
|
115
|
+
},
|
|
116
|
+
srcSet:
|
|
117
|
+
'https://picsum.photos/id/865/768/548 768w, https://picsum.photos/id/865/1024/684 1024w, https://picsum.photos/id/865/1440/770 1440w, https://picsum.photos/id/865/1800/963 1800w',
|
|
118
|
+
screenMd: {
|
|
119
|
+
url: 'https://picsum.photos/id/921/800/640'
|
|
120
|
+
},
|
|
121
|
+
screenSm: {
|
|
122
|
+
url: 'https://picsum.photos/id/247/640/900'
|
|
131
123
|
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
listingPageHeroImage: {
|
|
128
|
+
src: {
|
|
129
|
+
url: 'https://picsum.photos/id/973/1800/1200',
|
|
130
|
+
width: 1800,
|
|
131
|
+
height: 1200
|
|
132
|
+
},
|
|
133
|
+
srcSet:
|
|
134
|
+
'https://picsum.photos/id/865/768/548 768w, https://picsum.photos/id/865/1024/684 1024w, https://picsum.photos/id/865/1440/770 1440w, https://picsum.photos/id/865/1800/963 1800w',
|
|
135
|
+
screenMd: {
|
|
136
|
+
url: 'https://picsum.photos/id/921/800/640'
|
|
137
|
+
},
|
|
138
|
+
screenSm: {
|
|
139
|
+
url: 'https://picsum.photos/id/247/640/900'
|
|
148
140
|
}
|
|
149
141
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
]
|
|
154
146
|
}
|
|
155
147
|
}
|
|
156
148
|
}
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div
|
|
3
3
|
v-if="pageData"
|
|
4
|
-
class="max-w-screen-3xl mx-auto"
|
|
5
|
-
:class="{ '-nav-offset': pageData
|
|
4
|
+
class="HeroListingIndex max-w-screen-3xl mx-auto"
|
|
5
|
+
:class="{ '-nav-offset': pageData }"
|
|
6
6
|
>
|
|
7
7
|
<HeroMedium
|
|
8
|
-
v-if="pageData
|
|
8
|
+
v-if="pageData"
|
|
9
9
|
class="md:mb-12 lg:mb-18 mb-10"
|
|
10
10
|
:custom-pill="themeStore.theme === 'ThemeEdu' && customLabel ? customLabel : undefined"
|
|
11
11
|
:custom-pill-type="
|
|
12
|
-
themeStore.theme === 'ThemeEdu' && pageData.
|
|
13
|
-
? pageData.featured.__typename
|
|
14
|
-
: undefined
|
|
12
|
+
themeStore.theme === 'ThemeEdu' && pageData.__typename ? pageData.__typename : undefined
|
|
15
13
|
"
|
|
16
|
-
:custom-label="themeStore.theme === 'ThemeEdu' ? pageData.
|
|
17
|
-
:feature="pageData
|
|
14
|
+
:custom-label="themeStore.theme === 'ThemeEdu' ? pageData.topicLabel : customLabel"
|
|
15
|
+
:feature="pageData"
|
|
18
16
|
:custom-video="customVideo"
|
|
19
17
|
:custom-image="customImage"
|
|
20
18
|
:cta="cta"
|
|
@@ -54,17 +52,17 @@ export default defineComponent({
|
|
|
54
52
|
...mapStores(useThemeStore),
|
|
55
53
|
// parses a hero streamfield block for a video (newsDetailPage model)
|
|
56
54
|
customVideo(): object | undefined {
|
|
57
|
-
if (this.pageData && this.pageData
|
|
58
|
-
if (this.pageData.
|
|
59
|
-
return this.pageData.
|
|
55
|
+
if (this.pageData && this.pageData?.heroBlocks?.length > 0) {
|
|
56
|
+
if (this.pageData.heroBlocks[0].blockType === 'VideoBlock') {
|
|
57
|
+
return this.pageData.heroBlocks[0].video
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
60
|
return undefined
|
|
63
61
|
},
|
|
64
62
|
customImage(): object | undefined {
|
|
65
63
|
// parse hero streamfield block for the first usable image (newsDetailPage model)
|
|
66
|
-
if (this.pageData
|
|
67
|
-
const block = this.pageData
|
|
64
|
+
if (this.pageData?.heroBlocks?.length > 0) {
|
|
65
|
+
const block = this.pageData?.heroBlocks[0]
|
|
68
66
|
if (block.blockType === 'ImageChooserBlock' || block.blockType === 'HeroImageBlock') {
|
|
69
67
|
return block.listingPageHeroImage
|
|
70
68
|
} else if (block.blockType === 'CarouselBlock') {
|
|
@@ -75,8 +73,8 @@ export default defineComponent({
|
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
// else use heroImage
|
|
78
|
-
else if (this.pageData?.
|
|
79
|
-
return this.pageData.
|
|
76
|
+
else if (this.pageData?.listingPageHeroImage) {
|
|
77
|
+
return this.pageData.listingPageHeroImage
|
|
80
78
|
}
|
|
81
79
|
return undefined
|
|
82
80
|
}
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
<p class="text-h3 font-semibold mb-0">
|
|
75
75
|
<span class="mr-2">{{ feature.title }}</span>
|
|
76
76
|
<span
|
|
77
|
-
class="text-
|
|
77
|
+
class="text-action-light lg:hidden can-hover:group-hover:ml-2 ml-0 text-4xl transition-all duration-200 ease-in"
|
|
78
78
|
>
|
|
79
79
|
<IconArrow class="inline" />
|
|
80
80
|
</span>
|
|
@@ -11,12 +11,14 @@ interface MetadataEduResourceProps {
|
|
|
11
11
|
resource: EduResourceCardObject
|
|
12
12
|
compact?: boolean
|
|
13
13
|
variant?: string
|
|
14
|
+
showTime: boolean
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
// define props
|
|
17
18
|
const props = withDefaults(defineProps<MetadataEduResourceProps>(), {
|
|
18
19
|
resource: undefined,
|
|
19
20
|
compact: false,
|
|
21
|
+
showTime: false,
|
|
20
22
|
variant: 'primary'
|
|
21
23
|
})
|
|
22
24
|
|
|
@@ -30,7 +32,11 @@ const audience = computed(() => {
|
|
|
30
32
|
return rangeifyGrades(props.resource?.gradeLevels)
|
|
31
33
|
})
|
|
32
34
|
const time = computed(() => {
|
|
33
|
-
|
|
35
|
+
let time = props.resource?.time?.time
|
|
36
|
+
if (time && props.compact) {
|
|
37
|
+
time = time.replace('Under ', '<')
|
|
38
|
+
}
|
|
39
|
+
return time
|
|
34
40
|
})
|
|
35
41
|
</script>
|
|
36
42
|
<template>
|
|
@@ -61,7 +67,7 @@ const time = computed(() => {
|
|
|
61
67
|
<span>{{ audience }}</span>
|
|
62
68
|
</div>
|
|
63
69
|
<div
|
|
64
|
-
v-if="time &&
|
|
70
|
+
v-if="time && showTime"
|
|
65
71
|
class="MetadataEduResourceItem"
|
|
66
72
|
>
|
|
67
73
|
<IconTime
|
|
@@ -52,8 +52,24 @@ const displayTime = computed((): string => {
|
|
|
52
52
|
}
|
|
53
53
|
return ''
|
|
54
54
|
})
|
|
55
|
-
const
|
|
56
|
-
|
|
55
|
+
const location = computed(() => {
|
|
56
|
+
if (props.event?.location) {
|
|
57
|
+
return props.event?.location
|
|
58
|
+
} else if (props.compact) {
|
|
59
|
+
let text = 'Hybrid'
|
|
60
|
+
let virtual = props.event.isVirtualEvent
|
|
61
|
+
let inPerson = props.event.isInPersonEvent
|
|
62
|
+
if (props.event?.isVirtualEvent && props) {
|
|
63
|
+
if (virtual && !inPerson) {
|
|
64
|
+
text = 'Online'
|
|
65
|
+
} else if (!virtual && inPerson) {
|
|
66
|
+
text = 'In-person'
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return text
|
|
70
|
+
} else {
|
|
71
|
+
return props.event?.locationName
|
|
72
|
+
}
|
|
57
73
|
})
|
|
58
74
|
</script>
|
|
59
75
|
<template>
|
|
@@ -96,7 +112,7 @@ const locationName = computed(() => {
|
|
|
96
112
|
/>
|
|
97
113
|
<meta
|
|
98
114
|
itemprop="name"
|
|
99
|
-
:content="
|
|
115
|
+
:content="location"
|
|
100
116
|
/>
|
|
101
117
|
<IconLocation class="MetadataEventIcon text-[1.1em]" />
|
|
102
118
|
<BaseLink
|
|
@@ -105,18 +121,18 @@ const locationName = computed(() => {
|
|
|
105
121
|
:href="props.event.locationLink"
|
|
106
122
|
external-target-blank
|
|
107
123
|
>
|
|
108
|
-
{{
|
|
124
|
+
{{ location }}
|
|
109
125
|
</BaseLink>
|
|
110
126
|
</div>
|
|
111
127
|
<!-- Normal location -->
|
|
112
128
|
<div
|
|
113
|
-
v-else-if="
|
|
129
|
+
v-else-if="location"
|
|
114
130
|
class="MetadataEventItem"
|
|
115
131
|
>
|
|
116
132
|
<meta
|
|
117
133
|
v-if="!props.compact"
|
|
118
134
|
itemprop="location"
|
|
119
|
-
:content="
|
|
135
|
+
:content="location"
|
|
120
136
|
/>
|
|
121
137
|
<IconLocation class="MetadataEventIcon text-[1.2em]" />
|
|
122
138
|
<BaseLink
|
|
@@ -126,9 +142,9 @@ const locationName = computed(() => {
|
|
|
126
142
|
:href="props.event.locationLink"
|
|
127
143
|
external-target-blank
|
|
128
144
|
>
|
|
129
|
-
{{
|
|
145
|
+
{{ location }}
|
|
130
146
|
</BaseLink>
|
|
131
|
-
<span v-else>{{
|
|
147
|
+
<span v-else>{{ location }}</span>
|
|
132
148
|
</div>
|
|
133
149
|
</template>
|
|
134
150
|
</div>
|
|
@@ -250,9 +250,9 @@ export default defineComponent({
|
|
|
250
250
|
// key into the breadcrumbs for each section
|
|
251
251
|
const sectionLinks = this.breadcrumb.menu_links[urlKey]
|
|
252
252
|
// check if any of the paths contained in the array are active
|
|
253
|
-
const isActive = sectionLinks
|
|
254
|
-
mixinIsActivePath(link.path)
|
|
255
|
-
|
|
253
|
+
const isActive = sectionLinks?.length
|
|
254
|
+
? sectionLinks.some((link: BreadcrumbPathObject) => mixinIsActivePath(link.path))
|
|
255
|
+
: undefined
|
|
256
256
|
if (isActive) {
|
|
257
257
|
mixinUpdateGlobalChildren(sectionLinks)
|
|
258
258
|
}
|
|
@@ -265,7 +265,9 @@ export default defineComponent({
|
|
|
265
265
|
// get the more menu array
|
|
266
266
|
const arr = this.breadcrumb.more
|
|
267
267
|
// check if array contains current path
|
|
268
|
-
const isActive = arr
|
|
268
|
+
const isActive = arr?.length
|
|
269
|
+
? arr.some((el: BreadcrumbPathObject) => mixinIsActivePath(el.path))
|
|
270
|
+
: undefined
|
|
269
271
|
if (isActive) {
|
|
270
272
|
// clear the secondary nav store when visiting a breadcrumb page
|
|
271
273
|
// ensures blank secondary nav unless explicitly set via content page "Promote" settings
|
|
@@ -254,7 +254,9 @@ export default defineComponent({
|
|
|
254
254
|
// key into the breadcrumbs for each section
|
|
255
255
|
const objArray = this.breadcrumb.menu_links[urlKey]
|
|
256
256
|
// check if any of the paths contained in the array are active
|
|
257
|
-
const isActive = objArray
|
|
257
|
+
const isActive = objArray?.length
|
|
258
|
+
? objArray.some((el: BreadcrumbPathObject) => mixinIsActivePath(el.path))
|
|
259
|
+
: undefined
|
|
258
260
|
if (isActive) {
|
|
259
261
|
mixinUpdateGlobalChildren(this.breadcrumb.menu_links[urlKey])
|
|
260
262
|
}
|
|
@@ -267,7 +269,9 @@ export default defineComponent({
|
|
|
267
269
|
// get the more menu array
|
|
268
270
|
const arr = this.breadcrumb.more
|
|
269
271
|
// check if array contains current path
|
|
270
|
-
const isActive = arr
|
|
272
|
+
const isActive = arr?.length
|
|
273
|
+
? arr.some((el: BreadcrumbPathObject) => mixinIsActivePath(el.path))
|
|
274
|
+
: undefined
|
|
271
275
|
if (isActive) {
|
|
272
276
|
// clear the secondary nav store when visiting a breadcrumb page
|
|
273
277
|
// ensures blank secondary nav unless explicitly set via content page "Promote" settings
|
|
@@ -300,7 +304,7 @@ export default defineComponent({
|
|
|
300
304
|
</script>
|
|
301
305
|
<style lang="scss">
|
|
302
306
|
.NavDesktopEdu {
|
|
303
|
-
@apply border-
|
|
307
|
+
@apply border-none;
|
|
304
308
|
|
|
305
309
|
> .header-bg {
|
|
306
310
|
@apply bg-gradient-to-r from-black to-primary bg-transparent to-90%;
|
|
@@ -280,9 +280,11 @@ export default defineComponent({
|
|
|
280
280
|
// key into the breadcrumbs for each section
|
|
281
281
|
const objArray = this.breadcrumb.menu_links[urlKey]
|
|
282
282
|
// check if any of the paths contained in the array are active
|
|
283
|
-
return objArray
|
|
284
|
-
|
|
285
|
-
|
|
283
|
+
return objArray?.length
|
|
284
|
+
? objArray.some((el: BreadcrumbPathObject) => {
|
|
285
|
+
return mixinIsActivePath(el.path)
|
|
286
|
+
})
|
|
287
|
+
: undefined
|
|
286
288
|
}
|
|
287
289
|
return false
|
|
288
290
|
}
|
|
@@ -42,9 +42,11 @@ export default defineComponent({
|
|
|
42
42
|
},
|
|
43
43
|
computed: {
|
|
44
44
|
hasContent() {
|
|
45
|
-
return this.contacts
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
return this.contacts?.length
|
|
46
|
+
? this.contacts.some(
|
|
47
|
+
(c) => c.contact.name || c.contact.address || c.contact.phone || c.contact.email
|
|
48
|
+
)
|
|
49
|
+
: undefined
|
|
48
50
|
}
|
|
49
51
|
},
|
|
50
52
|
methods: {
|
|
@@ -13,32 +13,34 @@
|
|
|
13
13
|
<legend class="md:mb-3 text-body-md mb-2 font-bold leading-normal tracking-wide">
|
|
14
14
|
{{ groupTitle }}
|
|
15
15
|
</legend>
|
|
16
|
-
<div
|
|
17
|
-
v-for="(bucket, index) in buckets"
|
|
18
|
-
:key="bucket.key"
|
|
19
|
-
ref="buckets"
|
|
20
|
-
class="form-group form-check"
|
|
21
|
-
>
|
|
22
|
-
<!-- correct for zero based index -->
|
|
16
|
+
<div class="buckets">
|
|
23
17
|
<div
|
|
24
|
-
v-
|
|
25
|
-
|
|
18
|
+
v-for="(bucket, index) in buckets"
|
|
19
|
+
:key="bucket.key"
|
|
20
|
+
ref="buckets"
|
|
21
|
+
class="form-group form-check"
|
|
26
22
|
>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
v-
|
|
30
|
-
|
|
31
|
-
:value="bucket.key_as_string ? bucket.key_as_string : bucket.key"
|
|
32
|
-
class="text-primary focus:ring-2 focus:ring-primary flex-shrink-0 w-5 h-5 mt-px mr-1 align-middle border rounded-none"
|
|
33
|
-
/>
|
|
34
|
-
<!-- 'key_as_string' exists for dates to have a human readable version -->
|
|
35
|
-
<label
|
|
36
|
-
:for="bucket.key_as_string ? generateId(bucket.key_as_string) : generateId(bucket.key)"
|
|
37
|
-
class="form-check-label pl-2 tracking-normal align-middle"
|
|
23
|
+
<!-- correct for zero based index -->
|
|
24
|
+
<div
|
|
25
|
+
v-if="!truncateFilters || index <= checkbox.checkboxLimit - 1"
|
|
26
|
+
class="flex my-2"
|
|
38
27
|
>
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
<input
|
|
29
|
+
:id="bucket.key_as_string ? generateId(bucket.key_as_string) : generateId(bucket.key)"
|
|
30
|
+
v-model="filterByHandler"
|
|
31
|
+
type="checkbox"
|
|
32
|
+
:value="bucket.key_as_string ? bucket.key_as_string : bucket.key"
|
|
33
|
+
class="text-primary focus:ring-2 focus:ring-primary flex-shrink-0 w-5 h-5 mt-px mr-1 align-middle border rounded-none"
|
|
34
|
+
/>
|
|
35
|
+
<!-- 'key_as_string' exists for dates to have a human readable version -->
|
|
36
|
+
<label
|
|
37
|
+
:for="bucket.key_as_string ? generateId(bucket.key_as_string) : generateId(bucket.key)"
|
|
38
|
+
class="form-check-label pl-2 tracking-normal align-middle"
|
|
39
|
+
>
|
|
40
|
+
{{ prettyFilterNames(bucket.key_as_string ? bucket.key_as_string : bucket.key) }}
|
|
41
|
+
<span class="text-gray-mid-dark"> ({{ bucket.doc_count.toLocaleString() }}) </span>
|
|
42
|
+
</label>
|
|
43
|
+
</div>
|
|
42
44
|
</div>
|
|
43
45
|
</div>
|
|
44
46
|
<!--
|
|
@@ -49,7 +51,7 @@
|
|
|
49
51
|
|
|
50
52
|
<div v-show="truncateFilters && bucketsLength > checkbox.initialLimit">
|
|
51
53
|
<button
|
|
52
|
-
class="can-hover:hover:underline text-
|
|
54
|
+
class="can-hover:hover:underline text-action mt-2"
|
|
53
55
|
:aria-expanded="!checkbox.showMore ? 'true' : 'false'"
|
|
54
56
|
aria-haspopup="true"
|
|
55
57
|
:aria-controls="`filterGroup_${groupKey}`"
|
|
@@ -20,8 +20,11 @@
|
|
|
20
20
|
endDate,
|
|
21
21
|
customDate,
|
|
22
22
|
location,
|
|
23
|
-
eventType
|
|
24
|
-
ongoing
|
|
23
|
+
eventType,
|
|
24
|
+
ongoing,
|
|
25
|
+
primarySubject,
|
|
26
|
+
gradeLevels,
|
|
27
|
+
time
|
|
25
28
|
}
|
|
26
29
|
}"
|
|
27
30
|
show-calendar-chip
|
|
@@ -211,6 +214,7 @@
|
|
|
211
214
|
import type { PropType } from 'vue'
|
|
212
215
|
import { defineComponent } from 'vue'
|
|
213
216
|
import { mapStores } from 'pinia'
|
|
217
|
+
import type { PrimarySubjectObject, GradeLevelsObject, EduResourcesTime } from './../../interfaces'
|
|
214
218
|
import { useThemeStore } from '../../store/theme'
|
|
215
219
|
import PodcastEpisodeCard from './../PodcastEpisodeCard/PodcastEpisodeCard.vue'
|
|
216
220
|
import BaseLink from './../BaseLink/BaseLink.vue'
|
|
@@ -338,6 +342,18 @@ export default defineComponent({
|
|
|
338
342
|
ongoing: {
|
|
339
343
|
type: Boolean,
|
|
340
344
|
default: false
|
|
345
|
+
},
|
|
346
|
+
primarySubject: {
|
|
347
|
+
type: Object as PropType<PrimarySubjectObject>,
|
|
348
|
+
default: undefined
|
|
349
|
+
},
|
|
350
|
+
gradeLevels: {
|
|
351
|
+
type: Array as PropType<GradeLevelsObject[]>,
|
|
352
|
+
default: undefined
|
|
353
|
+
},
|
|
354
|
+
time: {
|
|
355
|
+
type: Object as PropType<EduResourcesTime>,
|
|
356
|
+
default: undefined
|
|
341
357
|
}
|
|
342
358
|
},
|
|
343
359
|
computed: {
|
|
@@ -15,12 +15,18 @@
|
|
|
15
15
|
startDate,
|
|
16
16
|
endTime,
|
|
17
17
|
endDate,
|
|
18
|
+
customDate,
|
|
18
19
|
location,
|
|
19
|
-
eventType
|
|
20
|
+
eventType,
|
|
21
|
+
ongoing,
|
|
22
|
+
primarySubject,
|
|
23
|
+
gradeLevels,
|
|
24
|
+
time
|
|
20
25
|
}
|
|
21
26
|
}"
|
|
22
27
|
:heading-level="headingLevel"
|
|
23
28
|
size="sm"
|
|
29
|
+
show-calendar-chip
|
|
24
30
|
/>
|
|
25
31
|
<BlockLinkCard
|
|
26
32
|
v-else-if="typename === 'News'"
|
|
@@ -91,6 +97,7 @@
|
|
|
91
97
|
import type { PropType } from 'vue'
|
|
92
98
|
import { defineComponent } from 'vue'
|
|
93
99
|
import { mapStores } from 'pinia'
|
|
100
|
+
import type { PrimarySubjectObject, GradeLevelsObject, EduResourcesTime } from './../../interfaces'
|
|
94
101
|
import { useThemeStore } from '../../store/theme'
|
|
95
102
|
import BaseLink from './../BaseLink/BaseLink.vue'
|
|
96
103
|
import BaseImage from './../BaseImage/BaseImage.vue'
|
|
@@ -148,6 +155,11 @@ export default defineComponent({
|
|
|
148
155
|
type: String,
|
|
149
156
|
required: false
|
|
150
157
|
},
|
|
158
|
+
customDate: {
|
|
159
|
+
type: String,
|
|
160
|
+
required: false,
|
|
161
|
+
default: undefined
|
|
162
|
+
},
|
|
151
163
|
startTime: {
|
|
152
164
|
type: String,
|
|
153
165
|
required: false,
|
|
@@ -173,6 +185,18 @@ export default defineComponent({
|
|
|
173
185
|
pageContentType: {
|
|
174
186
|
type: String,
|
|
175
187
|
required: false
|
|
188
|
+
},
|
|
189
|
+
primarySubject: {
|
|
190
|
+
type: Object as PropType<PrimarySubjectObject>,
|
|
191
|
+
default: undefined
|
|
192
|
+
},
|
|
193
|
+
gradeLevels: {
|
|
194
|
+
type: Array as PropType<GradeLevelsObject[]>,
|
|
195
|
+
default: undefined
|
|
196
|
+
},
|
|
197
|
+
time: {
|
|
198
|
+
type: Object as PropType<EduResourcesTime>,
|
|
199
|
+
default: undefined
|
|
176
200
|
}
|
|
177
201
|
},
|
|
178
202
|
computed: {
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
:event-type="page.eventType"
|
|
32
32
|
:ongoing="page.ongoing"
|
|
33
33
|
:location="page.location"
|
|
34
|
+
:primary-subject="page.primarySubject as unknown as PrimarySubjectObject"
|
|
35
|
+
:grade-levels="page.gradeLevels as unknown as GradeLevelsObject[]"
|
|
36
|
+
:time="page.time as unknown as EduResourcesTime"
|
|
34
37
|
:title="page.title"
|
|
35
38
|
:summary="page.summary"
|
|
36
39
|
:featured="featureFirstResult ? index === 0 && currentPage === 1 : false"
|
|
@@ -45,10 +48,17 @@
|
|
|
45
48
|
:topic="page.topic"
|
|
46
49
|
:image="page.image"
|
|
47
50
|
:date="page.date"
|
|
51
|
+
:custom-date="page.customDate"
|
|
48
52
|
:start-date="page.startDate"
|
|
49
53
|
:end-date="page.endDate"
|
|
50
54
|
:start-time="page.startTime"
|
|
51
55
|
:end-time="page.endTime"
|
|
56
|
+
:event-type="page.eventType"
|
|
57
|
+
:ongoing="page.ongoing"
|
|
58
|
+
:location="page.location"
|
|
59
|
+
:primary-subject="page.primarySubject as unknown as PrimarySubjectObject"
|
|
60
|
+
:grade-levels="page.gradeLevels as unknown as GradeLevelsObject[]"
|
|
61
|
+
:time="page.time as unknown as EduResourcesTime"
|
|
52
62
|
:title="page.title"
|
|
53
63
|
heading-level="h2"
|
|
54
64
|
/>
|
|
@@ -60,7 +70,7 @@
|
|
|
60
70
|
<script lang="ts">
|
|
61
71
|
import { defineComponent } from 'vue'
|
|
62
72
|
import type { ElasticSearchPage } from '../../interfaces'
|
|
63
|
-
|
|
73
|
+
import type { PrimarySubjectObject, GradeLevelsObject, EduResourcesTime } from './../../interfaces'
|
|
64
74
|
// @ts-ignore
|
|
65
75
|
import dayjs from 'dayjs'
|
|
66
76
|
import SearchResultCard from './../SearchResultCard/SearchResultCard.vue'
|
|
@@ -126,6 +136,10 @@ export default defineComponent({
|
|
|
126
136
|
: page._source[handle + '__image']
|
|
127
137
|
// date field is different for mission and event detail pages
|
|
128
138
|
let date
|
|
139
|
+
let location
|
|
140
|
+
let primarySubject
|
|
141
|
+
let gradeLevels
|
|
142
|
+
let time
|
|
129
143
|
let topic =
|
|
130
144
|
handle === 'missions_mission'
|
|
131
145
|
? page._source[handle + '__status_filter']
|
|
@@ -137,6 +151,7 @@ export default defineComponent({
|
|
|
137
151
|
date = 'Event date: ' + parseDate(page._source[handle + '__start_datetime'])
|
|
138
152
|
} else if (handle === 'edu_events_edueventpage') {
|
|
139
153
|
date = null
|
|
154
|
+
location = page._source[handle + '__location_filter']
|
|
140
155
|
} else if (handle === 'missions_mission') {
|
|
141
156
|
date = page._source.display_date_filter
|
|
142
157
|
? 'Launch date: ' + page._source.display_date_filter
|
|
@@ -146,6 +161,17 @@ export default defineComponent({
|
|
|
146
161
|
} else if (handle === 'profiles_profilepage') {
|
|
147
162
|
topic = page._source[handle + '__go_site_name']
|
|
148
163
|
date = null
|
|
164
|
+
} else if (handle.startsWith('edu_resources')) {
|
|
165
|
+
date = null
|
|
166
|
+
primarySubject = page._source[handle + '__primary_subject'] as PrimarySubjectObject
|
|
167
|
+
if (page._source[handle + '__grade_levels']) {
|
|
168
|
+
gradeLevels = [] as GradeLevelsObject[]
|
|
169
|
+
// @ts-expect-error
|
|
170
|
+
page._source[handle + '__grade_levels'].forEach((level) => {
|
|
171
|
+
gradeLevels.push({ gradeLevel: level.grade_level })
|
|
172
|
+
})
|
|
173
|
+
}
|
|
174
|
+
time = { time: page._source.activity_time_label_filter } as EduResourcesTime
|
|
149
175
|
} else {
|
|
150
176
|
date =
|
|
151
177
|
typeof page._source.publication_date_filter !== 'undefined'
|
|
@@ -161,9 +187,7 @@ export default defineComponent({
|
|
|
161
187
|
page.topic = topic
|
|
162
188
|
// properties for event's page
|
|
163
189
|
page.location =
|
|
164
|
-
handle === 'events_eventpage'
|
|
165
|
-
? page._source[handle + '__location'] | page._source[handle + '__location_name']
|
|
166
|
-
: null
|
|
190
|
+
handle === 'events_eventpage' ? page._source[handle + '__location'] : location
|
|
167
191
|
page.startDate =
|
|
168
192
|
handle === 'events_eventpage' || handle === 'edu_events_edueventpage'
|
|
169
193
|
? page._source[handle + '__start_datetime']
|
|
@@ -192,6 +216,10 @@ export default defineComponent({
|
|
|
192
216
|
handle === 'edu_events_edueventpage'
|
|
193
217
|
? page._source.edu_events_edueventpage__ongoing
|
|
194
218
|
: undefined
|
|
219
|
+
// edu resources
|
|
220
|
+
page.gradeLevels = gradeLevels
|
|
221
|
+
page.time = time
|
|
222
|
+
page.primarySubject = primarySubject
|
|
195
223
|
// properties that are different for profiles page
|
|
196
224
|
page.summary =
|
|
197
225
|
handle === 'profiles_profilepage'
|
package/src/interfaces.ts
CHANGED
|
@@ -92,6 +92,9 @@ export interface ElasticSearchPage {
|
|
|
92
92
|
summary?: string
|
|
93
93
|
eventType?: string
|
|
94
94
|
ongoing?: boolean
|
|
95
|
+
primarySubject?: string
|
|
96
|
+
gradeLevels: string
|
|
97
|
+
time: string
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
export interface FormOption {
|
|
@@ -129,6 +132,7 @@ export interface EventCardObject extends Card {
|
|
|
129
132
|
eventType?: string
|
|
130
133
|
ongoing?: boolean
|
|
131
134
|
isVirtualEvent?: boolean
|
|
135
|
+
isInPersonEvent?: boolean
|
|
132
136
|
locationName?: string
|
|
133
137
|
location?: string
|
|
134
138
|
locationLink?: string
|
|
@@ -209,7 +209,11 @@ export default defineComponent({
|
|
|
209
209
|
},
|
|
210
210
|
created() {
|
|
211
211
|
const sortByParam = this.$route?.query.sortBy
|
|
212
|
-
if (
|
|
212
|
+
if (
|
|
213
|
+
sortByParam &&
|
|
214
|
+
sortByOptions &&
|
|
215
|
+
sortByOptions.some((option) => option.value === sortByParam)
|
|
216
|
+
) {
|
|
213
217
|
this.sortBy = sortByParam as SortBy
|
|
214
218
|
}
|
|
215
219
|
|
package/src/utils/mixins.ts
CHANGED
|
@@ -194,12 +194,14 @@ export const mixinIsActivePath = (itemPath: string): Boolean => {
|
|
|
194
194
|
*/
|
|
195
195
|
export const mixinGetSrcSet = (srcSetObject: Partial<ImageObject>): string => {
|
|
196
196
|
let srcSet = ''
|
|
197
|
-
const valid = Object.keys(srcSetObject)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
197
|
+
const valid = Object.keys(srcSetObject)?.length
|
|
198
|
+
? Object.keys(srcSetObject).some(function (key) {
|
|
199
|
+
if (key.startsWith('screen')) {
|
|
200
|
+
return true
|
|
201
|
+
}
|
|
202
|
+
return false
|
|
203
|
+
})
|
|
204
|
+
: false
|
|
203
205
|
if (valid) {
|
|
204
206
|
const srcSetArray: string[] = []
|
|
205
207
|
for (const [key, value] of Object.entries(srcSetObject)) {
|
|
@@ -288,14 +290,16 @@ export const mixinLightboxGalleryItems = (items: object | any): object | false =
|
|
|
288
290
|
// return event dates for the red box that appears in the corner of the hero and thumbnail images
|
|
289
291
|
export const mixinFormatSplitEventDates = (
|
|
290
292
|
startDatetime: string,
|
|
291
|
-
endDatetime?: string
|
|
293
|
+
endDatetime?: string,
|
|
294
|
+
compact?: boolean
|
|
292
295
|
): EventDateObject => {
|
|
293
296
|
const startDateDayjs = dayjs(startDatetime)
|
|
294
297
|
|
|
298
|
+
const monthFormat = compact ? 'MM' : 'MMM'
|
|
295
299
|
let day = startDateDayjs.format('D')
|
|
296
|
-
const month = startDateDayjs.format(
|
|
300
|
+
const month = startDateDayjs.format(monthFormat).replace('.', '')
|
|
297
301
|
const year = startDateDayjs.format('YYYY')
|
|
298
|
-
const monthAndYear = startDateDayjs.format(
|
|
302
|
+
const monthAndYear = startDateDayjs.format(`${monthFormat} YYYY`)
|
|
299
303
|
|
|
300
304
|
if (endDatetime) {
|
|
301
305
|
const endDateDayjs = dayjs(endDatetime)
|