Skip to content

Commit acaa022

Browse files
authored
Merge pull request #211 from openzim/events-fix
display events in view
2 parents 3d8fefb + 1e756e7 commit acaa022

2 files changed

Lines changed: 90 additions & 68 deletions

File tree

frontend/src/components/BookTable.vue

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
<template>
22
<div>
33
<v-card v-if="!errors.length" :class="{ loading: loading }" flat>
4-
<v-card-title
5-
v-if="showSelection || $slots.actions"
6-
class="d-flex flex-column-reverse flex-sm-row align-sm-center justify-sm-end ga-2"
7-
>
8-
<slot name="actions" />
9-
<v-btn
10-
v-if="showSelection"
11-
size="small"
12-
variant="elevated"
13-
color="warning"
14-
:disabled="selectedBooks.length === 0"
15-
@click="clearSelections"
16-
>
17-
<v-icon size="small" class="mr-1">mdi-checkbox-multiple-blank-outline</v-icon>
18-
clear selections
19-
</v-btn>
20-
</v-card-title>
21-
224
<v-data-table-server
235
:headers="headers"
246
:items="books"
@@ -31,9 +13,6 @@
3113
:density="smAndDown ? 'compact' : 'comfortable'"
3214
class="elevation-1"
3315
item-value="name"
34-
:show-select="showSelection"
35-
:model-value="selectedBooks"
36-
@update:model-value="handleSelectionChange"
3716
@update:options="onUpdateOptions"
3817
:hide-default-footer="props.paginator.count === 0"
3918
:hide-default-header="props.paginator.count === 0"
@@ -83,7 +62,6 @@ import BookStatus from '@/components/BookStatus.vue'
8362
import type { Paginator } from '@/types/base'
8463
import { formatDt } from '@/utils/format'
8564
import type { BookLight, LocationKind } from '@/types/book'
86-
import { computed } from 'vue'
8765
import { useRouter, useRoute } from 'vue-router'
8866
import { useDisplay } from 'vuetify'
8967
@@ -105,14 +83,11 @@ interface Props {
10583
location_kind: string
10684
flag: string
10785
}
108-
selectedBooks?: string[]
109-
showSelection?: boolean
11086
showFilters?: boolean
11187
}
11288
11389
const props = withDefaults(defineProps<Props>(), {
11490
filters: () => ({ id: '', location_kind: '', flag: '' }),
115-
selectedBooks: () => [],
11691
showSelection: true,
11792
showFilters: true,
11893
})
@@ -121,7 +96,6 @@ const props = withDefaults(defineProps<Props>(), {
12196
const emit = defineEmits<{
12297
limitChanged: [limit: number]
12398
loadData: [limit: number, skip: number]
124-
selectionChanged: [selectedBooks: string[]]
12599
}>()
126100
127101
const limits = [10, 20, 50, 100]
@@ -134,8 +108,6 @@ const locationKindColors: Record<LocationKind, string> = {
134108
deleted: 'red-lighten-1',
135109
}
136110
137-
const selectedBooks = computed(() => props.selectedBooks)
138-
139111
function onUpdateOptions(options: { page: number; itemsPerPage: number }) {
140112
const query = { ...route.query }
141113
@@ -151,12 +123,4 @@ function onUpdateOptions(options: { page: number; itemsPerPage: number }) {
151123
emit('limitChanged', options.itemsPerPage)
152124
}
153125
}
154-
155-
function handleSelectionChange(selection: string[]) {
156-
emit('selectionChanged', selection)
157-
}
158-
159-
function clearSelections() {
160-
emit('selectionChanged', [])
161-
}
162126
</script>

frontend/src/views/InboxView.vue

Lines changed: 90 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<!-- Inbox View showing a list of books and zimfarm notifications -->
1+
<!-- Inbox View showing a list of books, zimfarm notifications, and events -->
22

33
<template>
44
<TabsList :active-tab="currentTab" :tab-options="tabOptions" @tab-changed="handleTabChange" />
@@ -15,6 +15,12 @@
1515
@filters-changed="handleZimfarmFiltersChange"
1616
@clear-filters="clearFilters"
1717
/>
18+
<EventFilters
19+
v-if="currentTab == 'events'"
20+
:filters="eventFilters"
21+
@filters-changed="handleEventFiltersChange"
22+
@clear-filters="clearFilters"
23+
/>
1824
<BookTable
1925
v-show="currentTab == 'books'"
2026
:headers="headers"
@@ -24,12 +30,9 @@
2430
:loading-text="loadingStore.loadingText"
2531
:errors="errors"
2632
:filters="bookFilters"
27-
:selected-books="selectedBooks"
28-
:show-selection="true"
2933
:show-filters="true"
3034
@limit-changed="handleLimitChange"
3135
@load-data="loadData"
32-
@selection-changed="handleSelectionChanged"
3336
/>
3437
<ZimfarmNotificationTable
3538
v-show="currentTab == 'zimfarm_notifications'"
@@ -40,11 +43,19 @@
4043
:loading-text="loadingStore.loadingText"
4144
:errors="errors"
4245
:filters="zimfarmFilters"
43-
:selected-zimfarm-notifications="selectedZimfarmNotifications"
44-
:show-selection="true"
4546
@limit-changed="handleLimitChange"
4647
@load-data="loadData"
47-
@selection-changed="handleSelectionChanged"
48+
/>
49+
<EventTable
50+
v-show="currentTab == 'events'"
51+
:headers="headers"
52+
:events="events"
53+
:paginator="paginator"
54+
:loading="loadingStore.isLoading"
55+
:loading-text="loadingStore.loadingText"
56+
:errors="errors"
57+
@limit-changed="handleLimitChange"
58+
@load-data="loadData"
4859
/>
4960
</template>
5061

@@ -54,11 +65,15 @@ import BookFilters from '@/components/BookFilters.vue'
5465
import BookTable from '@/components/BookTable.vue'
5566
import ZimfarmNotificationFilters from '@/components/ZimfarmNotificationFilters.vue'
5667
import ZimfarmNotificationTable from '@/components/ZimfarmNotificationTable.vue'
68+
import EventFilters from '@/components/EventFilters.vue'
69+
import EventTable from '@/components/EventTable.vue'
5770
import { useLoadingStore } from '@/stores/loading'
5871
import { useBookStore } from '@/stores/book'
5972
import { useZimfarmNotificationStore } from '@/stores/zimfarmNotification'
73+
import { useEventStore } from '@/stores/event'
6074
import type { BookLight } from '@/types/book'
6175
import type { ZimfarmNotificationLight } from '@/types/zimfarmNotification'
76+
import type { EventLight } from '@/types/event'
6277
import type { Paginator } from '@/types/base'
6378
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
6479
import { useRouter, useRoute } from 'vue-router'
@@ -68,12 +83,14 @@ const route = useRoute()
6883
6984
const bookStore = useBookStore()
7085
const zimfarmNotificationStore = useZimfarmNotificationStore()
86+
const eventStore = useEventStore()
7187
const loadingStore = useLoadingStore()
7288
7389
// Filter options
7490
const tabOptions = [
7591
{ value: 'books', label: 'BOOKS' },
7692
{ value: 'zimfarm_notifications', label: 'ZIMFARM NOTIFICATIONS' },
93+
{ value: 'events', label: 'EVENTS' },
7794
]
7895
7996
// Define headers for the table
@@ -92,6 +109,12 @@ const headers = computed(() => {
92109
{ title: 'Received', value: 'received_at' },
93110
{ title: 'Status', value: 'status' },
94111
]
112+
case 'events':
113+
return [
114+
{ title: 'ID', value: 'id' },
115+
{ title: 'Created', value: 'created_at' },
116+
{ title: 'Topic', value: 'topic' },
117+
]
95118
default:
96119
return []
97120
}
@@ -102,12 +125,22 @@ const currentTab = computed(() => {
102125
return (Array.isArray(tab) ? tab[0] : tab) || 'books'
103126
})
104127
105-
const defaultLimit = computed(() =>
106-
currentTab.value == 'book' ? bookStore.defaultLimit : zimfarmNotificationStore.defaultLimit,
107-
)
128+
const defaultLimit = computed(() => {
129+
switch (currentTab.value) {
130+
case 'books':
131+
return bookStore.defaultLimit
132+
case 'zimfarm_notifications':
133+
return zimfarmNotificationStore.defaultLimit
134+
case 'events':
135+
return eventStore.defaultLimit
136+
default:
137+
return 20
138+
}
139+
})
108140
109141
const books = ref<BookLight[]>([])
110142
const zimfarmNotifications = ref<ZimfarmNotificationLight[]>([])
143+
const events = ref<EventLight[]>([])
111144
const paginator = ref<Paginator>({
112145
page: Number(route.query.page) || 1,
113146
page_size: defaultLimit.value,
@@ -151,9 +184,19 @@ const zimfarmFilters = computed(() => {
151184
return derived
152185
})
153186
187+
const eventFilters = computed(() => {
188+
const query = router.currentRoute.value.query
189+
const derived = {
190+
topic: '',
191+
}
192+
if (query.topic && typeof query.topic === 'string') {
193+
derived.topic = query.topic
194+
}
195+
196+
return derived
197+
})
198+
154199
const intervalId = ref<number | null>(null)
155-
const selectedBooks = ref<string[]>([])
156-
const selectedZimfarmNotifications = ref<string[]>([])
157200
158201
const handleTabChange = (newTab: string) => {
159202
// Navigate to the new tab route
@@ -164,23 +207,28 @@ const handleTabChange = (newTab: string) => {
164207
})
165208
}
166209
167-
// Clear selections when switching tabs
168-
watch(currentTab, () => {
169-
selectedBooks.value = []
170-
selectedZimfarmNotifications.value = []
171-
})
172-
173210
async function loadData(limit: number, skip: number, tab?: string, hideLoading: boolean = false) {
174211
if (!tab) {
175212
tab = currentTab.value
176213
}
177214
178215
if (!hideLoading) {
179-
loadingStore.startLoading(
180-
tab === 'books' ? 'Fetching books...' : 'Fetching zimfarm notifications...',
181-
)
216+
let loadingText = 'Fetching data...'
217+
switch (tab) {
218+
case 'books':
219+
loadingText = 'Fetching books...'
220+
break
221+
case 'zimfarm_notifications':
222+
loadingText = 'Fetching zimfarm notifications...'
223+
break
224+
case 'events':
225+
loadingText = 'Fetching events...'
226+
break
227+
}
228+
loadingStore.startLoading(loadingText)
182229
books.value = []
183230
zimfarmNotifications.value = []
231+
events.value = []
184232
}
185233
186234
switch (tab) {
@@ -213,6 +261,13 @@ async function loadData(limit: number, skip: number, tab?: string, hideLoading:
213261
zimfarmNotificationStore.savePaginatorLimit(limit)
214262
paginator.value = { ...zimfarmNotificationStore.paginator }
215263
break
264+
case 'events':
265+
await eventStore.fetchEvents(limit, skip, eventFilters.value.topic || undefined)
266+
events.value = eventStore.events
267+
errors.value = eventStore.errors
268+
eventStore.savePaginatorLimit(limit)
269+
paginator.value = { ...eventStore.paginator }
270+
break
216271
default:
217272
throw new Error(`Invalid tab: ${tab}`)
218273
}
@@ -230,6 +285,9 @@ async function handleLimitChange(newLimit: number) {
230285
case 'zimfarm_notifications':
231286
zimfarmNotificationStore.savePaginatorLimit(newLimit)
232287
break
288+
case 'events':
289+
eventStore.savePaginatorLimit(newLimit)
290+
break
233291
}
234292
235293
if (paginator.value.page != 1) {
@@ -245,7 +303,7 @@ async function handleLimitChange(newLimit: number) {
245303
}
246304
247305
function updateUrlFilters(
248-
sourceFilters: typeof bookFilters.value | typeof ZimfarmNotificationFilters.value,
306+
sourceFilters: typeof bookFilters.value | typeof zimfarmFilters.value | typeof eventFilters.value,
249307
) {
250308
// create query object from selected filters
251309
const query: Record<string, string | string[]> = {}
@@ -255,7 +313,7 @@ function updateUrlFilters(
255313
query.tab = currentTab.value
256314
}
257315
258-
if (sourceFilters.id) {
316+
if ('id' in sourceFilters && sourceFilters.id) {
259317
query.id = sourceFilters.id
260318
}
261319
@@ -267,6 +325,10 @@ function updateUrlFilters(
267325
query.flag = sourceFilters.flag
268326
}
269327
328+
if ('topic' in sourceFilters && sourceFilters.topic) {
329+
query.topic = sourceFilters.topic
330+
}
331+
270332
router.push({
271333
name: route.name,
272334
query: Object.keys(query).length > 0 ? query : undefined,
@@ -281,6 +343,9 @@ async function clearFilters() {
281343
case 'zimfarm_notifications':
282344
updateUrlFilters({ id: '' })
283345
break
346+
case 'events':
347+
updateUrlFilters({ topic: '' })
348+
break
284349
}
285350
}
286351
@@ -292,15 +357,8 @@ async function handleZimfarmFiltersChange(newFilters: typeof zimfarmFilters.valu
292357
updateUrlFilters(newFilters)
293358
}
294359
295-
function handleSelectionChanged(newSelection: string[]) {
296-
switch (currentTab.value) {
297-
case 'books':
298-
selectedBooks.value = newSelection
299-
break
300-
case 'zimfarm_notifications':
301-
selectedZimfarmNotifications.value = newSelection
302-
break
303-
}
360+
async function handleEventFiltersChange(newFilters: typeof eventFilters.value) {
361+
updateUrlFilters(newFilters)
304362
}
305363
306364
watch(

0 commit comments

Comments
 (0)