Merge pull request 'Migruoja nuo senstančio webpack prie Vite ir Problemų tipų redagavimas ir pagalbinių funkcijų pridėjimas' (#6) from 22-01-25-issueType-admin into master

Reviewed-on: #6
This commit is contained in:
2022-01-26 18:59:21 +01:00
31 changed files with 1487 additions and 13701 deletions

View File

@@ -1,23 +1,5 @@
.DS_Store
node_modules node_modules
/dist .DS_Store
dist
dist-ssr
# local env files *.local
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,3 @@
{
"recommendations": ["johnsoncodehk.volar"]
}

View File

@@ -1,24 +0,0 @@
# clientapp
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<title>KTU SA Problemų sprendimo sistema</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -1,55 +1,26 @@
{ {
"name": "clientapp", "name": "clientapp",
"version": "0.1.0", "version": "0.0.0",
"private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "serve": "vite",
"build": "vue-cli-service build", "dev": "vite",
"lint": "vue-cli-service lint" "build": "vite build",
"preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@azure/msal-browser": "^2.20.0", "@azure/msal-browser": "^2.21.0",
"@popperjs/core": "^2.11.0", "@popperjs/core": "^2.10.2",
"axios": "^0.20.0-0", "axios": "^0.25.0",
"bootstrap": "^5.1.3", "bootstrap": "^5.1.3",
"bootstrap-icons": "^1.7.2", "bootstrap-icons": "^1.7.2",
"cookies-js": "^1.2.3", "lodash": "^4.17.21",
"core-js": "^3.20.0", "vue": "^3.2.25",
"joi": "^17.5.0",
"jwt-decode": "^3.1.2",
"vue": "^3.2.26",
"vue-loader-v16": "npm:vue-loader@^16.8.3",
"vue-router": "^4.0.12", "vue-router": "^4.0.12",
"vuex": "^4.0.2" "vuex": "^4.0.2"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "^4.5.15", "@vitejs/plugin-vue": "^2.0.0",
"@vue/cli-plugin-eslint": "^4.5.15", "sass": "^1.49.0",
"@vue/cli-service": "^4.5.15", "vite": "^2.7.2"
"@vue/compiler-sfc": "^3.2.26", }
"babel-eslint": "^10.1.0",
"eslint": "^6.8.0",
"eslint-plugin-vue": "^7.20.0",
"sass": "^1.45.1",
"sass-loader": "^10.2.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
} }

View File

@@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>KTU SA Problemų sprendimo sistema</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@@ -1,6 +1,11 @@
<template> <template>
<nav-menu /> <header>
<nav-menu />
<admin-menu />
</header>
<data-alert /> <data-alert />
<confirm-alert ref="ca" />
<div class="mb-3"></div>
<div v-if="isLocal" class="container"> <div v-if="isLocal" class="container">
<div class="alert alert-danger"> <div class="alert alert-danger">
<h4 class="alert-heading">Lokali sistemą aptikta</h4> <h4 class="alert-heading">Lokali sistemą aptikta</h4>
@@ -20,20 +25,26 @@
</span> </span>
</div> </div>
</div> </div>
<transition name="slide-fade"> <router-view v-slot="{ Component }">
<router-view /> <transition name="slide-fade" mode="out-in">
</transition> <component :is="Component" />
</transition>
</router-view>
</template> </template>
<script> <script>
import NavMenu from './components/NavMenu.vue' import NavMenu from './components/NavMenu.vue'
import DataAlert from './components/DataAlert.vue' import DataAlert from './components/DataAlert.vue'
import ConfirmAlert from './components/ConfirmAlert.vue'
import AdminMenu from './components/AdminMenu.vue'
export default { export default {
name: 'App', name: 'App',
components: { components: {
NavMenu, NavMenu,
DataAlert, DataAlert,
ConfirmAlert,
AdminMenu,
}, },
data() { data() {
return { return {
@@ -54,6 +65,36 @@ export default {
return location.protocol !== 'https:' return location.protocol !== 'https:'
}, },
}, },
methods: {
async confirm(text, title, options = {}) {
const passedOptions = Object.assign(
{ text, title, affirmitive: {}, negative: {} },
options
)
await new Promise((res, rej) => {
passedOptions.affirmitive.action = res
passedOptions.negative.action = () =>
rej(new Error('User rejected confirmation.'))
this.$refs.ca.configure(passedOptions)
this.$refs.ca.show()
})
},
async deleteConfirmation() {
await this.confirm(
'Ar tikrai norite ištrinti šį elementą?',
'Ištrinimo patvirtinimas',
{
affirmitive: {
text: 'Ištrinti',
type: 'danger',
},
negative: {
text: 'Atšaukti',
},
}
)
},
},
} }
</script> </script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -1,23 +1,17 @@
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap');
@import 'custom'; @import 'custom';
@import '~bootstrap/scss/bootstrap'; @import 'bootstrap/scss/bootstrap';
@import url('https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css'); @import url('https://cdn.jsdelivr.net/npm/bootstrap-icons@1.7.2/font/bootstrap-icons.css');
/* Enter and leave animations can use different */ /* Enter and leave animations can use different */
/* durations and timing functions. */ /* durations and timing functions. */
.slide-fade-enter-active { .slide-fade-enter-active {
transition: all 0.3s ease-out; transition: all 0.15s ease-out;
} }
.slide-fade-leave-active { .slide-fade-leave-active {
transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1); transition: all 0.15s cubic-bezier(1, 0.5, 0.8, 1);
}
.slide-fade-leave-active,
.slide-fade-enter-active {
position: relative;
top: 0;
} }
.slide-fade-enter-from, .slide-fade-enter-from,
@@ -31,3 +25,23 @@
transform: translateX(0px); transform: translateX(0px);
opacity: 1; opacity: 1;
} }
.fade-enter-active {
transition: all 0.3s ease-out;
}
.fade-leave-active {
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: scale(0);
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
transform: scale(1);
}

View File

@@ -0,0 +1,58 @@
<template>
<nav
v-if="$store.state.msalAuth.isAdmin"
class="navbar navbar-expand-lg navbar-dark bg-black"
>
<div class="container-fluid">
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#adminbarNav"
aria-controls="navbarNav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div
class="collapse navbar-collapse"
:class="{ show: isExpanded }"
id="adminbarNav"
>
<ul class="navbar-nav me-auto">
<li class="nav-item">
<router-link :to="{ name: 'Issues' }" class="nav-link"
>Pateiktos problemos</router-link
>
</li>
<li class="nav-item">
<router-link :to="{ name: 'AdminIssueTypes' }" class="nav-link"
>Problemų tipai</router-link
>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script>
export default {
name: 'AdminMenu',
data() {
return {
isExpanded: false,
}
},
methods: {
collapse() {
this.isExpanded = false
},
toggle() {
this.isExpanded = !this.isExpanded
},
},
}
</script>

View File

@@ -0,0 +1,67 @@
<template>
<transition name="fade">
<div
v-if="shown"
class="alert"
:class="{ ['alert-' + type]: true }"
role="alert"
>
<h4 v-if="title" class="alert-heading">{{ title }}</h4>
{{ text }}
</div>
</transition>
</template>
<script>
import defaults from 'lodash/defaults'
const defaultOptions = {
title: null,
text: 'You have not configured alerter.',
type: 'danger',
}
export default {
data() {
return {
shown: false,
text: 'A simple alert',
title: null,
type: 'primary',
dismisstimer: null,
}
},
methods: {
show() {
this.shown = true
},
hide() {
this.shown = false
this.cancelAutoDismiss()
},
cancelAutoDismiss() {
if (this.dismisstimer) clearTimeout(this.dismisstimer)
this.dismisstimer = null
},
autoDismiss(timeout) {
this.cancelAutoDismiss()
this.dismisstimer = setTimeout(() => this.hide(), timeout)
},
configure(options) {
const final = defaults(options, defaultOptions)
this.text = final.text
this.title = final.title
this.type = final.type
},
alert(options) {
this.configure(options)
this.cancelAutoDismiss()
this.show()
},
alertTimed(options, timeout = 4000) {
this.alert(options)
this.autoDismiss(timeout)
},
},
}
</script>

View File

@@ -0,0 +1,98 @@
<template>
<div ref="modal" class="modal fade" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ options.title }}</h5>
</div>
<div class="modal-body">
<p>
{{ options.text }}
</p>
</div>
<div class="modal-footer">
<button
type="button"
class="btn"
:class="'btn-' + options.affirmitive.type"
@click="accept"
>
{{ options.affirmitive.text }}
</button>
<button
type="button"
class="btn"
:class="'btn-' + options.negative.type"
@click="reject"
>
{{ options.negative.text }}
</button>
</div>
</div>
</div>
</div>
</template>
<script>
import defaultsDeep from 'lodash/defaultsDeep'
import { Modal } from 'bootstrap'
const defaultValues = {
title: 'Confirmation',
text: 'Do you confirm this action?',
affirmitive: {
hide: false,
text: 'Yes',
type: 'primary',
action: () => null,
},
negative: {
hide: false,
text: 'No',
type: 'secondary',
action: () => null,
},
}
export default {
data() {
return {
modal: null,
beenUsed: false,
options: Object.assign({}, defaultValues),
}
},
mounted() {
var el = this.$refs.modal
el.addEventListener('hide.bs.modal', () => this.handleHideEvent())
this.modal = new Modal(el, {})
},
methods: {
handleHideEvent() {
if (!this.beenUsed) {
this.options.negative.action()
}
},
show() {
this.beenUsed = false
this.modal.show()
},
hide() {
this.modal.hide()
},
accept() {
this.beenUsed = true
this.options.affirmitive.action()
this.hide()
},
reject() {
this.beenUsed = true
this.options.negative.action()
this.hide()
},
configure(options) {
this.options = defaultsDeep({}, options || {}, defaultValues)
},
},
}
</script>

View File

@@ -1,73 +1,68 @@
<template> <template>
<header class="mb-3"> <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<nav class="navbar navbar-expand-lg navbar-dark bg-primary"> <div class="container-fluid">
<div class="container-fluid"> <router-link :to="{ name: 'Home' }" class="navbar-brand"
<router-link :to="{ name: 'Home' }" class="navbar-brand" >KTU SA Problemų sprendimo sistema</router-link
>KTU SA Problemų sprendimo sistema</router-link >
> <button
<button class="navbar-toggler"
class="navbar-toggler" type="button"
type="button" data-bs-toggle="collapse"
data-bs-toggle="collapse" data-bs-target="#navbarNav"
data-bs-target="#navbarNav" aria-controls="navbarNav"
aria-controls="navbarNav" aria-expanded="false"
aria-expanded="false" aria-label="Toggle navigation"
aria-label="Toggle navigation" >
> <span class="navbar-toggler-icon"></span>
<span class="navbar-toggler-icon"></span> </button>
</button> <div
<div class="collapse navbar-collapse"
class="collapse navbar-collapse" :class="{ show: isExpanded }"
:class="{ show: isExpanded }" id="navbarNav"
id="navbarNav" >
> <ul class="navbar-nav me-auto">
<ul class="navbar-nav me-auto"> <li class="nav-item">
<router-link :to="{ name: 'Home' }" class="nav-link"
>Pagrindinis</router-link
>
</li>
<template v-if="$store.state.msalAuth.isLoggedIn">
<li class="nav-item"> <li class="nav-item">
<router-link :to="{ name: 'Home' }" class="nav-link"
>Pagrindinis</router-link
>
</li>
<li class="nav-item" v-if="$store.state.msalAuth.isLoggedIn">
<router-link :to="{ name: 'Submit' }" class="nav-link" <router-link :to="{ name: 'Submit' }" class="nav-link"
>Pateikti problemą</router-link >Pateikti problemą</router-link
> >
</li> </li>
<li class="nav-item" v-if="$store.state.msalAuth.isLoggedIn"> <li class="nav-item">
<router-link :to="{ name: 'Problems' }" class="nav-link" <router-link :to="{ name: 'Problems' }" class="nav-link"
>Problemos</router-link >Problemos</router-link
> >
</li> </li>
<li class="nav-item" v-if="$store.state.msalAuth.isLoggedIn"> <li class="nav-item">
<router-link :to="{ name: 'Feedbacks' }" class="nav-link" <router-link :to="{ name: 'Feedbacks' }" class="nav-link"
>Atsiliepimai</router-link >Atsiliepimai</router-link
> >
</li> </li>
<li class="nav-item" v-if="$store.state.msalAuth.isAdmin"> </template>
<router-link :to="{ name: 'Issues' }" class="nav-link" <li v-if="$root.isLocal" class="nav-item">
>Pateiktos problemos</router-link <a href="/swagger" class="nav-link">SUI</a>
> </li>
</li> </ul>
<li v-if="$root.isLocal" class="nav-item"> <div class="navbar-nav">
<a href="/swagger" class="nav-link">Swagger UI</a> <template v-if="$store.state.msalAuth.isLoggedIn">
</li> <span class="navbar-text"
</ul> >Prisijungta kaip {{ $store.state.msalAuth.displayName }}
<div class="navbar-nav"> </span>
<template v-if="$store.state.msalAuth.isLoggedIn"> <div class="nav-item">
<span class="navbar-text" <a href="#" @click="LogoutMsal" class="nav-link">Atsijungti</a>
>Prisijungta kaip {{ $store.state.msalAuth.displayName }}
</span>
<div class="nav-item">
<a href="#" @click="LogoutMsal" class="nav-link">Atsijungti</a>
</div>
</template>
<div v-else class="nav-item">
<a href="#" @click="LoginMsal" class="nav-link">Prisijungti</a>
</div> </div>
</template>
<div v-else class="nav-item">
<a href="#" @click="LoginMsal" class="nav-link">Prisijungti</a>
</div> </div>
</div> </div>
</div> </div>
</nav> </div>
</header> </nav>
</template> </template>
<script> <script>

View File

@@ -0,0 +1,40 @@
<template>
<div class="mb-3">
<label for="feedbackLtTextArea" class="form-label"
>Lietuviškas Aprašymas</label
>
<textarea
v-model="feedbackLt"
class="form-control"
id="feedbackLtTextArea"
rows="4"
></textarea>
</div>
<div class="mb-3">
<label for="feedbackEnTextArea" class="form-label"
>Angliškas Aprašymas</label
>
<textarea
v-model="feedbackEn"
class="form-control"
id="feedbackEnTextArea"
rows="4"
></textarea>
</div>
</template>
<script>
import { mapModel } from './formHelpers'
export default {
props: {
modelValue: {
type: Object,
default: () => ({}),
},
},
emits: ['update:modelValue'],
computed: {
...mapModel(['feedbackLt', 'feedbackEn']),
},
}
</script>

View File

@@ -0,0 +1,27 @@
<template>
<div class="mb-3">
<label for="nameInput" class="form-label">Lietuviškas pavadinimas</label>
<input v-model="name" type="text" class="form-control" id="nameInput" />
</div>
<div class="mb-3">
<label for="nameEnInput" class="form-label">Angliškas pavadinimas</label>
<input v-model="nameEn" type="text" class="form-control" id="nameEnInput" />
</div>
</template>
<script>
import { mapModel } from './formHelpers'
export default {
props: {
modelValue: {
type: Object,
default: () => ({}),
},
},
emits: ['update:modelValue'],
computed: {
...mapModel(['name', 'nameEn']),
},
}
</script>

View File

@@ -0,0 +1,27 @@
export function autoComputed(propName, defaultValue) {
return {
get() {
return this.modelValue[propName] || defaultValue
},
set(value) {
this.$emit('update:modelValue', {
...this.modelValue,
[propName]: value,
})
},
}
}
export function mapModel(props) {
const computedValues = {}
if (Array.isArray(props)) {
props.forEach((propName) => {
computedValues[propName] = autoComputed(propName, '')
})
} else {
Object.entries(props).forEach(([propName, defaultValue]) => {
computedValues[propName] = autoComputed(propName, defaultValue)
})
}
return computedValues
}

View File

@@ -12,5 +12,3 @@ app.use(router)
app.use(store) app.use(store)
app.mount('#app') app.mount('#app')
window.r = router

View File

@@ -1,5 +1,4 @@
import * as msal from '@azure/msal-browser' import * as msal from '@azure/msal-browser'
import Cookies from 'cookies-js'
import axios from 'axios' import axios from 'axios'
const ClientIdCookieName = 'ktusakacas' const ClientIdCookieName = 'ktusakacas'
@@ -22,6 +21,7 @@ const msalState = {
displayName: null, displayName: null,
debugFullTokenResponse: null, debugFullTokenResponse: null,
msalRefreshTimer: null,
} }
async function initializeMSAL() { async function initializeMSAL() {
@@ -36,6 +36,7 @@ async function initializeMSAL() {
redirectUri: window.location.protocol + '//' + window.location.host + '/', redirectUri: window.location.protocol + '//' + window.location.host + '/',
}, },
} }
msalState.msalRefreshTimer = setInterval(__refreshToken, 10 * 60 * 1000)
msalState.msal = new msal.PublicClientApplication(msalConfig) msalState.msal = new msal.PublicClientApplication(msalConfig)
@@ -71,6 +72,22 @@ export function LogoutMsal() {
msalState.msal.logout() msalState.msal.logout()
} }
async function __refreshToken() {
if (!msalState.isLoggedIn) return
msalState.debugFullTokenResponse = await msalState.msal
.acquireTokenSilent({ scopes: RequestedScopes })
.catch((error) => {
if (error instanceof msal.InteractionRequiredAuthError) {
// fallback to interaction when silent call fails
return msalState.msal.acquireTokenRedirect({
scopes: RequestedScopes,
})
}
})
__responseObjectToMsalState()
__stateChanged()
}
async function __handleResponse(response) { async function __handleResponse(response) {
if (response !== null) { if (response !== null) {
if (__isAccountAceptable(response.account)) { if (__isAccountAceptable(response.account)) {
@@ -83,7 +100,7 @@ async function __handleResponse(response) {
msalState.msal msalState.msal
.getAllAccounts() .getAllAccounts()
.filter(__isAccountAceptable) .filter(__isAccountAceptable)
.forEach(account => { .forEach((account) => {
msalState.msal.setActiveAccount(account) msalState.msal.setActiveAccount(account)
}) })
@@ -91,7 +108,7 @@ async function __handleResponse(response) {
if (account != null) { if (account != null) {
msalState.debugFullTokenResponse = await msalState.msal msalState.debugFullTokenResponse = await msalState.msal
.acquireTokenSilent({ scopes: RequestedScopes }) .acquireTokenSilent({ scopes: RequestedScopes })
.catch(error => { .catch((error) => {
if (error instanceof msal.InteractionRequiredAuthError) { if (error instanceof msal.InteractionRequiredAuthError) {
// fallback to interaction when silent call fails // fallback to interaction when silent call fails
return msalState.msal.acquireTokenRedirect({ return msalState.msal.acquireTokenRedirect({
@@ -119,26 +136,11 @@ function __isAccountAceptable(account) {
} }
function __stateChanged() { function __stateChanged() {
msalState.stateChangeCallbacks.forEach(cb => cb()) msalState.stateChangeCallbacks.forEach((cb) => cb())
}
function __isLocalStorageAvailable() {
try {
localStorage.setItem('__lsTest', 'true')
const result = localStorage.getItem('__lsTest')
localStorage.removeItem('__lsTest')
return result == 'true'
} catch (e) {
return false
}
} }
async function __loadAuthParameters() { async function __loadAuthParameters() {
if (__isLocalStorageAvailable()) { await __loadAuthParametersLocalStorage()
await __loadAuthParametersLocalStorage()
} else {
await __loadAuthParametersCookies()
}
} }
async function __loadAuthParametersLocalStorage() { async function __loadAuthParametersLocalStorage() {
@@ -157,22 +159,6 @@ async function __loadAuthParametersLocalStorage() {
} }
} }
async function __loadAuthParametersCookies() {
const clientId = Cookies.get(ClientIdCookieName)
const authority = Cookies.get(AuthorityCookieName)
const tenant = Cookies.get(TenantCookieName)
if (clientId == null || authority == null || tenant == null) {
await __fetchAuthParameters()
Cookies.set(ClientIdCookieName, msalState.clientId)
Cookies.set(AuthorityCookieName, msalState.authority)
Cookies.set(TenantCookieName, msalState.tenant)
} else {
msalState.clientId = clientId
msalState.authority = authority
msalState.tenant = tenant
}
}
async function __fetchAuthParameters() { async function __fetchAuthParameters() {
var response = await axios.get('/api/AuthMetadata') var response = await axios.get('/api/AuthMetadata')
msalState.clientId = response.data.clientId msalState.clientId = response.data.clientId

View File

@@ -66,6 +66,7 @@ export default {
this.error = null this.error = null
this.ok = null this.ok = null
try { try {
await this.$root.deleteConfirmation()
await authAxios.delete(`/api/Issues/${id}`) await authAxios.delete(`/api/Issues/${id}`)
this.ok = 'Sėkmingai ištrintą' this.ok = 'Sėkmingai ištrintą'
await this.fetchData() await this.fetchData()

View File

@@ -24,28 +24,7 @@
</div> </div>
<div class="row justify-content-center"> <div class="row justify-content-center">
<div class="card col-lg-6 p-5"> <div class="card col-lg-6 p-5">
<div class="mb-3"> <feedback-form v-model="feedback" />
<label for="problemLtTextArea" class="form-label"
>Lietuviškas Aprašymas</label
>
<textarea
v-model="feedback.feedbackLt"
class="form-control"
id="problemLtTextArea"
rows="4"
></textarea>
</div>
<div class="mb-3">
<label for="problemEnTextArea" class="form-label"
>Angliškas Aprašymas</label
>
<textarea
v-model="feedback.feedbackEn"
class="form-control"
id="problemEnTextArea"
rows="4"
></textarea>
</div>
<button @click="create" class="btn btn-primary btn-lg"> <button @click="create" class="btn btn-primary btn-lg">
Sukurti naują atsiliepimą Sukurti naują atsiliepimą
</button> </button>
@@ -56,8 +35,12 @@
<script> <script>
import { axios, authAxios } from '@/axios' import { axios, authAxios } from '@/axios'
import FeedbackForm from '@/components/forms/FeedbackForm.vue'
export default { export default {
components: {
FeedbackForm,
},
data() { data() {
return { return {
issue: null, issue: null,

View File

@@ -0,0 +1,15 @@
<template>
<div>
<div class="container">
<div class="alert alert-warning">
<b>Dėmesio!</b> Tu esi administracinėje skiltyje, visą informacija
pateikiama čia yra galimai konfidianciali.
</div>
</div>
<router-view v-slot="{ Component }">
<transition name="slide-fade" mode="out-in">
<component :is="Component" />
</transition>
</router-view>
</div>
</template>

View File

@@ -0,0 +1,62 @@
<template>
<div class="container">
<h1>Redaguoti problemos tipą</h1>
<div class="row justify-content-center">
<div class="card col-lg-6 p-5">
<issue-type-form v-model="issueType" />
<alerter ref="submitAlerter" />
<button @click="update" class="btn btn-primary btn-lg">
Išsaugoti
</button>
</div>
</div>
</div>
</template>
<script>
import { axios, authAxios } from '@/axios'
import IssueTypeForm from '@/components/forms/IssueTypeForm.vue'
import Alerter from '@/components/Alerter.vue'
export default {
components: {
IssueTypeForm,
Alerter,
},
data() {
return {
issueType: { name: '', nameEn: '' },
}
},
created() {
this.fetchData()
},
methods: {
async fetchData() {
const response = await axios.get(
`/api/IssueTypes/${this.$route.params.id}`
)
this.issueType = response.data
},
async update() {
try {
if (!this.issueType.name || !this.issueType.nameEn) {
this.$refs.submitAlerter.alertTimed({
text: 'Problemos tipas turi turėti pavadinimus!!!',
})
return
}
await authAxios.patch(
`/api/IssueTypes/${this.$route.params.id}`,
this.issueType
)
this.$router.push({ name: 'AdminIssueTypes' })
} catch (error) {
this.$refs.submitAlerter.alert({
title: 'Įvyko klaidą sukuriant tipą.',
text: error,
})
}
},
},
}
</script>

View File

@@ -0,0 +1,54 @@
<template>
<div class="container">
<h1>Naujas problemos tipas</h1>
<div class="row justify-content-center">
<div class="card col-lg-6 p-5">
<issue-type-form v-model="issueType" />
<alerter ref="submitAlerter" />
<button @click="create" class="btn btn-primary btn-lg">
Sukurti naują problemos tipą
</button>
</div>
</div>
</div>
</template>
<script>
import { authAxios } from '@/axios'
import IssueTypeForm from '@/components/forms/IssueTypeForm.vue'
import Alerter from '@/components/Alerter.vue'
export default {
components: {
IssueTypeForm,
Alerter,
},
data() {
return {
issueType: { name: '', nameEn: '' },
}
},
methods: {
async create() {
try {
if (!this.issueType.name || !this.issueType.nameEn) {
this.$refs.submitAlerter.alertTimed({
text: 'Problemos tipas turi turėti pavadinimus!!!',
})
return
}
await authAxios.post('/api/IssueTypes', this.issueType)
this.$refs.submitAlerter.alertTimed({
text: 'Sėkmingai sukurtas problemos tipas.',
type: 'success',
})
this.issueType = {}
} catch (error) {
this.$refs.submitAlerter.alert({
title: 'Įvyko klaidą sukuriant tipą.',
text: error,
})
}
},
},
}
</script>

View File

@@ -0,0 +1,57 @@
<template>
<div class="container">
<router-link
:to="{ name: 'AdminIssueTypeNew' }"
class="btn btn-primary mx-1"
>Sukurti naują problemos tipą</router-link
>
<div class="card my-4" v-for="it in issueTypes" :key="it.id">
<div class="row g-0">
<div class="card-body">
<h5 class="card-title">{{ it.name }}</h5>
<h5 class="card-title text-muted">{{ it.nameEn }}</h5>
<button class="btn btn-danger mx-1" @click="deleteIssueType(it.id)">
<i class="bi bi-trash-fill"></i>
Ištrinti
</button>
<router-link
:to="{ name: 'AdminIssueTypeEdit', params: { id: it.id } }"
class="btn btn-primary mx-1"
>Redaguoti</router-link
>
</div>
</div>
</div>
</div>
</template>
<script>
import { axios, authAxios } from '@/axios'
export default {
data() {
return {
issueTypes: [],
}
},
created() {
this.fetchData()
},
methods: {
async fetchData() {
const response = await axios.get('/api/IssueTypes')
this.issueTypes = response.data
},
async deleteIssueType(id) {
try {
await this.$root.deleteConfirmation()
await authAxios.delete(`/api/IssueTypes/${id}`)
// TODO: Display some success info
await this.fetchData()
} catch (error) {
// TODO: Display error.
}
},
},
}
</script>

View File

@@ -0,0 +1,28 @@
import IssueTypes from '@/pages/admin/IssueTypes.vue'
import IssueTypeNew from '@/pages/admin/IssueTypeNew.vue'
import IssueTypeEdit from '@/pages/admin/IssueTypeEdit.vue'
import Admin from '@/pages/admin/Admin.vue'
export default [
{
path: '/admin',
component: Admin,
children: [
{
path: 'issuetypes',
name: 'AdminIssueTypes',
component: IssueTypes,
},
{
path: 'issuetypes/new',
name: 'AdminIssueTypeNew',
component: IssueTypeNew,
},
{
path: 'issuetypes/:id/edit',
name: 'AdminIssueTypeEdit',
component: IssueTypeEdit,
},
],
},
]

View File

@@ -6,6 +6,7 @@ import Feedbacks from '@/pages/Feedbacks.vue'
import Issues from '@/pages/Issues.vue' import Issues from '@/pages/Issues.vue'
import NewProblem from '@/pages/NewProblem.vue' import NewProblem from '@/pages/NewProblem.vue'
import NewFeedback from '@/pages/NewFeedback.vue' import NewFeedback from '@/pages/NewFeedback.vue'
import AdminRoutes from './admin'
const routes = [ const routes = [
{ {
@@ -43,6 +44,7 @@ const routes = [
name: 'IssueNewFeedback', name: 'IssueNewFeedback',
component: NewFeedback, component: NewFeedback,
}, },
...AdminRoutes,
] ]
const router = createRouter({ const router = createRouter({

View File

@@ -0,0 +1,13 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from "path"
// https://vitejs.dev/config/
export default defineConfig({
resolve:{
alias:{
'@' : path.resolve(__dirname, './src')
},
},
plugins: [vue()]
})

View File

@@ -1,8 +0,0 @@
module.exports = {
runtimeCompiler: true,
chainWebpack: (config) => {
config.resolve.alias
.set("balm-ui-plus", "balm-ui/dist/balm-ui-plus.js")
.set("balm-ui-css", "balm-ui/dist/balm-ui.css");
},
};

523
KTUSAPS/ClientApp/yarn.lock Normal file
View File

@@ -0,0 +1,523 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@azure/msal-browser@^2.21.0":
version "2.21.0"
resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-2.21.0.tgz#2ebe4b0874a61d64009419d4cfef1f6bb5e226b3"
integrity sha512-y+oAUJJ0m7gRUT505iGT4SDXktrRzOE3HZC0+nQyHDI+3O7BKK5NjQUwD/4V8FNNyrhxEtLk99iwJEo61epinQ==
dependencies:
"@azure/msal-common" "^6.0.0"
"@azure/msal-common@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-6.0.0.tgz#9a60c27967ae6f6678015eb6dfb0ea7cc999eb3b"
integrity sha512-Vva3snqmWPHJNDCBb4lz3D0rvZsi/0QikAxHvVFNwtNg5pP4NZE4U34tNiXN+m9KhlQFrZBPkE5rk7dIEOGcWw==
dependencies:
debug "^4.1.1"
"@babel/parser@^7.16.4":
version "7.16.12"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6"
integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A==
"@popperjs/core@^2.10.2":
version "2.11.2"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.2.tgz#830beaec4b4091a9e9398ac50f865ddea52186b9"
integrity sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==
"@vitejs/plugin-vue@^2.0.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-2.1.0.tgz#ddf5e0059f84f2ff649afc25ce5a59211e670542"
integrity sha512-AZ78WxvFMYd8JmM/GBV6a6SGGTU0GgN/0/4T+FnMMsLzFEzTeAUwuraapy50ifHZsC+G5SvWs86bvaCPTneFlA==
"@vue/compiler-core@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.29.tgz#b06097ab8ff0493177c68c5ea5b63d379a061097"
integrity sha512-RePZ/J4Ub3sb7atQw6V6Rez+/5LCRHGFlSetT3N4VMrejqJnNPXKUt5AVm/9F5MJriy2w/VudEIvgscCfCWqxw==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/shared" "3.2.29"
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-dom@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.29.tgz#ad0ead405bd2f2754161335aad9758aa12430715"
integrity sha512-y26vK5khdNS9L3ckvkqJk/78qXwWb75Ci8iYLb67AkJuIgyKhIOcR1E8RIt4mswlVCIeI9gQ+fmtdhaiTAtrBQ==
dependencies:
"@vue/compiler-core" "3.2.29"
"@vue/shared" "3.2.29"
"@vue/compiler-sfc@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.29.tgz#f76d556cd5fca6a55a3ea84c88db1a2a53a36ead"
integrity sha512-X9+0dwsag2u6hSOP/XsMYqFti/edvYvxamgBgCcbSYuXx1xLZN+dS/GvQKM4AgGS4djqo0jQvWfIXdfZ2ET68g==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.29"
"@vue/compiler-dom" "3.2.29"
"@vue/compiler-ssr" "3.2.29"
"@vue/reactivity-transform" "3.2.29"
"@vue/shared" "3.2.29"
estree-walker "^2.0.2"
magic-string "^0.25.7"
postcss "^8.1.10"
source-map "^0.6.1"
"@vue/compiler-ssr@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.29.tgz#37b15b32dcd2f6b410bb61fca3f37b1a92b7eb1e"
integrity sha512-LrvQwXlx66uWsB9/VydaaqEpae9xtmlUkeSKF6aPDbzx8M1h7ukxaPjNCAXuFd3fUHblcri8k42lfimHfzMICA==
dependencies:
"@vue/compiler-dom" "3.2.29"
"@vue/shared" "3.2.29"
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.0.0-beta.18":
version "6.0.0-beta.21.1"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.0.0-beta.21.1.tgz#f1410f53c42aa67fa3b01ca7bdba891f69d7bc97"
integrity sha512-FqC4s3pm35qGVeXRGOjTsRzlkJjrBLriDS9YXbflHLsfA9FrcKzIyWnLXoNm+/7930E8rRakXuAc2QkC50swAw==
"@vue/reactivity-transform@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.29.tgz#a08d606e10016b7cf588d1a43dae4db2953f9354"
integrity sha512-YF6HdOuhdOw6KyRm59+3rML8USb9o8mYM1q+SH0G41K3/q/G7uhPnHGKvspzceD7h9J3VR1waOQ93CUZj7J7OA==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.29"
"@vue/shared" "3.2.29"
estree-walker "^2.0.2"
magic-string "^0.25.7"
"@vue/reactivity@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.29.tgz#afdc9c111d4139b14600be17ad80267212af6052"
integrity sha512-Ryhb6Gy62YolKXH1gv42pEqwx7zs3n8gacRVZICSgjQz8Qr8QeCcFygBKYfJm3o1SccR7U+bVBQDWZGOyG1k4g==
dependencies:
"@vue/shared" "3.2.29"
"@vue/runtime-core@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.29.tgz#fb8577b2fcf52e8d967bd91cdf49ab9fb91f9417"
integrity sha512-VMvQuLdzoTGmCwIKTKVwKmIL0qcODIqe74JtK1pVr5lnaE0l25hopodmPag3RcnIcIXe+Ye3B2olRCn7fTCgig==
dependencies:
"@vue/reactivity" "3.2.29"
"@vue/shared" "3.2.29"
"@vue/runtime-dom@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.29.tgz#35e9a2bf04ef80b86ac2ca0e7b2ceaccf1e18f01"
integrity sha512-YJgLQLwr+SQyORzTsBQLL5TT/5UiV83tEotqjL7F9aFDIQdFBTCwpkCFvX9jqwHoyi9sJqM9XtTrMcc8z/OjPA==
dependencies:
"@vue/runtime-core" "3.2.29"
"@vue/shared" "3.2.29"
csstype "^2.6.8"
"@vue/server-renderer@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.29.tgz#ea6afa361b9c781a868c8da18c761f9b7bc89102"
integrity sha512-lpiYx7ciV7rWfJ0tPkoSOlLmwqBZ9FTmQm33S+T4g0j1fO/LmhJ9b9Ctl1o5xvIFVDk9QkSUWANZn7H2pXuxVw==
dependencies:
"@vue/compiler-ssr" "3.2.29"
"@vue/shared" "3.2.29"
"@vue/shared@3.2.29":
version "3.2.29"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.29.tgz#07dac7051117236431d2f737d16932aa38bbb925"
integrity sha512-BjNpU8OK6Z0LVzGUppEk0CMYm/hKDnZfYdjSmPOs0N+TR1cLKJAkDwW8ASZUvaaSLEi6d3hVM7jnWnX+6yWnHw==
anymatch@~3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
dependencies:
normalize-path "^3.0.0"
picomatch "^2.0.4"
axios@^0.25.0:
version "0.25.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a"
integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==
dependencies:
follow-redirects "^1.14.7"
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
bootstrap-icons@^1.7.2:
version "1.7.2"
resolved "https://registry.yarnpkg.com/bootstrap-icons/-/bootstrap-icons-1.7.2.tgz#4024e081e2c850602552e1fed6451e682d09322a"
integrity sha512-NiR2PqC73AQOPdVSu6GJfnk+hN2z6powcistXk1JgPnKuoV2FSdSl26w931Oz9HYbKCcKUSB6ncZTYJAYJl3QQ==
bootstrap@^5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.1.3.tgz#ba081b0c130f810fa70900acbc1c6d3c28fa8f34"
integrity sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==
braces@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==
dependencies:
fill-range "^7.0.1"
"chokidar@>=3.0.0 <4.0.0":
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
dependencies:
anymatch "~3.1.2"
braces "~3.0.2"
glob-parent "~5.1.2"
is-binary-path "~2.1.0"
is-glob "~4.0.1"
normalize-path "~3.0.0"
readdirp "~3.6.0"
optionalDependencies:
fsevents "~2.3.2"
csstype@^2.6.8:
version "2.6.19"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.19.tgz#feeb5aae89020bb389e1f63669a5ed490e391caa"
integrity sha512-ZVxXaNy28/k3kJg0Fou5MiYpp88j7H9hLZp8PDC3jV0WFjfH5E9xHb56L0W59cPbKbcHXeP4qyT8PrHp8t6LcQ==
debug@^4.1.1:
version "4.3.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
dependencies:
ms "2.1.2"
esbuild-android-arm64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.15.tgz#3fc3ff0bab76fe35dd237476b5d2b32bb20a3d44"
integrity sha512-m602nft/XXeO8YQPUDVoHfjyRVPdPgjyyXOxZ44MK/agewFFkPa8tUo6lAzSWh5Ui5PB4KR9UIFTSBKh/RrCmg==
esbuild-darwin-64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.15.tgz#8e9169c16baf444eacec60d09b24d11b255a8e72"
integrity sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==
esbuild-darwin-arm64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.15.tgz#1b07f893b632114f805e188ddfca41b2b778229a"
integrity sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==
esbuild-freebsd-64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.15.tgz#0b8b7eca1690c8ec94c75680c38c07269c1f4a85"
integrity sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==
esbuild-freebsd-arm64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.15.tgz#2e1a6c696bfdcd20a99578b76350b41db1934e52"
integrity sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==
esbuild-linux-32@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.15.tgz#6fd39f36fc66dd45b6b5f515728c7bbebc342a69"
integrity sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==
esbuild-linux-64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.15.tgz#9cb8e4bcd7574e67946e4ee5f1f1e12386bb6dd3"
integrity sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==
esbuild-linux-arm64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.15.tgz#3891aa3704ec579a1b92d2a586122e5b6a2bfba1"
integrity sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==
esbuild-linux-arm@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.15.tgz#8a00e99e6a0c6c9a6b7f334841364d8a2b4aecfe"
integrity sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==
esbuild-linux-mips64le@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.15.tgz#36b07cc47c3d21e48db3bb1f4d9ef8f46aead4f7"
integrity sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==
esbuild-linux-ppc64le@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.15.tgz#f7e6bba40b9a11eb9dcae5b01550ea04670edad2"
integrity sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==
esbuild-netbsd-64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.13.15.tgz#a2fedc549c2b629d580a732d840712b08d440038"
integrity sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==
esbuild-openbsd-64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.15.tgz#b22c0e5806d3a1fbf0325872037f885306b05cd7"
integrity sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==
esbuild-sunos-64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.15.tgz#d0b6454a88375ee8d3964daeff55c85c91c7cef4"
integrity sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==
esbuild-windows-32@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.15.tgz#c96d0b9bbb52f3303322582ef8e4847c5ad375a7"
integrity sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==
esbuild-windows-64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.15.tgz#1f79cb9b1e1bb02fb25cd414cb90d4ea2892c294"
integrity sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==
esbuild-windows-arm64@0.13.15:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.15.tgz#482173070810df22a752c686509c370c3be3b3c3"
integrity sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==
esbuild@^0.13.12:
version "0.13.15"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.15.tgz#db56a88166ee373f87dbb2d8798ff449e0450cdf"
integrity sha512-raCxt02HBKv8RJxE8vkTSCXGIyKHdEdGfUmiYb8wnabnaEmHzyW7DCHb5tEN0xU8ryqg5xw54mcwnYkC4x3AIw==
optionalDependencies:
esbuild-android-arm64 "0.13.15"
esbuild-darwin-64 "0.13.15"
esbuild-darwin-arm64 "0.13.15"
esbuild-freebsd-64 "0.13.15"
esbuild-freebsd-arm64 "0.13.15"
esbuild-linux-32 "0.13.15"
esbuild-linux-64 "0.13.15"
esbuild-linux-arm "0.13.15"
esbuild-linux-arm64 "0.13.15"
esbuild-linux-mips64le "0.13.15"
esbuild-linux-ppc64le "0.13.15"
esbuild-netbsd-64 "0.13.15"
esbuild-openbsd-64 "0.13.15"
esbuild-sunos-64 "0.13.15"
esbuild-windows-32 "0.13.15"
esbuild-windows-64 "0.13.15"
esbuild-windows-arm64 "0.13.15"
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
fill-range@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40"
integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==
dependencies:
to-regex-range "^5.0.1"
follow-redirects@^1.14.7:
version "1.14.7"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.7.tgz#2004c02eb9436eee9a21446a6477debf17e81685"
integrity sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==
fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
dependencies:
function-bind "^1.1.1"
immutable@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23"
integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
dependencies:
binary-extensions "^2.0.0"
is-core-module@^2.8.1:
version "2.8.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==
dependencies:
has "^1.0.3"
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
is-glob@^4.0.1, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
magic-string@^0.25.7:
version "0.25.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051"
integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==
dependencies:
sourcemap-codec "^1.4.4"
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
nanoid@^3.1.30:
version "3.2.0"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picomatch@^2.0.4, picomatch@^2.2.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
postcss@^8.1.10, postcss@^8.4.5:
version "8.4.5"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.5.tgz#bae665764dfd4c6fcc24dc0fdf7e7aa00cc77f95"
integrity sha512-jBDboWM8qpaqwkMwItqTQTiFikhs/67OYVvblFFTM7MrZjt6yMKd6r2kgXizEbTTljacm4NldIlZnhbjr84QYg==
dependencies:
nanoid "^3.1.30"
picocolors "^1.0.0"
source-map-js "^1.0.1"
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
dependencies:
picomatch "^2.2.1"
resolve@^1.20.0:
version "1.22.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
dependencies:
is-core-module "^2.8.1"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
rollup@^2.59.0:
version "2.66.1"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.66.1.tgz#366b0404de353c4331d538c3ad2963934fcb4937"
integrity sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==
optionalDependencies:
fsevents "~2.3.2"
sass@^1.49.0:
version "1.49.0"
resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.0.tgz#65ec1b1d9a6bc1bae8d2c9d4b392c13f5d32c078"
integrity sha512-TVwVdNDj6p6b4QymJtNtRS2YtLJ/CqZriGg0eIAbAKMlN8Xy6kbv33FsEZSF7FufFFM705SQviHjjThfaQ4VNw==
dependencies:
chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0"
source-map-js ">=0.6.2 <2.0.0"
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
sourcemap-codec@^1.4.4:
version "1.4.8"
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
vite@^2.7.2:
version "2.7.13"
resolved "https://registry.yarnpkg.com/vite/-/vite-2.7.13.tgz#99b56e27dfb1e4399e407cf94648f5c7fb9d77f5"
integrity sha512-Mq8et7f3aK0SgSxjDNfOAimZGW9XryfHRa/uV0jseQSilg+KhYDSoNb9h1rknOy6SuMkvNDLKCYAYYUMCE+IgQ==
dependencies:
esbuild "^0.13.12"
postcss "^8.4.5"
resolve "^1.20.0"
rollup "^2.59.0"
optionalDependencies:
fsevents "~2.3.2"
vue-router@^4.0.12:
version "4.0.12"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.12.tgz#8dc792cddf5bb1abcc3908f9064136de7e13c460"
integrity sha512-CPXvfqe+mZLB1kBWssssTiWg4EQERyqJZes7USiqfW9B5N2x+nHlnsM1D3b5CaJ6qgCvMmYJnz+G0iWjNCvXrg==
dependencies:
"@vue/devtools-api" "^6.0.0-beta.18"
vue@^3.2.25:
version "3.2.29"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.29.tgz#3571b65dbd796d3a6347e2fd45a8e6e11c13d56a"
integrity sha512-cFIwr7LkbtCRanjNvh6r7wp2yUxfxeM2yPpDQpAfaaLIGZSrUmLbNiSze9nhBJt5MrZ68Iqt0O5scwAMEVxF+Q==
dependencies:
"@vue/compiler-dom" "3.2.29"
"@vue/compiler-sfc" "3.2.29"
"@vue/runtime-dom" "3.2.29"
"@vue/server-renderer" "3.2.29"
"@vue/shared" "3.2.29"
vuex@^4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.2.tgz#f896dbd5bf2a0e963f00c67e9b610de749ccacc9"
integrity sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==
dependencies:
"@vue/devtools-api" "^6.0.0-beta.11"