checkpoint
This commit is contained in:
parent
937785991f
commit
241066587d
11
package.json
11
package.json
@ -5,10 +5,17 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
"build": "vue-cli-service build",
|
"build": "vue-cli-service build",
|
||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint",
|
||||||
|
"mock": "yarn run json-server -S ./test/mock/api -p 17653 -d 1700 -i name -w -r ./test/mock/api/routes.json ./test/mock/api/db.json",
|
||||||
|
"serve-all": "yarn run concurrently -k \"yarn run serve\" \"yarn run mock\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@popperjs/core": "^2.9.2",
|
||||||
|
"axios": "^0.21.1",
|
||||||
|
"bootstrap": "^5.0.1",
|
||||||
|
"bootstrap-icons": "^1.5.0",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
"jquery": "^3.6.0",
|
||||||
"vue": "^3.0.0",
|
"vue": "^3.0.0",
|
||||||
"vue-router": "^4.0.0-0",
|
"vue-router": "^4.0.0-0",
|
||||||
"vuex": "^4.0.0-0"
|
"vuex": "^4.0.0-0"
|
||||||
@ -22,9 +29,11 @@
|
|||||||
"@vue/compiler-sfc": "^3.0.0",
|
"@vue/compiler-sfc": "^3.0.0",
|
||||||
"@vue/eslint-config-prettier": "^6.0.0",
|
"@vue/eslint-config-prettier": "^6.0.0",
|
||||||
"babel-eslint": "^10.1.0",
|
"babel-eslint": "^10.1.0",
|
||||||
|
"concurrently": "^6.2.0",
|
||||||
"eslint": "^6.7.2",
|
"eslint": "^6.7.2",
|
||||||
"eslint-plugin-prettier": "^3.3.1",
|
"eslint-plugin-prettier": "^3.3.1",
|
||||||
"eslint-plugin-vue": "^7.0.0",
|
"eslint-plugin-vue": "^7.0.0",
|
||||||
|
"json-server": "^0.16.3",
|
||||||
"less": "^3.0.4",
|
"less": "^3.0.4",
|
||||||
"less-loader": "^5.0.0",
|
"less-loader": "^5.0.0",
|
||||||
"prettier": "^2.2.1"
|
"prettier": "^2.2.1"
|
||||||
|
@ -6,6 +6,10 @@
|
|||||||
<router-view />
|
<router-view />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {};
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
#app {
|
#app {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hello">
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
<p>
|
|
||||||
For a guide and recipes on how to configure / customize this project,<br />
|
|
||||||
check out the
|
|
||||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener"
|
|
||||||
>vue-cli documentation</a
|
|
||||||
>.
|
|
||||||
</p>
|
|
||||||
<h3>Installed CLI Plugins</h3>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>babel</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>router</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>vuex</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>eslint</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h3>Essential Links</h3>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://forum.vuejs.org" target="_blank" rel="noopener"
|
|
||||||
>Forum</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://chat.vuejs.org" target="_blank" rel="noopener"
|
|
||||||
>Community Chat</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://twitter.com/vuejs" target="_blank" rel="noopener"
|
|
||||||
>Twitter</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h3>Ecosystem</h3>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<a href="https://router.vuejs.org" target="_blank" rel="noopener"
|
|
||||||
>vue-router</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://github.com/vuejs/vue-devtools#vue-devtools"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>vue-devtools</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener"
|
|
||||||
>vue-loader</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href="https://github.com/vuejs/awesome-vue"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
>awesome-vue</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "HelloWorld",
|
|
||||||
props: {
|
|
||||||
msg: String,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped lang="less">
|
|
||||||
h3 {
|
|
||||||
margin: 40px 0 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
</style>
|
|
194
src/components/InfobaseList.vue
Normal file
194
src/components/InfobaseList.vue
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
<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">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="0 == infobases.length">
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<Icon_Exclamation />
|
||||||
|
<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">
|
||||||
|
<form
|
||||||
|
v-if="is_edit_url_active(infobase.name)"
|
||||||
|
@submit.prevent="apply_edit_url(infobase.name)"
|
||||||
|
>
|
||||||
|
<div class="btn-group shadow rounded-start" role="group">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="url_edit[infobase.name]"
|
||||||
|
class="rounded-start"
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-sm btn-primary"
|
||||||
|
hint="Принять"
|
||||||
|
>
|
||||||
|
<Icon_V />
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-sm btn-outline-secondary"
|
||||||
|
@click="cancel_edit_url(infobase.name)"
|
||||||
|
hint="Отменить"
|
||||||
|
>
|
||||||
|
<Icon_X />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<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 axios from "axios";
|
||||||
|
import Icon_V from "@/components/icons/icon-v.vue";
|
||||||
|
import Icon_X from "@/components/icons/icon-x.vue";
|
||||||
|
import Icon_Exclamation from "@/components/icons/icon-exclamation.vue";
|
||||||
|
|
||||||
|
const api_base = "http://localhost:17653/api/v1";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "InfobaseList",
|
||||||
|
data: () => ({
|
||||||
|
url_base: "http://localhost:11111",
|
||||||
|
is_loading: true,
|
||||||
|
loading_error: false,
|
||||||
|
infobases: [],
|
||||||
|
url_edit: {},
|
||||||
|
}),
|
||||||
|
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_edit[name] = infobase.url;
|
||||||
|
},
|
||||||
|
cancel_edit_url(name) {
|
||||||
|
delete this.url_edit[name];
|
||||||
|
},
|
||||||
|
apply_edit_url(name) {
|
||||||
|
this.set_url(name, this.url_edit[name]);
|
||||||
|
delete this.url_edit[name];
|
||||||
|
},
|
||||||
|
is_edit_url_active(name) {
|
||||||
|
return name in this.url_edit;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
Icon_V,
|
||||||
|
Icon_X,
|
||||||
|
Icon_Exclamation,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
16
src/components/icons/icon-exclamation.vue
Normal file
16
src/components/icons/icon-exclamation.vue
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
fill="currentColor"
|
||||||
|
class="bi bi-exclamation-triangle-fill flex-shrink-0 me-2"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
role="img"
|
||||||
|
aria-label="Warning:"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M8.982 1.566a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566zM8 5c.535 0 .954.462.9.995l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995A.905.905 0 0 1 8 5zm.002 6a1 1 0 1 1 0 2 1 1 0 0 1 0-2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
14
src/components/icons/icon-v.vue
Normal file
14
src/components/icons/icon-v.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="bi bi-check-lg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M13.485 1.431a1.473 1.473 0 0 1 2.104 2.062l-7.84 9.801a1.473 1.473 0 0 1-2.12.04L.431 8.138a1.473 1.473 0 0 1 2.084-2.083l4.111 4.112 6.82-8.69a.486.486 0 0 1 .04-.045z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
14
src/components/icons/icon-x.vue
Normal file
14
src/components/icons/icon-x.vue
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<template>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="16"
|
||||||
|
height="16"
|
||||||
|
fill="currentColor"
|
||||||
|
class="bi bi-x-lg"
|
||||||
|
viewBox="0 0 16 16"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M1.293 1.293a1 1 0 0 1 1.414 0L8 6.586l5.293-5.293a1 1 0 1 1 1.414 1.414L9.414 8l5.293 5.293a1 1 0 0 1-1.414 1.414L8 9.414l-5.293 5.293a1 1 0 0 1-1.414-1.414L6.586 8 1.293 2.707a1 1 0 0 1 0-1.414z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
@ -3,4 +3,10 @@ import App from "./App.vue";
|
|||||||
import router from "./router";
|
import router from "./router";
|
||||||
import store from "./store";
|
import store from "./store";
|
||||||
|
|
||||||
|
import "jquery/src/jquery.js";
|
||||||
|
import "bootstrap/dist/css/bootstrap.min.css";
|
||||||
|
import "bootstrap/dist/js/bootstrap.min.js";
|
||||||
|
|
||||||
|
window.jQuery = window.$ = require("jquery");
|
||||||
|
|
||||||
createApp(App).use(store).use(router).mount("#app");
|
createApp(App).use(store).use(router).mount("#app");
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="home">
|
<div class="home">
|
||||||
<img alt="Vue logo" src="../assets/logo.png" />
|
<InfobaseList msg="Welcome to Your Vue.js App" />
|
||||||
<HelloWorld msg="Welcome to Your Vue.js App" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// @ is an alias to /src
|
// @ is an alias to /src
|
||||||
import HelloWorld from "@/components/HelloWorld.vue";
|
//import HelloWorld from "@/components/HelloWorld.vue";
|
||||||
|
import InfobaseList from "@/components/InfobaseList.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Home",
|
name: "Home",
|
||||||
components: {
|
components: {
|
||||||
HelloWorld,
|
InfobaseList,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
11
test/mock/api/db.json
Normal file
11
test/mock/api/db.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"index": ["infobases", "publications", "module", "config"],
|
||||||
|
"infobases":["test1", "accounting", "bpdemo", "hrm31", "Trade-2021"],
|
||||||
|
"publications":["accounting", "hrm31"],
|
||||||
|
"publication":[
|
||||||
|
{"name": "accounting", "url": "/acc"},
|
||||||
|
{"name": "hrm31", "url": "/hrm"}
|
||||||
|
],
|
||||||
|
"module":{},
|
||||||
|
"config":{}
|
||||||
|
}
|
7
test/mock/api/routes.json
Normal file
7
test/mock/api/routes.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"/api/v1/*": "/$1",
|
||||||
|
"/": "/index",
|
||||||
|
"": "/index",
|
||||||
|
"/publications/:name": "/publication/:name",
|
||||||
|
"/publications/:name/url": "/publication/:name"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user