Skip to content

Commit

Permalink
Add result kind to the SELECT_SEARCH_RESULT event
Browse files Browse the repository at this point in the history
  • Loading branch information
obulat committed Oct 10, 2023
1 parent 3bb5bff commit 623c97c
Show file tree
Hide file tree
Showing 14 changed files with 61 additions and 47 deletions.
2 changes: 1 addition & 1 deletion frontend/src/components/VAudioDetails/VRelatedAudio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<VAudioCollection
:results="media"
:fetch-state="fetchState"
:is-related="true"
kind="related"
:collection-label="$t('audioDetails.relatedAudios').toString()"
class="mb-12"
/>
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/components/VImageCell/VImageCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
import { computed, defineComponent, PropType } from "vue"
import type { AspectRatio, ImageDetail } from "~/types/media"
import type { ResultKind } from "~/types/result"
import { useImageCellSize } from "~/composables/use-image-cell-size"
import { useI18n } from "~/composables/use-i18n"
import { useAnalytics } from "~/composables/use-analytics"
Expand Down Expand Up @@ -107,6 +108,10 @@ export default defineComponent({
type: String as PropType<AspectRatio>,
default: "square",
},
kind: {
type: String as PropType<ResultKind>,
default: "search",
},
relatedTo: {
type: [String, null] as PropType<string | null>,
default: null,
Expand Down Expand Up @@ -175,6 +180,7 @@ export default defineComponent({
const sendSelectSearchResultEvent = () => {
sendCustomEvent("SELECT_SEARCH_RESULT", {
id: props.image.id,
kind: props.kind,
mediaType: IMAGE,
provider: props.image.provider,
query: props.searchTerm || "",
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/VImageDetails/VRelatedImages.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
{{ $t("imageDetails.relatedImages") }}
</h2>
<VImageGrid
:images="media"
:is-single-page="true"
kind="related"
:results="media"
:fetch-state="fetchState"
:image-grid-label="$t('imageDetails.relatedImages').toString()"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
</VSnackbar>
<VAudioList
:collection-label="collectionLabel"
:is-related="isRelated"
:kind="kind"
:results="results"
/>
<footer v-if="!isRelated" class="mt-4">
<footer v-if="kind !== 'related'" class="mt-4">
<VLoadMore />
</footer>
</section>
Expand All @@ -32,6 +32,7 @@ import { defineComponent, PropType } from "vue"
import type { AudioDetail } from "~/types/media"
import type { FetchState } from "~/types/fetch-state"
import type { ResultKind } from "~/types/result"
import { useAudioSnackbar } from "~/composables/use-audio-snackbar"
import VAudioList from "~/components/VSearchResultsGrid/VAudioList.vue"
Expand Down Expand Up @@ -59,8 +60,8 @@ export default defineComponent({
/**
* If used for Related audio, do not show the Load more button.
*/
isRelated: {
type: Boolean,
kind: {
type: String as PropType<ResultKind>,
required: true,
},
fetchState: {
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/components/VSearchResultsGrid/VAudioList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<ol
:aria-label="collectionLabel"
class="-mx-2 flex flex-col md:-mx-4"
:class="isRelated ? 'gap-4' : 'gap-2 md:gap-1'"
:class="kind === 'related' ? 'gap-4' : 'gap-2 md:gap-1'"
>
<VAudioResult
v-for="audio in results"
Expand All @@ -12,7 +12,7 @@
:audio="audio"
layout="row"
:size="audioTrackSize"
:is-related="isRelated"
:kind="kind"
/>
</ol>
</template>
Expand All @@ -21,6 +21,7 @@
import { computed, defineComponent, PropType } from "vue"
import type { AudioDetail } from "~/types/media"
import type { ResultKind } from "~/types/result"
import { useSearchStore } from "~/stores/search"
import { useUiStore } from "~/stores/ui"
Expand All @@ -37,8 +38,8 @@ export default defineComponent({
type: Array as PropType<AudioDetail[]>,
default: () => [],
},
isRelated: {
type: Boolean,
kind: {
type: String as PropType<ResultKind>,
required: true,
},
/**
Expand All @@ -53,7 +54,7 @@ export default defineComponent({
const uiStore = useUiStore()
const audioTrackSize = computed(() => {
if (props.isRelated) {
if (props.kind === "related") {
return uiStore.isBreakpoint("md") ? "l" : "s"
} else {
return !uiStore.isDesktopLayout
Expand Down
19 changes: 11 additions & 8 deletions frontend/src/components/VSearchResultsGrid/VAudioResult.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import type { AudioInteractionData } from "~/types/analytics"
import type { AudioLayout, AudioSize } from "~/constants/audio"
import type { AudioTrackClickEvent } from "~/types/events"
import type { AudioDetail } from "~/types/media"
import type { ResultKind } from "~/types/result"
import VAudioTrack from "~/components/VAudioTrack/VAudioTrack.vue"
Expand All @@ -48,9 +49,9 @@ export default defineComponent({
type: String,
required: true,
},
isRelated: {
type: Boolean,
required: true,
kind: {
type: String as PropType<ResultKind>,
default: "search",
},
},
setup(props) {
Expand All @@ -69,6 +70,7 @@ export default defineComponent({
useAudioSnackbar().hide()
sendCustomEvent("SELECT_SEARCH_RESULT", {
id: audio.id,
kind: props.kind,
mediaType: AUDIO,
query: props.searchTerm,
provider: audio.provider,
Expand All @@ -80,11 +82,12 @@ export default defineComponent({
const sendInteractionEvent = (
data: Omit<AudioInteractionData, "component">
) => {
const component = props.isRelated
? "VRelatedAudio"
: props.layout === "box"
? "VAllResultsGrid"
: "AudioSearch"
const component =
props.kind === "related"
? "VRelatedAudio"
: props.layout === "box"
? "VAllResultsGrid"
: "AudioSearch"
sendCustomEvent("AUDIO_INTERACTION", { ...data, component })
}
Expand Down
30 changes: 16 additions & 14 deletions frontend/src/components/VSearchResultsGrid/VImageGrid.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
<template>
<section class="pt-2 sm:pt-0">
<VGridSkeleton
v-if="images && !images.length && !fetchState.isFinished"
v-if="results && !results.length && !fetchState.isFinished"
is-for-tab="image"
/>
<ol class="image-grid flex flex-wrap gap-4" :aria-label="imageGridLabel">
<VImageCell
v-for="image in images"
v-for="image in results"
:key="image.id"
:image="image"
:search-term="searchTerm"
aspect-ratio="intrinsic"
:kind="kind"
:related-to="relatedTo"
/>
</ol>
<footer v-if="!isSinglePage" class="pt-4">
<footer v-if="kind !== 'related'" class="pt-4">
<VLoadMore />
</footer>
</section>
Expand All @@ -24,8 +25,7 @@
/**
* This component receives an array of images as a prop, and
* is responsible for displaying them as a grid.
* It can also fetch more images when 'Load More' clicked,
* or display 'No More Media'.
* It can also fetch more images when 'Load More' is clicked.
* Used to display both image search results, and related images.
*/
import { computed, defineComponent, PropType } from "vue"
Expand All @@ -35,6 +35,7 @@ import { useRelatedMediaStore } from "~/stores/media/related-media"
import type { FetchState } from "~/types/fetch-state"
import type { ImageDetail } from "~/types/media"
import type { ResultKind } from "~/types/result"
import VGridSkeleton from "~/components/VSkeleton/VGridSkeleton.vue"
import VLoadMore from "~/components/VLoadMore.vue"
Expand All @@ -44,19 +45,18 @@ export default defineComponent({
name: "ImageGrid",
components: { VGridSkeleton, VLoadMore, VImageCell },
props: {
images: {
results: {
type: Array as PropType<ImageDetail[]>,
default: () => [],
},
/**
* VImageGrid is used for the search grid and the related images.
* In the related images, it is just a single page of results without the
* "Load More" button, and in the search grid it is a grid that can load
* more images on the "Load More" button click.
* `VImageGrid` is used for the image search results, related images,
* and the image collection page.
* The load more button is not shown for related images.
*/
isSinglePage: {
type: Boolean,
required: true,
kind: {
type: String as PropType<ResultKind>,
default: "search",
},
fetchState: {
type: Object as PropType<FetchState>,
Expand All @@ -73,7 +73,9 @@ export default defineComponent({
const searchTerm = computed(() => searchStore.searchTerm)
const relatedTo = computed(() => {
return props.isSinglePage ? useRelatedMediaStore().mainMediaId : null
return props.kind === "related"
? useRelatedMediaStore().mainMediaId
: null
})
return { searchTerm, relatedTo }
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/search/audio.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<VAudioCollection
:results="results"
:is-related="false"
kind="search"
:fetch-state="fetchState"
:collection-label="collectionLabel"
/>
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/pages/search/image.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<VImageGrid
:images="results"
:is-single-page="false"
:results="results"
:fetch-state="fetchState"
kind="search"
:image-grid-label="
$t('browsePage.aria.results', { query: searchTerm }).toString()
"
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/types/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type {
} from "~/constants/media"
import type { ReportReason } from "~/constants/content-report"
import type { FilterCategory } from "~/constants/filters"
import { ResultKind } from "~/types/result"

export type AudioInteraction = "play" | "pause" | "seek"
export type AudioInteractionData = Exclude<
Expand Down Expand Up @@ -254,6 +255,8 @@ export type Events = {
id: string
/** If the result is a related result, provide the ID of the 'original' result */
relatedTo: string | null
/** Kind of the result selected: search/related/collection */
kind: ResultKind
/** The media type being searched */
mediaType: SearchType
/** The slug (not the prettified name) of the provider */
Expand Down
4 changes: 0 additions & 4 deletions frontend/src/types/external-source.ts

This file was deleted.

1 change: 1 addition & 0 deletions frontend/src/types/result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type ResultKind = "search" | "related" | "collection"
2 changes: 2 additions & 0 deletions frontend/test/playwright/e2e/all-results-analytics.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ test.describe("all results grid analytics test", () => {
expectEventPayloadToMatch(selectSearchResultEvent, {
mediaType: AUDIO,
query: "birds",
kind: "search",
relatedTo: null,
id: "2e38ac1e-830c-4e9c-b13d-2c9a1ad53f95",
provider: "jamendo",
Expand All @@ -45,6 +46,7 @@ test.describe("all results grid analytics test", () => {

expectEventPayloadToMatch(selectSearchResultEvent, {
id: "da5cb478-c093-4d62-b721-cda18797e3fb",
kind: "search",
mediaType: IMAGE,
query: "birds",
provider: "flickr",
Expand Down
11 changes: 5 additions & 6 deletions frontend/test/unit/specs/components/v-image-grid.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { render } from "~~/test/unit/test-utils/render"
import VImageGrid from "~/components/VSearchResultsGrid/VImageGrid.vue"

const propsData = {
images: [
results: [
{ id: "i1", url: "http://localhost:8080/i1.png", title: "image1" },
{ id: "i2", url: "http://localhost:8080/i2.jpg", title: "image2" },
{ id: "i3", url: "http://localhost:8080/i3.svg", title: "image3" },
Expand All @@ -15,7 +15,7 @@ const propsData = {
isFetching: false,
fetchingError: null,
},
isSinglePage: true,
kind: "related",
imageGridLabel: "Image Results",
}

Expand All @@ -28,11 +28,10 @@ describe("VImageGrid", () => {
}
})
it("renders images without load more button for related images", () => {
const imageCount = propsData.results.length
render(VImageGrid, options)
expect(screen.queryAllByRole("img").length).toEqual(propsData.images.length)
expect(screen.queryAllByRole("figure").length).toEqual(
propsData.images.length
)
expect(screen.queryAllByRole("img").length).toEqual(imageCount)
expect(screen.queryAllByRole("figure").length).toEqual(imageCount)
expect(screen.queryByTestId("load-more")).toBeNull()
})
})

0 comments on commit 623c97c

Please sign in to comment.