Skip to content

Commit e957d05

Browse files
committed
Add remove filter. Lint and type-check
1 parent 901cf3d commit e957d05

File tree

8 files changed

+90
-25
lines changed

8 files changed

+90
-25
lines changed

src/main/kotlin/no/java/conf/model/search/SessionResponse.kt

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import kotlinx.serialization.Serializable
44

55
@Serializable
66
data class SessionResponse(
7+
val id: String,
78
val title: String,
89
val video: String?,
910
val year: Int,

web/src/components/AggregateCard.vue

+16-1
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,22 @@ import type {AggregateCardRow} from "@/types/helpers";
44
const props = defineProps<{
55
title: string
66
aggregate: AggregateCardRow[]
7+
filter?: string
78
}>()
89
910
const emit = defineEmits<{
1011
filter: [value: string]
12+
clear: []
1113
}>()
1214
1315
const performFilter = (value: string) => {
1416
emit('filter', value)
1517
}
1618
19+
const clearFilter = () => {
20+
emit('clear')
21+
}
22+
1723
</script>
1824

1925
<template>
@@ -24,7 +30,16 @@ const performFilter = (value: string) => {
2430
</v-card-title>
2531
</v-card-item>
2632
<v-card-text>
27-
<v-row v-for="row in props.aggregate" align="center" dense>
33+
<v-row v-if="props.filter">
34+
<v-col class="text-body-2">
35+
<v-icon icon="far fa-window-close" @click="clearFilter()"/>
36+
<div class="filter-link pl-2 d-inline-block" @click="clearFilter()">
37+
{{ props.filter }}
38+
</div>
39+
</v-col>
40+
41+
</v-row>
42+
<v-row v-else v-for="row in props.aggregate" :key="row.code" align="center" dense>
2843
<v-col class="text-body-2">
2944
<div class="filter-link" @click="performFilter(row.code)">{{ row.name }}</div>
3045
</v-col>

web/src/components/AggregateTotals.vue

+29-6
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,24 @@ import type {AggregateCardRow} from "@/types/helpers";
77
88
const props = defineProps<{
99
aggregate: Aggregate
10+
filteredYear?: number
11+
filteredLanguage?: string
12+
filteredFormat?: string
1013
}>()
1114
1215
const emit = defineEmits<{
1316
filterYear: [year: number]
1417
filterFormat: [format: string]
1518
filterLanguage: [language: string]
19+
clear: [filter: string]
1620
}>()
1721
1822
const languageRow = computed(() => {
1923
return props.aggregate.languages.map((item) => {
2024
return {
2125
code: item.language,
2226
name: displayLanguage(item.language),
23-
count: item.count
27+
count: item.count,
2428
} as AggregateCardRow
2529
}
2630
)
@@ -31,7 +35,7 @@ const formatRow = computed(() => {
3135
return {
3236
code: item.format,
3337
name: displayFormat(item.format),
34-
count: item.count
38+
count: item.count,
3539
} as AggregateCardRow
3640
}
3741
)
@@ -42,7 +46,7 @@ const yearRow = computed(() => {
4246
return {
4347
code: item.year.toString(),
4448
name: item.year.toString(),
45-
count: item.count
49+
count: item.count,
4650
} as AggregateCardRow
4751
}
4852
)
@@ -64,12 +68,31 @@ const applyFilter = (filter: string, code: string) => {
6468
}
6569
}
6670
}
71+
72+
const clearFilter = (filter: string) => {
73+
emit('clear', filter)
74+
}
75+
6776
</script>
6877

6978
<template>
7079
<div v-if="props.aggregate">
71-
<AggregateCard title="Languages" :aggregate="languageRow" @filter="applyFilter('LANGUAGE', $event)"/>
72-
<AggregateCard title="Formats" :aggregate="formatRow" @filter="applyFilter('FORMAT', $event)"/>
73-
<AggregateCard title="Years" :aggregate="yearRow" @filter="applyFilter('YEAR', $event)"/>
80+
<AggregateCard title="Languages"
81+
:aggregate="languageRow"
82+
@filter="applyFilter('LANGUAGE', $event)"
83+
@clear="clearFilter('LANGUAGE')"
84+
:filter="displayLanguage(filteredLanguage)"/>
85+
86+
<AggregateCard title="Formats"
87+
:aggregate="formatRow"
88+
@filter="applyFilter('FORMAT', $event)"
89+
@clear="clearFilter('FORMAT')"
90+
:filter="displayFormat(filteredFormat)"/>
91+
92+
<AggregateCard title="Years"
93+
:aggregate="yearRow"
94+
@filter="applyFilter('YEAR', $event)"
95+
@clear="clearFilter('YEAR')"
96+
:filter="filteredYear?.toString()"/>
7497
</div>
7598
</template>

web/src/components/SessionItem.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const props = defineProps<{
3737
<div class="text-h5">Speakers</div>
3838
</div>
3939

40-
<div v-for="speaker in props.session.speakers" class="mt-2 mb-2">
40+
<div v-for="speaker in props.session.speakers" :key="speaker.name" class="mt-2 mb-2">
4141
<div class="text-h6">{{ speaker.name }}</div>
4242

4343
<p v-if="speaker.bio">{{ speaker.bio }}</p>

web/src/types/aggregates.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
export function displayLanguage(lang: string) {
1+
export function displayLanguage(lang?: string) {
2+
if (lang === undefined) {
3+
return undefined
4+
}
5+
26
switch (lang) {
37
case 'NO': {
48
return "Norwegian";
@@ -12,7 +16,11 @@ export function displayLanguage(lang: string) {
1216
}
1317
}
1418

15-
export function displayFormat(format: string) {
19+
export function displayFormat(format?: string) {
20+
if (format === undefined) {
21+
return undefined
22+
}
23+
1624
switch (format) {
1725
case 'PRESENTATION': {
1826
return "Presentation";

web/src/types/api.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export interface Speaker {
1111
}
1212

1313
export interface Session {
14+
id: string
1415
title: string
1516
video?: string
1617
year: number

web/src/views/AllVideosView.vue

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import {computed, onMounted, ref} from 'vue'
2+
import {onMounted, ref} from 'vue'
33
import type {Video} from "@/types/api";
44
55
const data = ref<Video[]>([])
@@ -12,23 +12,13 @@ onMounted(() => {
1212
.then((response) => response.json())
1313
.then((res) => (data.value = res))
1414
})
15-
16-
const items = computed(() => {
17-
return data.value.map((video) => {
18-
return {
19-
title: video.title,
20-
year: video.year,
21-
link: video.video
22-
}
23-
})
24-
})
2515
</script>
2616

2717
<template>
2818
<div class="text-h4 ma-3">All Videos</div>
2919

30-
<v-data-table :items="items" items-per-page="100">
31-
<template v-slot:item.link="{ value }">
20+
<v-data-table :items="data" items-per-page="100">
21+
<template #[`item.video`]="{ value }">
3222
<v-btn>
3323
<a :href="value">
3424
<v-icon icon="fas fa-video"/>

web/src/views/SearchView.vue

+29-2
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,25 @@ const filterLanguage = (language: string) => {
7373
performSearch()
7474
}
7575
76+
const clearFilter = (filter: string) => {
77+
switch (filter) {
78+
case "LANGUAGE": {
79+
filteredLanguage.value = undefined
80+
break;
81+
}
82+
case "FORMAT": {
83+
filteredFormat.value = undefined
84+
break;
85+
}
86+
case "YEAR": {
87+
filteredYear.value = undefined
88+
break;
89+
}
90+
}
91+
92+
performSearch()
93+
}
94+
7695
</script>
7796

7897
<template>
@@ -106,13 +125,21 @@ const filterLanguage = (language: string) => {
106125
name="drawer"
107126
permanent
108127
>
109-
<AggregateTotals v-if="data && data?.aggregateResponse" :aggregate="data?.aggregateResponse" @filterYear="filterYear" @filterFormat="filterFormat" @filterLanguage="filterLanguage"/>
128+
<AggregateTotals v-if="data && data?.aggregateResponse"
129+
:aggregate="data?.aggregateResponse"
130+
@filterYear="filterYear"
131+
@filterFormat="filterFormat"
132+
@filterLanguage="filterLanguage"
133+
@clear="clearFilter"
134+
:filteredFormat="filteredFormat"
135+
:filteredLanguage="filteredLanguage"
136+
:filteredYear="filteredYear"/>
110137
</v-navigation-drawer>
111138

112139

113140
<div>
114141
<div class="d-flex flex-row flex-wrap justify-center">
115-
<SessionItem v-for="session in data?.sessionsResponse" :session="session"/>
142+
<SessionItem v-for="session in data?.sessionsResponse" :key="session.id" :session="session"/>
116143
</div>
117144
</div>
118145
</template>

0 commit comments

Comments
 (0)