@explorer-1/vue 0.2.19 → 0.2.20

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@explorer-1/vue",
3
- "version": "0.2.19",
3
+ "version": "0.2.20",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -129,6 +129,54 @@ export const EventItem = {
129
129
  }
130
130
  }
131
131
  }
132
+ export const EventItemWithChip = {
133
+ decorators: [
134
+ () => ({
135
+ template: `<div id="storyDecorator" class="relative grid grid-cols-2 gap-3"><story/></div>`
136
+ })
137
+ ],
138
+ args: {
139
+ ...BlockLinkCardData,
140
+ showCalendarChip: true,
141
+ data: {
142
+ page: {
143
+ ...BlockLinkCardData.data,
144
+ __typename: 'EDUEventPage',
145
+ startDate: '2021-11-11',
146
+ startDatetime: '2021-11-11T00:00:00-08:00',
147
+ endDatetime: '2021-11-11T23:59:59.999999-08:00',
148
+ endDate: '2021-11-11',
149
+ ongoing: false,
150
+ eventType: 'Workshop'
151
+ }
152
+ }
153
+ }
154
+ }
155
+ export const EduLesson = {
156
+ decorators: [
157
+ () => ({
158
+ template: `<div id="storyDecorator" class="relative grid grid-cols-2 gap-3"><story/></div>`
159
+ })
160
+ ],
161
+ args: {
162
+ ...BlockLinkCardData,
163
+ data: {
164
+ page: {
165
+ __typename: 'EDULessonPage',
166
+ ...BlockLinkCardData.data,
167
+ primarySubject: {
168
+ subject: 'Math'
169
+ },
170
+ gradeLevels: [
171
+ { gradeLevel: 'K' },
172
+ { gradeLevel: '1' },
173
+ { gradeLevel: '2' },
174
+ { gradeLevel: '8' }
175
+ ]
176
+ }
177
+ }
178
+ }
179
+ }
132
180
  export const EduExplainerArticle = {
133
181
  decorators: [
134
182
  () => ({
@@ -28,6 +28,7 @@
28
28
  <div v-else></div>
29
29
  <CalendarChip
30
30
  v-if="
31
+ showCalendarChip &&
31
32
  themeStore.isEdu &&
32
33
  ((theItem as EventCardObject).startDate || (theItem as EventCardObject).ongoing)
33
34
  "
@@ -41,7 +42,7 @@
41
42
  class="BlockLinkCard__CardContent transition-translate can-hover:group-hover:delay-200 duration-200 ease-in transform ThemeVariantLight"
42
43
  :class="contentClasses"
43
44
  >
44
- <template v-if="metadataType && metadataAttrs">
45
+ <template v-if="metadataAttrs">
45
46
  <BasePill
46
47
  :class="{ 'mb-2': !large, 'mb-4': large }"
47
48
  size="sm"
@@ -50,6 +51,20 @@
50
51
  {{ (theItem as EventCardObject).eventType }}
51
52
  </BasePill>
52
53
  </template>
54
+ <template
55
+ v-else-if="themeStore.isEdu && theItem.parent?.title && theItem.parent?.title !== 'EDU'"
56
+ >
57
+ <div class="flex flex-wrap">
58
+ <p
59
+ class="text-subtitle"
60
+ :class="small ? 'mb-2' : 'mb-4'"
61
+ >
62
+ <span class="edu:text-primary ThemeVariantLight">
63
+ {{ (theItem as Card).parent?.title }}
64
+ </span>
65
+ </p>
66
+ </div>
67
+ </template>
53
68
  <template v-else>
54
69
  <div class="flex flex-wrap">
55
70
  <p
@@ -96,18 +111,20 @@
96
111
  {{ theItem.summary }}
97
112
  </p>
98
113
  <div
99
- v-if="metadataType && metadataAttrs"
114
+ v-if="metadataAttrs"
100
115
  :class="{ 'mt-4': large, 'mt-2 mb-1': medium, 'mt-1 mb-0': small }"
101
116
  >
102
117
  <MetadataEvent
103
118
  v-if="metadataType === 'EDUEventPage'"
104
119
  :event="theItem"
120
+ :show-time="false"
121
+ :show-location="false"
105
122
  compact
106
123
  />
107
124
  <MetadataEduResource
108
- v-else-if="metadataType === 'EDUExplainerArticlePage'"
125
+ v-else-if="metadataAttrs.type === 'resource'"
109
126
  :resource="theItem as EduResourceCardObject"
110
- :variant="eduMetadataDictionaryComputed[metadataType].variant"
127
+ :variant="metadataAttrs.variant"
111
128
  compact
112
129
  />
113
130
  </div>
@@ -115,11 +132,7 @@
115
132
  <div
116
133
  v-if="!large"
117
134
  class="BlockLinkCard__CardArrow ThemeVariantLight can-hover:block can-hover:-ml-3 can-hover:group-hover:delay-200 can-hover:opacity-0 can-hover:group-hover:ml-0 can-hover:group-hover:opacity-100 hidden -mt-1 text-2xl leading-normal transition-all duration-200 ease-in"
118
- :class="
119
- metadataType && metadataAttrs
120
- ? `text-${eduMetadataDictionaryComputed[metadataType].variant}`
121
- : 'text-primary'
122
- "
135
+ :class="metadataAttrs ? `text-${metadataAttrs.variant}` : 'text-primary'"
123
136
  >
124
137
  <IconArrow />
125
138
  </div>
@@ -234,6 +247,10 @@ export default defineComponent({
234
247
  type: (String as PropType<HeadingLevel>) || null,
235
248
  required: false,
236
249
  default: undefined
250
+ },
251
+ showCalendarChip: {
252
+ type: Boolean,
253
+ default: false
237
254
  }
238
255
  },
239
256
  computed: {
@@ -258,9 +275,6 @@ export default defineComponent({
258
275
  }
259
276
  return classes
260
277
  },
261
- eduMetadataDictionaryComputed() {
262
- return eduMetadataDictionary
263
- },
264
278
  // to allow for various data shapes and sources
265
279
  // use-case: content pages provide this.data.page with non-page siblings (i.e. external link cards)
266
280
  // use-case: search and listing pages pass individual props
@@ -304,12 +318,14 @@ export default defineComponent({
304
318
  return undefined
305
319
  },
306
320
  metadataType() {
321
+ // checks that this is a valid metadata type
307
322
  const validContentTypes = Object.keys(eduMetadataDictionary)
308
323
  return this.data?.page?.__typename && validContentTypes.includes(this.data?.page?.__typename)
309
324
  ? this.data?.page?.__typename
310
325
  : undefined
311
326
  },
312
327
  metadataAttrs() {
328
+ // retrieves attributes for that metadata type
313
329
  if (this.metadataType) {
314
330
  return eduMetadataDictionary[this.metadataType]
315
331
  }
@@ -29,10 +29,13 @@ export default defineComponent({
29
29
  required: false,
30
30
  default: false
31
31
  },
32
-
32
+ startDate: {
33
+ type: String,
34
+ default: undefined
35
+ },
33
36
  startDatetime: {
34
37
  type: String,
35
- required: true
38
+ default: undefined
36
39
  },
37
40
  endDatetime: {
38
41
  type: String,
@@ -76,9 +79,12 @@ export default defineComponent({
76
79
  methods: {
77
80
  init() {
78
81
  let recurrence = undefined
79
- if (this.endDatetime && this.isAllDay) {
82
+ if ((this.isAllDay && this.endDatetime) || (this.startDate && this.endDatetime)) {
83
+ console.log('initing')
80
84
  // Calculate how many full days
81
- const startDateDayjs = dayjs(this.startDatetime)
85
+ const startDateDayjs = this.startDatetime
86
+ ? dayjs(this.startDatetime)
87
+ : dayjs(this.startDate)
82
88
  const endDateDayjs = dayjs(this.endDatetime)
83
89
  const difference = endDateDayjs.diff(startDateDayjs, 'day') + 1
84
90
  recurrence = { frequency: 'DAILY', interval: 1, count: difference }
@@ -88,7 +94,11 @@ export default defineComponent({
88
94
  title: this.title ? this.title : undefined,
89
95
  location: this.location ? this.location : undefined,
90
96
  description: this.icsDescription,
91
- start: new Date(this.startDatetime),
97
+ start: this.startDatetime
98
+ ? new Date(this.startDatetime)
99
+ : this.startDate
100
+ ? new Date(this.startDate)
101
+ : new Date(),
92
102
  end: !this.isAllDay && this.endDatetime ? new Date(this.endDatetime) : undefined,
93
103
  recurrence
94
104
  }
@@ -13,13 +13,17 @@ interface MetadataEventProps {
13
13
  event: EventCardObject
14
14
  compact?: boolean
15
15
  allowBreak?: boolean
16
+ showLocation?: boolean
17
+ showTime?: boolean
16
18
  }
17
19
 
18
20
  // define props
19
21
  const props = withDefaults(defineProps<MetadataEventProps>(), {
20
22
  event: undefined,
21
23
  compact: false,
22
- allowBreak: false
24
+ allowBreak: false,
25
+ showLocation: true,
26
+ showTime: true
23
27
  })
24
28
 
25
29
  const startDatetimeForFormatting = computed(() => {
@@ -35,7 +39,7 @@ const formattedEventDates = computed((): string | undefined => {
35
39
  : undefined
36
40
  })
37
41
  const displayTime = computed((): string => {
38
- if (!props.event.customDate) {
42
+ if (!props.event.customDate && props.event.startTime && props.event.endTime) {
39
43
  const time =
40
44
  props.event && startDatetimeForFormatting.value
41
45
  ? mixinFormatEventTimeInHoursAndMinutes(
@@ -71,60 +75,62 @@ const locationName = computed(() => {
71
75
  }}</span>
72
76
  </div>
73
77
  <div
74
- v-show="displayTime"
78
+ v-show="displayTime && showTime"
75
79
  class="MetadataEventItem"
76
80
  >
77
81
  <IconTime class="MetadataEventIcon text-[1.15em]" />
78
82
  <span>{{ displayTime }}</span>
79
83
  </div>
80
84
  <!--Virtual location -->
81
- <div
82
- v-if="props.event.isVirtualEvent && props.event.locationLink && !props.compact"
83
- itemprop="location"
84
- itemscope
85
- itemtype="https://schema.org/VirtualLocation"
86
- class="MetadataEventItem"
87
- >
88
- <link
89
- itemprop="url"
90
- :href="props.event.locationLink"
91
- />
92
- <meta
93
- itemprop="name"
94
- :content="locationName"
95
- />
96
- <IconLocation class="MetadataEventIcon text-[1.1em]" />
97
- <BaseLink
98
- variant="none"
99
- class="text-action"
100
- :href="props.event.locationLink"
101
- external-target-blank
102
- >
103
- {{ locationName }}
104
- </BaseLink>
105
- </div>
106
- <!-- Normal location -->
107
- <div
108
- v-else-if="locationName"
109
- class="MetadataEventItem"
110
- >
111
- <meta
112
- v-if="!props.compact"
85
+ <template v-if="showLocation">
86
+ <div
87
+ v-if="props.event.isVirtualEvent && props.event.locationLink && !props.compact"
113
88
  itemprop="location"
114
- :content="locationName"
115
- />
116
- <IconLocation class="MetadataEventIcon text-[1.2em]" />
117
- <BaseLink
118
- v-if="props.event.locationLink && !props.compact"
119
- variant="none"
120
- class="text-action"
121
- :href="props.event.locationLink"
122
- external-target-blank
89
+ itemscope
90
+ itemtype="https://schema.org/VirtualLocation"
91
+ class="MetadataEventItem"
123
92
  >
124
- {{ locationName }}
125
- </BaseLink>
126
- <span v-else>{{ locationName }}</span>
127
- </div>
93
+ <link
94
+ itemprop="url"
95
+ :href="props.event.locationLink"
96
+ />
97
+ <meta
98
+ itemprop="name"
99
+ :content="locationName"
100
+ />
101
+ <IconLocation class="MetadataEventIcon text-[1.1em]" />
102
+ <BaseLink
103
+ variant="none"
104
+ class="text-action"
105
+ :href="props.event.locationLink"
106
+ external-target-blank
107
+ >
108
+ {{ locationName }}
109
+ </BaseLink>
110
+ </div>
111
+ <!-- Normal location -->
112
+ <div
113
+ v-else-if="locationName"
114
+ class="MetadataEventItem"
115
+ >
116
+ <meta
117
+ v-if="!props.compact"
118
+ itemprop="location"
119
+ :content="locationName"
120
+ />
121
+ <IconLocation class="MetadataEventIcon text-[1.2em]" />
122
+ <BaseLink
123
+ v-if="props.event.locationLink && !props.compact"
124
+ variant="none"
125
+ class="text-action"
126
+ :href="props.event.locationLink"
127
+ external-target-blank
128
+ >
129
+ {{ locationName }}
130
+ </BaseLink>
131
+ <span v-else>{{ locationName }}</span>
132
+ </div>
133
+ </template>
128
134
  </div>
129
135
  </template>
130
136
  <style lang="scss">
package/src/constants.ts CHANGED
@@ -3,10 +3,17 @@ import type { DictionaryInterface, PillDictionaryInterface } from './interfaces'
3
3
  export const eduMetadataDictionary: PillDictionaryInterface = {
4
4
  EDUExplainerArticlePage: {
5
5
  label: 'Explainer Article',
6
- variant: 'secondary'
6
+ variant: 'secondary',
7
+ type: 'resource'
8
+ },
9
+ EDULessonPage: {
10
+ label: 'Lesson',
11
+ variant: 'primary',
12
+ type: 'resource'
7
13
  },
8
14
  EDUEventPage: {
9
- variant: 'primary'
15
+ variant: 'primary',
16
+ type: 'event'
10
17
  }
11
18
  }
12
19
 
@@ -16,5 +23,6 @@ export const searchContentTypeToPageType: DictionaryInterface = {
16
23
  events_eventpage: 'EventPage',
17
24
  missions_mission: 'Mission',
18
25
  eduevents_edueventpage: 'EDUEventPage',
19
- eduresources_eduexplainerarticlepage: 'EDUExplainerArticlePage'
26
+ eduresources_eduexplainerarticlepage: 'EDUExplainerArticlePage',
27
+ eduresources_edulessonpage: 'EDULessonPage'
20
28
  }
package/src/interfaces.ts CHANGED
@@ -103,6 +103,9 @@ export interface FormOption {
103
103
  export interface Card {
104
104
  __typename?: string
105
105
  type?: string
106
+ parent?: {
107
+ title: string
108
+ }
106
109
  url?: string
107
110
  externalLink?: string
108
111
  page?: Card | EventCardObject | EduResourceCardObject
@@ -192,6 +195,7 @@ export type MetadataType = 'event' | 'resource'
192
195
  export interface LabelObject {
193
196
  label?: string
194
197
  variant: string
198
+ type?: MetadataType
195
199
  }
196
200
  export interface PillDictionaryInterface {
197
201
  [EDUExplainerArticlePage: string]: LabelObject
@@ -43,6 +43,11 @@ export default defineComponent({
43
43
  },
44
44
  computed: {
45
45
  ...mapStores(useThemeStore),
46
+ displayLabel() {
47
+ return this.themeStore.isEdu && this.data?.parent?.title && this.data?.parent?.title !== 'EDU'
48
+ ? this.data?.parent?.title
49
+ : this.data?.displayLabel
50
+ },
46
51
  heroInline() {
47
52
  if (this.data?.heroPosition === 'inline') {
48
53
  return true
@@ -94,7 +99,7 @@ export default defineComponent({
94
99
  >
95
100
  <DetailHeadline
96
101
  :title="data.title"
97
- :label="data.displayLabel"
102
+ :label="displayLabel"
98
103
  :class="{ 'sr-only': hideH1 }"
99
104
  />
100
105
  <ShareButtonsEdu
@@ -28,6 +28,6 @@ export default {
28
28
  export const BaseStory = {
29
29
  name: 'PageContent',
30
30
  args: {
31
- data: ContentPageData
31
+ data: { ...ContentPageData, displayLabel: undefined, parent: { title: 'Parent Page' } }
32
32
  }
33
33
  }
@@ -62,7 +62,6 @@ const PageEduEventDetailData = {
62
62
  detailUrl: null
63
63
  },
64
64
  heroConstrain: false,
65
- heroPosition: 'inline',
66
65
  thumbnailImage: {
67
66
  alt: '',
68
67
  original: 'https://picsum.photos/512/288'
@@ -134,6 +133,19 @@ export const BaseStory = {
134
133
  args: { data: PageEduEventDetailData }
135
134
  }
136
135
 
136
+ export const NoTimes = {
137
+ args: {
138
+ data: {
139
+ ...PageEduEventDetailData,
140
+ endDate: '2024-08-10',
141
+ endDatetime: '2024-08-10T23:59:59.999999-07:00',
142
+ endTime: null,
143
+ startDate: '2024-08-08',
144
+ startDatetime: null,
145
+ startTime: null
146
+ }
147
+ }
148
+ }
137
149
  export const CustomDate = {
138
150
  args: {
139
151
  data: {
@@ -1,10 +1,7 @@
1
1
  <template>
2
2
  <div
3
3
  v-if="data"
4
- class="PageEduEventDetail ThemeVariantLight"
5
- :class="{
6
- 'pt-5 lg:pt-12': heroIsInline
7
- }"
4
+ class="PageEduEventDetail ThemeVariantLight pt-5 lg:pt-12"
8
5
  itemscope
9
6
  itemtype="http://schema.org/Event"
10
7
  >
@@ -28,23 +25,6 @@
28
25
  itemprop="description"
29
26
  :content="data.summary || data.body"
30
27
  />
31
- <div
32
- v-if="!heroIsInline"
33
- class="relative max-w-screen-3xl mx-auto -mt-1"
34
- >
35
- <!-- hero image -->
36
- <HeroMedia
37
- class="md:mb-12 lg:mb-18 mb-10"
38
- :image="data.eventImage"
39
- :constrain="data.heroConstrain"
40
- />
41
- <CalendarChip
42
- v-if="startDatetimeForFormatting"
43
- :start-date="startDatetimeForFormatting"
44
- :end-date="data.endDatetime"
45
- :ongoing="data.ongoing"
46
- />
47
- </div>
48
28
  <LayoutHelper
49
29
  indent="col-2"
50
30
  class="mb-6 lg:mb-12"
@@ -83,7 +63,7 @@
83
63
 
84
64
  <LayoutHelper indent="col-2">
85
65
  <EventDetailHero
86
- v-if="heroIsInline"
66
+ v-if="data?.eventImage"
87
67
  :image="data.eventImage"
88
68
  :start-date="startDatetimeForFormatting"
89
69
  :end-date="data.endDate"
@@ -121,7 +101,8 @@
121
101
  <!-- Todo IF VIRTUAL EVENT passes url as string to location prop -->
122
102
  <!-- location= location name and link -->
123
103
  <CalendarButton
124
- v-if="data.startDatetime"
104
+ v-if="(data.startDatetime || data.endDatetime) && !data.ongoing"
105
+ :start-date="data.startDate"
125
106
  :start-datetime="data.startDatetime"
126
107
  :end-datetime="data.endDatetime ? data.endDatetime : null"
127
108
  :title="data.title ? data.title : null"
@@ -281,7 +262,6 @@ import BaseHeading from './../../../components/BaseHeading/BaseHeading.vue'
281
262
  import BasePill from './../../../components/BasePill/BasePill.vue'
282
263
  import ShareButtonsEdu from './../../../components/ShareButtonsEdu/ShareButtonsEdu.vue'
283
264
  import EventDetailHero from './../../../components/EventDetailHero/EventDetailHero.vue'
284
- import HeroMedia from './../../../components/HeroMedia/HeroMedia.vue'
285
265
  import BaseLink from './../../../components/BaseLink/BaseLink.vue'
286
266
  import BaseButton from './../../../components/BaseButton/BaseButton.vue'
287
267
  import CalendarButton from './../../../components/CalendarButton/CalendarButton.vue'
@@ -291,7 +271,6 @@ import BaseImage from './../../../components/BaseImage/BaseImage.vue'
291
271
  import BlockRelatedLinks from './../../../components/BlockRelatedLinks/BlockRelatedLinks.vue'
292
272
  import BlockLinkCarousel from './../../../components/BlockLinkCarousel/BlockLinkCarousel.vue'
293
273
  import BlockText from './../../../components/BlockText/BlockText.vue'
294
- import CalendarChip from './../../../components/CalendarChip/CalendarChip.vue'
295
274
  import MetadataEvent from './../../../components/MetadataEvent/MetadataEvent.vue'
296
275
 
297
276
  // @ts-ignore
@@ -305,7 +284,6 @@ export default defineComponent({
305
284
  BasePill,
306
285
  ShareButtonsEdu,
307
286
  EventDetailHero,
308
- HeroMedia,
309
287
  BaseLink,
310
288
  BaseButton,
311
289
  CalendarButton,
@@ -315,7 +293,6 @@ export default defineComponent({
315
293
  BlockRelatedLinks,
316
294
  BlockLinkCarousel,
317
295
  BlockText,
318
- CalendarChip,
319
296
  MetadataEvent
320
297
  },
321
298
  props: {
@@ -334,9 +311,6 @@ export default defineComponent({
334
311
  startDatetimeForFormatting(): string {
335
312
  return this.data?.startDatetime || this.data?.startDate
336
313
  },
337
- heroIsInline(): boolean {
338
- return this.data?.heroPosition === 'inline'
339
- },
340
314
  relatedEvents(): EventCardObject[] {
341
315
  // mimic the data shape of a PageChooserBlock array
342
316
  const mapped = this.data?.relatedEvents
@@ -8,6 +8,8 @@ import advancedFormat from 'dayjs/plugin/advancedFormat.js'
8
8
  // see https://github.com/iamkun/dayjs/tree/dev/src/locale
9
9
  import 'dayjs/locale/en-gb.js'
10
10
 
11
+ dayjs.extend(timezone)
12
+ dayjs.extend(advancedFormat)
11
13
  dayjs.extend(localizedFormat)
12
14
  dayjs.extend(updateLocale)
13
15
  dayjs.updateLocale('en', {
@@ -26,7 +28,5 @@ dayjs.updateLocale('en', {
26
28
  'Dec.'
27
29
  ]
28
30
  })
29
- dayjs.extend(timezone)
30
- dayjs.extend(advancedFormat)
31
31
 
32
32
  export default dayjs
@@ -63,7 +63,7 @@ export const rangeifyGrades = (gradeLevels: GradeLevelsObject[]) => {
63
63
  const filteredGrades = rangeify(gradesArray.filter(Number.isFinite))
64
64
  let preparedGrades: string = ''
65
65
  if (filteredGrades?.length) {
66
- const gradeString = filteredGrades.length > 1 ? 'Grades: ' : 'Grade: '
66
+ const gradeString = filteredGrades.length > 0 ? 'Grades: ' : 'Grade: '
67
67
  preparedGrades = filteredGrades
68
68
  .map((grade, index) => (index === 0 ? gradeString + grade : grade))
69
69
  .join(', ')