<template> <main class="container is-fluid"> <h1 class="title">Repositories</h1> <h2 class="subtitle">Manage Git repositories</h2> <Paginator :response="reposPage" v-slot="{ results }" :loading="loading" > <table class="table is-fullwidth is-hoverable"> <thead> <tr> <th>URL</th> <th>Workers</th> <th v-if="hasFeature('enterprise')">Users</th> <th v-if="isVerified">Actions</th> </tr> </thead> <tbody> <Row v-for="repo in results" :key="repo.id" :repo="repo" v-on:remove="repoDeletion = repo" /> </tbody> </table> </Paginator> <DeleteModal v-if="repoDeletion" v-model:modal="deleteModal" :repo="repoDeletion" v-on:delete="handleDeletion" /> </main> </template> <script lang="ts"> import { defineComponent } from 'vue' import { useRepositoryStore, useNotificationStore } from '@/stores' import { mapActions, mapState } from 'pinia' import { mapGetters } from 'vuex' import { errorParser } from '@/helpers' import Paginator from '@/components/Paginator.vue' import Row from '@/components/Repos/Row.vue' import DeleteModal from '@/components/Repos/DeleteModal.vue' import { PageNumberPagination } from '@/types' import { Repository } from '@/types/worker' const Component = defineComponent({ components: { Paginator, Row, DeleteModal }, data: () => ({ loading: false, // Stores a repository to delete. Automatically prompt the deletion modal repoDeletion: null as Repository | null, deleteModal: false, reposPage: null as PageNumberPagination<Repository> | null }), beforeRouteEnter ({ query }, from, next) { /* * In order to not get typing error related to 'vm', we name the component which allos us to tell TypeScript that vm * is of the same type as that component. */ next(vm => (vm as InstanceType<typeof Component>).updatePage(parseInt(`${query.page ?? 1}`))) }, beforeRouteUpdate ({ query }) { this.updatePage(parseInt(`${query.page ?? 1}`)) }, computed: { ...mapGetters('auth', ['isVerified', 'hasFeature']), ...mapState(useRepositoryStore, ['repositories']) }, methods: { ...mapActions(useNotificationStore, ['notify']), ...mapActions(useRepositoryStore, ['listRepository']), async updatePage (page: number) { this.loading = true try { this.reposPage = await this.listRepository(page) } catch (err) { this.notify({ type: 'error', text: `An error occurred listing repositories: ${errorParser(err)}` }) } finally { this.loading = false } }, handleDeletion () { // Reload repositories page this.repoDeletion = null this.updatePage(parseInt(`${this.$route.query.page ?? 1}`)) } }, watch: { repoDeletion (repo) { if (repo) this.deleteModal = true }, deleteModal (open) { if (!open) this.repoDeletion = null } } }) export default Component </script>