Skip to content

Commit ad4c814

Browse files
authored
Add result kind to the SELECT_SEARCH_RESULT event (#3173)
1 parent ed3748e commit ad4c814

File tree

14 files changed

+61
-47
lines changed

14 files changed

+61
-47
lines changed

frontend/src/components/VAudioDetails/VRelatedAudio.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<VAudioCollection
77
:results="media"
88
:fetch-state="fetchState"
9-
:is-related="true"
9+
kind="related"
1010
:collection-label="$t('audioDetails.relatedAudios').toString()"
1111
class="mb-12"
1212
/>

frontend/src/components/VImageCell/VImageCell.vue

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import { computed, defineComponent, PropType } from "vue"
6565
6666
import type { AspectRatio, ImageDetail } from "~/types/media"
67+
import type { ResultKind } from "~/types/result"
6768
import { useImageCellSize } from "~/composables/use-image-cell-size"
6869
import { useI18n } from "~/composables/use-i18n"
6970
import { useAnalytics } from "~/composables/use-analytics"
@@ -111,6 +112,10 @@ export default defineComponent({
111112
type: String as PropType<AspectRatio>,
112113
default: "square",
113114
},
115+
kind: {
116+
type: String as PropType<ResultKind>,
117+
default: "search",
118+
},
114119
relatedTo: {
115120
type: [String, null] as PropType<string | null>,
116121
default: null,
@@ -179,6 +184,7 @@ export default defineComponent({
179184
const sendSelectSearchResultEvent = () => {
180185
sendCustomEvent("SELECT_SEARCH_RESULT", {
181186
id: props.image.id,
187+
kind: props.kind,
182188
mediaType: IMAGE,
183189
provider: props.image.provider,
184190
query: props.searchTerm || "",

frontend/src/components/VImageDetails/VRelatedImages.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
{{ $t("imageDetails.relatedImages") }}
55
</h2>
66
<VImageGrid
7-
:images="media"
8-
:is-single-page="true"
7+
kind="related"
8+
:results="media"
99
:fetch-state="fetchState"
1010
:image-grid-label="$t('imageDetails.relatedImages').toString()"
1111
/>

frontend/src/components/VSearchResultsGrid/VAudioCollection.vue

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
</VSnackbar>
1919
<VAudioList
2020
:collection-label="collectionLabel"
21-
:is-related="isRelated"
21+
:kind="kind"
2222
:results="results"
2323
/>
24-
<footer v-if="!isRelated" class="mt-4">
24+
<footer v-if="kind !== 'related'" class="mt-4">
2525
<VLoadMore />
2626
</footer>
2727
</section>
@@ -32,6 +32,7 @@ import { defineComponent, PropType } from "vue"
3232
3333
import type { AudioDetail } from "~/types/media"
3434
import type { FetchState } from "~/types/fetch-state"
35+
import type { ResultKind } from "~/types/result"
3536
import { useAudioSnackbar } from "~/composables/use-audio-snackbar"
3637
3738
import VAudioList from "~/components/VSearchResultsGrid/VAudioList.vue"
@@ -59,8 +60,8 @@ export default defineComponent({
5960
/**
6061
* If used for Related audio, do not show the Load more button.
6162
*/
62-
isRelated: {
63-
type: Boolean,
63+
kind: {
64+
type: String as PropType<ResultKind>,
6465
required: true,
6566
},
6667
fetchState: {

frontend/src/components/VSearchResultsGrid/VAudioList.vue

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<ol
44
:aria-label="collectionLabel"
55
class="-mx-2 flex flex-col md:-mx-4"
6-
:class="isRelated ? 'gap-4' : 'gap-2 md:gap-1'"
6+
:class="kind === 'related' ? 'gap-4' : 'gap-2 md:gap-1'"
77
>
88
<VAudioResult
99
v-for="audio in results"
@@ -12,7 +12,7 @@
1212
:audio="audio"
1313
layout="row"
1414
:size="audioTrackSize"
15-
:is-related="isRelated"
15+
:kind="kind"
1616
/>
1717
</ol>
1818
</template>
@@ -21,6 +21,7 @@
2121
import { computed, defineComponent, PropType } from "vue"
2222
2323
import type { AudioDetail } from "~/types/media"
24+
import type { ResultKind } from "~/types/result"
2425
import { useSearchStore } from "~/stores/search"
2526
import { useUiStore } from "~/stores/ui"
2627
@@ -37,8 +38,8 @@ export default defineComponent({
3738
type: Array as PropType<AudioDetail[]>,
3839
default: () => [],
3940
},
40-
isRelated: {
41-
type: Boolean,
41+
kind: {
42+
type: String as PropType<ResultKind>,
4243
required: true,
4344
},
4445
/**
@@ -53,7 +54,7 @@ export default defineComponent({
5354
const uiStore = useUiStore()
5455
5556
const audioTrackSize = computed(() => {
56-
if (props.isRelated) {
57+
if (props.kind === "related") {
5758
return uiStore.isBreakpoint("md") ? "l" : "s"
5859
} else {
5960
return !uiStore.isDesktopLayout

frontend/src/components/VSearchResultsGrid/VAudioResult.vue

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import type { AudioInteractionData } from "~/types/analytics"
2525
import type { AudioLayout, AudioSize } from "~/constants/audio"
2626
import type { AudioTrackClickEvent } from "~/types/events"
2727
import type { AudioDetail } from "~/types/media"
28+
import type { ResultKind } from "~/types/result"
2829
2930
import VAudioTrack from "~/components/VAudioTrack/VAudioTrack.vue"
3031
@@ -48,9 +49,9 @@ export default defineComponent({
4849
type: String,
4950
required: true,
5051
},
51-
isRelated: {
52-
type: Boolean,
53-
required: true,
52+
kind: {
53+
type: String as PropType<ResultKind>,
54+
default: "search",
5455
},
5556
},
5657
setup(props) {
@@ -69,6 +70,7 @@ export default defineComponent({
6970
useAudioSnackbar().hide()
7071
sendCustomEvent("SELECT_SEARCH_RESULT", {
7172
id: audio.id,
73+
kind: props.kind,
7274
mediaType: AUDIO,
7375
query: props.searchTerm,
7476
provider: audio.provider,
@@ -80,11 +82,12 @@ export default defineComponent({
8082
const sendInteractionEvent = (
8183
data: Omit<AudioInteractionData, "component">
8284
) => {
83-
const component = props.isRelated
84-
? "VRelatedAudio"
85-
: props.layout === "box"
86-
? "VAllResultsGrid"
87-
: "AudioSearch"
85+
const component =
86+
props.kind === "related"
87+
? "VRelatedAudio"
88+
: props.layout === "box"
89+
? "VAllResultsGrid"
90+
: "AudioSearch"
8891
sendCustomEvent("AUDIO_INTERACTION", { ...data, component })
8992
}
9093

frontend/src/components/VSearchResultsGrid/VImageGrid.vue

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
<template>
22
<section class="pt-2 sm:pt-0">
33
<VGridSkeleton
4-
v-if="images && !images.length && !fetchState.isFinished"
4+
v-if="results && !results.length && !fetchState.isFinished"
55
is-for-tab="image"
66
/>
77
<ol class="image-grid flex flex-wrap gap-4" :aria-label="imageGridLabel">
88
<VImageCell
9-
v-for="image in images"
9+
v-for="image in results"
1010
:key="image.id"
1111
:image="image"
1212
:search-term="searchTerm"
1313
aspect-ratio="intrinsic"
14+
:kind="kind"
1415
:related-to="relatedTo"
1516
/>
1617
</ol>
17-
<footer v-if="!isSinglePage" class="pt-4">
18+
<footer v-if="kind !== 'related'" class="pt-4">
1819
<VLoadMore />
1920
</footer>
2021
</section>
@@ -24,8 +25,7 @@
2425
/**
2526
* This component receives an array of images as a prop, and
2627
* is responsible for displaying them as a grid.
27-
* It can also fetch more images when 'Load More' clicked,
28-
* or display 'No More Media'.
28+
* It can also fetch more images when 'Load More' is clicked.
2929
* Used to display both image search results, and related images.
3030
*/
3131
import { computed, defineComponent, PropType } from "vue"
@@ -35,6 +35,7 @@ import { useRelatedMediaStore } from "~/stores/media/related-media"
3535
3636
import type { FetchState } from "~/types/fetch-state"
3737
import type { ImageDetail } from "~/types/media"
38+
import type { ResultKind } from "~/types/result"
3839
3940
import VGridSkeleton from "~/components/VSkeleton/VGridSkeleton.vue"
4041
import VLoadMore from "~/components/VLoadMore.vue"
@@ -44,19 +45,18 @@ export default defineComponent({
4445
name: "ImageGrid",
4546
components: { VGridSkeleton, VLoadMore, VImageCell },
4647
props: {
47-
images: {
48+
results: {
4849
type: Array as PropType<ImageDetail[]>,
4950
default: () => [],
5051
},
5152
/**
52-
* VImageGrid is used for the search grid and the related images.
53-
* In the related images, it is just a single page of results without the
54-
* "Load More" button, and in the search grid it is a grid that can load
55-
* more images on the "Load More" button click.
53+
* `VImageGrid` is used for the image search results, related images,
54+
* and the image collection page.
55+
* The load more button is not shown for related images.
5656
*/
57-
isSinglePage: {
58-
type: Boolean,
59-
required: true,
57+
kind: {
58+
type: String as PropType<ResultKind>,
59+
default: "search",
6060
},
6161
fetchState: {
6262
type: Object as PropType<FetchState>,
@@ -73,7 +73,9 @@ export default defineComponent({
7373
const searchTerm = computed(() => searchStore.searchTerm)
7474
7575
const relatedTo = computed(() => {
76-
return props.isSinglePage ? useRelatedMediaStore().mainMediaId : null
76+
return props.kind === "related"
77+
? useRelatedMediaStore().mainMediaId
78+
: null
7779
})
7880
7981
return { searchTerm, relatedTo }

frontend/src/pages/search/audio.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<template>
22
<VAudioCollection
33
:results="results"
4-
:is-related="false"
4+
kind="search"
55
:fetch-state="fetchState"
66
:collection-label="collectionLabel"
77
/>

frontend/src/pages/search/image.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<template>
22
<VImageGrid
3-
:images="results"
4-
:is-single-page="false"
3+
:results="results"
54
:fetch-state="fetchState"
5+
kind="search"
66
:image-grid-label="
77
$t('browsePage.aria.results', { query: searchTerm }).toString()
88
"

frontend/src/types/analytics.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
} from "~/constants/media"
66
import type { ReportReason } from "~/constants/content-report"
77
import type { FilterCategory } from "~/constants/filters"
8+
import { ResultKind } from "~/types/result"
89

910
export type AudioInteraction = "play" | "pause" | "seek"
1011
export type AudioInteractionData = Exclude<
@@ -254,6 +255,8 @@ export type Events = {
254255
id: string
255256
/** If the result is a related result, provide the ID of the 'original' result */
256257
relatedTo: string | null
258+
/** Kind of the result selected: search/related/collection */
259+
kind: ResultKind
257260
/** The media type being searched */
258261
mediaType: SearchType
259262
/** The slug (not the prettified name) of the provider */

frontend/src/types/external-source.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

frontend/src/types/result.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export type ResultKind = "search" | "related" | "collection"

frontend/test/playwright/e2e/all-results-analytics.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ test.describe("all results grid analytics test", () => {
2525
expectEventPayloadToMatch(selectSearchResultEvent, {
2626
mediaType: AUDIO,
2727
query: "birds",
28+
kind: "search",
2829
relatedTo: null,
2930
id: "2e38ac1e-830c-4e9c-b13d-2c9a1ad53f95",
3031
provider: "jamendo",
@@ -45,6 +46,7 @@ test.describe("all results grid analytics test", () => {
4546

4647
expectEventPayloadToMatch(selectSearchResultEvent, {
4748
id: "da5cb478-c093-4d62-b721-cda18797e3fb",
49+
kind: "search",
4850
mediaType: IMAGE,
4951
query: "birds",
5052
provider: "flickr",

frontend/test/unit/specs/components/v-image-grid.spec.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { render } from "~~/test/unit/test-utils/render"
55
import VImageGrid from "~/components/VSearchResultsGrid/VImageGrid.vue"
66

77
const propsData = {
8-
images: [
8+
results: [
99
{ id: "i1", url: "http://localhost:8080/i1.png", title: "image1" },
1010
{ id: "i2", url: "http://localhost:8080/i2.jpg", title: "image2" },
1111
{ id: "i3", url: "http://localhost:8080/i3.svg", title: "image3" },
@@ -15,7 +15,7 @@ const propsData = {
1515
isFetching: false,
1616
fetchingError: null,
1717
},
18-
isSinglePage: true,
18+
kind: "related",
1919
imageGridLabel: "Image Results",
2020
}
2121

@@ -28,11 +28,10 @@ describe("VImageGrid", () => {
2828
}
2929
})
3030
it("renders images without load more button for related images", () => {
31+
const imageCount = propsData.results.length
3132
render(VImageGrid, options)
32-
expect(screen.queryAllByRole("img").length).toEqual(propsData.images.length)
33-
expect(screen.queryAllByRole("figure").length).toEqual(
34-
propsData.images.length
35-
)
33+
expect(screen.queryAllByRole("img").length).toEqual(imageCount)
34+
expect(screen.queryAllByRole("figure").length).toEqual(imageCount)
3635
expect(screen.queryByTestId("load-more")).toBeNull()
3736
})
3837
})

0 commit comments

Comments
 (0)