<template> <div> <h2>Список баз</h2> <div v-if="loading_error" class="text-danger m-4"> <span class="fs-1">⛔</span><br /> <h3>Ошибка загрузки</h3> </div> <div v-else-if="is_loading" class="container"> <div class="spinner-border text-primary" role="status"> <span class="visually-hidden">Loading...</span> </div> </div> <div v-else-if="0 == infobases.length" class="container"> <div class="alert alert-warning" role="alert"> <svg class="m-2" width="32" height="32"> <use xlink:href="#exclamation-triangle-fill--sprite"></use> </svg> <span>Нет ни одной базы</span> </div> </div> <table v-else class="table table-striped"> <thead> <tr> <th scope="col" class="col">#</th> <th scope="col" class="col-lg-6">Имя</th> <th scope="col" class="col">Ссылка</th> <th scope="col" class="col">Действия</th> </tr> </thead> <tbody> <tr v-for="(infobase, index) in infobases" :key="infobase.name"> <th scope="row">{{ index + 1 }}</th> <td>{{ infobase.name }}</td> <td> <template v-if="infobase.publicated"> <InfobaseURLEditor v-if="is_edit_url_active(infobase.name)" :infobase_name="infobase.name" :key="infobase.name" :init_url="infobase.url" @submit="apply_edit_url" @cancel="cancel_edit_url" /> <a v-else v-bind:href="url_base + infobase.url" target="blank">{{ infobase.url }}</a> </template> </td> <td> <div v-if="!is_edit_url_active(infobase.name)" class="btn-group shadow" role="group" > <button v-if="infobase.publicated" type="button" class="btn btn-warning" @click="start_edit_url(infobase.name)" hint="Изменить URL" > Изменить </button> <button v-if="infobase.publicated" type="button" class="btn btn-danger" @click="remove_publication(infobase.name)" hint="Снять с публикации" > Отменить </button> <button v-else type="button" class="btn btn-primary" @click="publicate(infobase.name)" hint="Опубликовать базу" > Публиковать </button> </div> </td> </tr> </tbody> </table> </div> </template> <script> import "bootstrap-icons/icons/exclamation-triangle-fill.svg?sprite"; import axios from "axios"; import InfobaseURLEditor from "@/components/InfobaseURLEditor.vue"; const api_base = "http://localhost:17653/api/v1"; export default { name: "InfobaseList", components: { InfobaseURLEditor, }, data: () => ({ url_base: "http://localhost:11111", is_loading: true, loading_error: false, infobases: [], url_editors: {}, }), methods: { publicate(name) { let infobase = this.infobases.find((infobase) => name === infobase.name); if (infobase === undefined) return; infobase.publicated = true; }, remove_publication(name) { let infobase = this.infobases.find((infobase) => name === infobase.name); if (infobase === undefined) return; infobase.publicated = false; }, set_url(name, url) { let infobase = this.infobases.find((infobase) => name === infobase.name); if (infobase === undefined) return; infobase.url = url; }, start_edit_url(name) { let infobase = this.infobases.find((infobase) => name === infobase.name); if (infobase === undefined) return; this.url_editors[name] = true; }, cancel_edit_url({name}) { delete this.url_editors[name]; }, apply_edit_url({name, url}) { this.set_url(name, url); delete this.url_editors[name]; }, is_edit_url_active(name) { return name in this.url_editors; }, }, async mounted() { try { const res = await axios.get(`${api_base}/infobases`); if (!res) { return; } const names = res.data; if (!Array.isArray(names)) { this.loading_error = true; return; } if (0 < names.length) { if ("string" !== typeof names[0]) { this.loading_error = true; return; } } this.is_loading = false; this.loading_error = false; this.infobases = names.map((name) => { return { name: name, publicated: "bpdemo" === name, url: "/" }; }); } catch (err) { this.loading_error = true; } }, }; </script>