Skip to content

Commit

Permalink
Add harvest jobs page (#233)
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaudDauce authored Dec 31, 2024
1 parent 8a1729f commit e181084
Show file tree
Hide file tree
Showing 9 changed files with 499 additions and 109 deletions.
90 changes: 30 additions & 60 deletions components/Harvesters/AdminHarvestersPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,43 @@
>
<td>
<AdminContentWithTooltip>
<a
<NuxtLinkLocale
class="fr-link fr-reset-link"
:href="getHarvesterLinkToAdmin(harvester)"
:href="getHarvesterAdminUrl(harvester)"
>
<TextClamp
:text="harvester.name"
:auto-resize="true"
:max-lines="2"
/>
</a>
</NuxtLinkLocale>
</AdminContentWithTooltip>
</td>
<td>
<AdminBadge
v-if="harvester.validation.state === 'refused'"
size="xs"
:type="getStatus(harvester).type"
type="danger"
>
{{ getStatus(harvester).label }}
{{ $t('Refused') }}
</AdminBadge>
<AdminBadge
v-else-if="harvester.validation.state === 'pending'"
size="xs"
type="warning"
>
{{ $t('Waiting validation') }}
</AdminBadge>
<JobBadge
v-else-if="harvester.last_job"
:job="harvester.last_job"
/>
<AdminBadge
v-else
size="xs"
type="secondary"
>
{{ $t('No job yet') }}
</AdminBadge>
</td>
<td>{{ formatDate(harvester.created_at) }}</td>
Expand Down Expand Up @@ -143,11 +162,13 @@ import { formatDate, Pagination, type Organization } from '@datagouv/components'
import { refDebounced } from '@vueuse/core'
import { computed, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import type { AdminBadgeState, AdminBadgeType, DiscussionSortedBy, PaginatedArray, SortDirection } from '~/types/types'
import JobBadge from './JobBadge.vue'
import type { PaginatedArray } from '~/types/types'
import Breadcrumb from '~/components/Breadcrumb/Breadcrumb.vue'
import AdminTable from '~/components/AdminTable/Table/AdminTable.vue'
import AdminTableTh from '~/components/AdminTable/Table/AdminTableTh.vue'
import type { HarvesterJob, HarvesterSource } from '~/types/harvesters'
import { getHarvesterAdminUrl } from '~/utils/harvesters'
const props = defineProps<{
organization?: Organization | null
Expand All @@ -158,9 +179,6 @@ const { $api } = useNuxtApp()
const page = ref(1)
const pageSize = ref(10)
const sortedBy = ref<DiscussionSortedBy>('created')
const direction = ref<SortDirection>('desc')
const sortDirection = computed(() => `${direction.value === 'asc' ? '' : '-'}${sortedBy.value}`)
const q = ref('')
const qDebounced = refDebounced(q, 500) // TODO add 500 in config
Expand All @@ -172,7 +190,6 @@ const url = computed(() => {
}
url.searchParams.set('deleted', 'true')
url.searchParams.set('sort', sortDirection.value)
url.searchParams.set('q', qDebounced.value)
url.searchParams.set('page_size', pageSize.value.toString())
url.searchParams.set('page', page.value.toString())
Expand All @@ -194,17 +211,15 @@ watchEffect(async () => {
jobsPromises.value[source.last_job.id] = $api<HarvesterJob>(`/api/1/harvest/job/${source.last_job.id}/`)
.then((job) => {
jobs.value[source.last_job.id] = job // Working because there is no conflicts between IDs from different types
if (source.last_job) {
jobs.value[source.last_job.id] = job // Working because there is no conflicts between IDs from different types
}
})
}
await Promise.all(Object.values(jobsPromises.value))
})
function getHarvesterLinkToAdmin(harvester: HarvesterSource) {
return `${config.public.apiBase}/en/admin/harvester/${harvester.id}/`
}
function getHarvesterDataservices(harvester: HarvesterSource) {
if (!harvester.last_job || !jobs.value[harvester.last_job.id]) {
return 0
Expand All @@ -218,49 +233,4 @@ function getHarvesterDatasets(harvester: HarvesterSource) {
}
return jobs.value[harvester.last_job.id].items.filter(item => item.dataset).length
}
function getStatus(harvester: HarvesterSource): { label: string, type: AdminBadgeType } {
switch (harvester.last_job?.status) {
case 'pending':
return {
label: t('Pending'),
type: 'secondary',
}
case 'initializing':
return {
label: t('Initializing'),
type: 'primary',
}
case 'initialized':
return {
label: t('Initialized'),
type: 'secondary',
}
case 'processing':
return {
label: t('Processing'),
type: 'primary',
}
case 'done':
return {
label: t('Done'),
type: 'success',
}
case 'done-errors':
return {
label: t('Done with errors'),
type: 'warning',
}
case 'failed':
return {
label: t('Failed'),
type: 'danger',
}
default:
return {
label: t('No job yet'),
type: 'secondary',
}
}
}
</script>
61 changes: 61 additions & 0 deletions components/Harvesters/JobBadge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<AdminBadge
size="xs"
:type="status.type"
>
{{ status.label }}
</AdminBadge>
</template>

<script setup lang="ts">
import type { HarvesterJob } from '~/types/harvesters'
import type { AdminBadgeType } from '~/types/types'
const props = defineProps<{
job: HarvesterJob
}>()
const { t } = useI18n()
const status = computed< { label: string, type: AdminBadgeType }>(() => {
switch (props.job.status) {
case 'pending':
return {
label: t('Pending'),
type: 'secondary',
}
case 'initializing':
return {
label: t('Initializing'),
type: 'primary',
}
case 'initialized':
return {
label: t('Initialized'),
type: 'secondary',
}
case 'processing':
return {
label: t('Processing'),
type: 'primary',
}
case 'done':
return {
label: t('Done'),
type: 'success',
}
case 'done-errors':
return {
label: t('Done with errors'),
type: 'warning',
}
case 'failed':
return {
label: t('Failed'),
type: 'danger',
}
default:
return throwOnNever(props.job.status, 'Unknown job status')
}
})
</script>
12 changes: 12 additions & 0 deletions lang/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,18 @@
"{n} posts": "{n} posts | {n} post | {n} posts",
"Published the {date}": "Published the {date}",
"Posts": "Posts",
"{n} jobs": "{n} jobs | {n} job | {n} jobs",
"Job ID": "Job ID",
"Started at": "Started at",
"Ended at": "Ended at",
"Run": "Run",
"Schedule:": "Schedule:",
"URL:": "URL:",
"Implementation:": "Implementation:",
"Done items": "Done items",
"Skipped items": "Skipped items",
"Archived items": "Archived items",
"Failed items": "Failed items",
"Unarchive the dataservice": "Unarchive the dataservice",
"Archive the dataservice": "Archive the dataservice",
"An archived dataservice is no longer indexed but still accessible for users with the direct link.": "An archived dataservice is no longer indexed but still accessible for users with the direct link.",
Expand Down
12 changes: 12 additions & 0 deletions lang/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,18 @@
"{n} posts": "{n} posts | {n} post | {n} posts",
"Published the {date}": "Published the {date}",
"Posts": "Posts",
"{n} jobs": "{n} jobs | {n} job | {n} jobs",
"Job ID": "Job ID",
"Started at": "Started at",
"Ended at": "Ended at",
"Run": "Run",
"Schedule:": "Schedule:",
"URL:": "URL:",
"Implementation:": "Implementation:",
"Done items": "Done items",
"Skipped items": "Skipped items",
"Archived items": "Archived items",
"Failed items": "Failed items",
"Unarchive the dataservice": "Unarchive the dataservice",
"Archive the dataservice": "Archive the dataservice",
"An archived dataservice is no longer indexed but still accessible for users with the direct link.": "An archived dataservice is no longer indexed but still accessible for users with the direct link.",
Expand Down
14 changes: 13 additions & 1 deletion lang/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@
"Initialized": "Initialisé",
"Processing": "En traitement",
"Done": "Terminé",
"Done with errors": "",
"Done with errors": "Terminé avec des erreurs",
"Failed": "Échoué",
"No job yet": "Aucun job pour l'instant",
"See the organization page": "Voir la page de l'organisation",
Expand Down Expand Up @@ -787,6 +787,18 @@
"{n} posts": "{n} articles | {n} article | {n} articles",
"Published the {date}": "Publié le {date}",
"Posts": "Articles",
"{n} jobs": "{n} jobs | {n} job | {n} jobs",
"Job ID": "Job ID",
"Started at": "Débuté le",
"Ended at": "Terminé le",
"Run": "Exécuter",
"Schedule:": "Planning :",
"URL:": "URL :",
"Implementation:": "Implémentation :",
"Done items": "Éléments finis",
"Skipped items": "Éléments ignorés",
"Archived items": "Éléments archivés",
"Failed items": "Éléments en échec",
"Unarchive the dataservice": "Désarchiver cette API",
"Archive the dataservice": "Archiver cette API",
"An archived dataservice is no longer indexed but still accessible for users with the direct link.": "Une API archivée n'est plus indexée mais reste accessible aux utilisateurs avec un lien direct.",
Expand Down
Loading

0 comments on commit e181084

Please sign in to comment.