176 lines
5.2 KiB
Vue
176 lines
5.2 KiB
Vue
<template>
|
||
<div class="container-fluid">
|
||
<div v-if="errorMessage" class="container">
|
||
<div class="alert alert-danger d-flex align-items-center" role="alert">
|
||
<svg
|
||
class="bi flex-shrink-0 me-2"
|
||
width="24"
|
||
height="24"
|
||
role="img"
|
||
aria-label="Danger:"
|
||
>
|
||
<use xlink:href="#exclamation-triangle-fill--sprite" />
|
||
</svg>
|
||
<span v-text="errorMessage"></span>
|
||
</div> </div>
|
||
<h2>Список баз</h2>
|
||
<div v-if="isLoadingError" class="m-4 alert alert-danger d-flex align-items-center" role="alert">
|
||
<svg
|
||
class="bi flex-shrink-0 me-2"
|
||
width="32"
|
||
height="32"
|
||
role="img"
|
||
aria-label="Danger:"
|
||
>
|
||
<use xlink:href="#exclamation-triangle-fill--sprite" />
|
||
</svg>
|
||
<span>Ошибка загрузки</span>
|
||
</div>
|
||
<div v-else-if="isLoading" class="container">
|
||
<div class="spinner-border text-primary" role="status">
|
||
<span class="visually-hidden">Loading...</span>
|
||
</div>
|
||
</div>
|
||
<div v-else-if="0 == allInfobases.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 allInfobases" :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 { mapGetters, mapMutations, mapActions } from "vuex";
|
||
|
||
import InfobaseURLEditor from "@/components/InfobaseURLEditor.vue";
|
||
|
||
export default {
|
||
name: "InfobaseList",
|
||
components: {
|
||
InfobaseURLEditor,
|
||
},
|
||
data: () => ({
|
||
url_base: "http://localhost:11111",
|
||
is_loading: true,
|
||
loading_error: false,
|
||
infobases: [],
|
||
url_editors: {},
|
||
}),
|
||
computed: mapGetters([
|
||
"allInfobases",
|
||
"getInfobaseByName",
|
||
"isLoading",
|
||
"isLoadingError",
|
||
"errorMessage",
|
||
]),
|
||
methods: {
|
||
...mapMutations({
|
||
set_url: "setInfobaseURL",
|
||
set_publication: "setInfobasePublication",
|
||
}),
|
||
...mapActions({
|
||
set_url: "updateInfobaseURL",
|
||
}),
|
||
add_publication(name) {
|
||
this.set_publication({ name, publicated: true });
|
||
},
|
||
remove_publication(name) {
|
||
this.set_publication({ name, publicated: false });
|
||
},
|
||
start_edit_url(name) {
|
||
let infobase = this.getInfobaseByName(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() {
|
||
this.$store.dispatch("fetchInfobases");
|
||
},
|
||
};
|
||
</script>
|