183 lines
5.3 KiB
Vue
183 lines
5.3 KiB
Vue
<template>
|
||
<div class="container-fluid">
|
||
<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 text-end">#</th>
|
||
<th scope="col" class="col text-center">Имя</th>
|
||
<th scope="col" class="col text-start">Ссылка</th>
|
||
<th scope="col" class="col text-end">Действия</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="(infobase, index) in infobases" :key="infobase.name">
|
||
<th class="text-end" scope="row">{{ index + 1 }}</th>
|
||
<td class="text-center">{{ infobase.name }}</td>
|
||
<td class="text-start">
|
||
<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
|
||
class="text-break"
|
||
v-if="!is_edit_url_active(infobase.name)"
|
||
v-bind:href="url_base + infobase.url"
|
||
target="blank"
|
||
>{{ infobase.url }}</a
|
||
>
|
||
</template>
|
||
</td>
|
||
<td class="text-end">
|
||
<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)"
|
||
title="Изменить URL"
|
||
>
|
||
Изменить
|
||
</button>
|
||
<button
|
||
v-if="infobase.publicated"
|
||
type="button"
|
||
class="btn btn-danger"
|
||
@click="remove_publication(infobase.name)"
|
||
title="Снять с публикации"
|
||
>
|
||
Отменить
|
||
</button>
|
||
<button
|
||
v-if="!infobase.publicated"
|
||
type="button"
|
||
class="btn btn-primary"
|
||
@click="add_publication(infobase.name)"
|
||
title="Опубликовать базу"
|
||
>
|
||
Публиковать
|
||
</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: {
|
||
infobase(name) {
|
||
return this.infobases.find((infobase) => name === infobase.name);
|
||
},
|
||
add_publication(name) {
|
||
let infobase = this.infobase(name);
|
||
if (infobase === undefined) return;
|
||
|
||
infobase.publicated = true;
|
||
},
|
||
remove_publication(name) {
|
||
let infobase = this.infobase(name);
|
||
if (infobase === undefined) return;
|
||
|
||
infobase.publicated = false;
|
||
},
|
||
set_url(name, url) {
|
||
let infobase = this.infobase(name);
|
||
if (infobase === undefined) return;
|
||
|
||
infobase.url = url;
|
||
},
|
||
start_edit_url(name) {
|
||
let infobase = this.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>
|