Merge branch 'feature/info_message' into develop
This commit is contained in:
commit
75056fc932
|
@ -4,8 +4,8 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
<link rel="icon" href="<%= BASE_URL %>wuicon.ico">
|
||||||
<title>newgruecht-vue</title>
|
<title>Flaschengeist</title>
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900">
|
||||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
|
@ -3,7 +3,7 @@
|
||||||
<v-btn icon>
|
<v-btn icon>
|
||||||
<v-img src="@/assets/logo-big.png" contain height="40"></v-img>
|
<v-img src="@/assets/logo-big.png" contain height="40"></v-img>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-toolbar-title>WU5-Dashboard</v-toolbar-title>
|
<v-toolbar-title>Flaschengeist</v-toolbar-title>
|
||||||
<v-spacer />
|
<v-spacer />
|
||||||
<v-btn icon v-if="isFinanzer">
|
<v-btn icon v-if="isFinanzer">
|
||||||
<v-icon>{{attach_money}}</v-icon>
|
<v-icon>{{attach_money}}</v-icon>
|
||||||
|
|
|
@ -1,9 +1,47 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
|
<v-dialog v-model="dialog" max-width="290">
|
||||||
|
<v-card>
|
||||||
|
<v-card-title class="headline"
|
||||||
|
>Transaktion ist länger als 5 Minuten her!</v-card-title
|
||||||
|
>
|
||||||
|
<v-card-text>
|
||||||
|
Da die Transaktion länger als 5 Minutern her ist, kann eine
|
||||||
|
Stornierung nicht durchgeführt werden. Wende dich bitte an den
|
||||||
|
Finanzer.
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer />
|
||||||
|
<v-btn text @click="dialog = false">
|
||||||
|
Verstanden
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
<v-progress-linear v-if="loading && users.length !== 0" indeterminate />
|
<v-progress-linear v-if="loading && users.length !== 0" indeterminate />
|
||||||
<v-container>
|
<v-container>
|
||||||
<AddAmountSkeleton v-if="loading && users.length === 0" />
|
<AddAmountSkeleton v-if="loading && users.length === 0" />
|
||||||
</v-container>
|
</v-container>
|
||||||
|
<v-navigation-drawer v-model="menu" right app clipped>
|
||||||
|
<v-list-item-group>
|
||||||
|
<div
|
||||||
|
v-for="message in messages"
|
||||||
|
three-line
|
||||||
|
:key="messages.indexOf(message)"
|
||||||
|
>
|
||||||
|
<v-list-item three-line>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>{{ now(message.date) }}</v-list-item-title>
|
||||||
|
<v-list-item-subtitle>{{ message.message }}</v-list-item-subtitle>
|
||||||
|
<v-list-item-subtitle class="red--text" v-if="message.storno">STORNIERT!!!</v-list-item-subtitle>
|
||||||
|
<v-list-item-action-text @click.stop="storno(message)"
|
||||||
|
>Klicken um zu Stornieren
|
||||||
|
</v-list-item-action-text>
|
||||||
|
</v-list-item-content>
|
||||||
|
</v-list-item>
|
||||||
|
</div>
|
||||||
|
</v-list-item-group>
|
||||||
|
</v-navigation-drawer>
|
||||||
<div v-for="user in users" :key="users.indexOf(user)">
|
<div v-for="user in users" :key="users.indexOf(user)">
|
||||||
<div v-if="isFiltered(user)">
|
<div v-if="isFiltered(user)">
|
||||||
<v-container>
|
<v-container>
|
||||||
|
@ -22,7 +60,11 @@
|
||||||
class="creditBtn"
|
class="creditBtn"
|
||||||
block
|
block
|
||||||
@click="
|
@click="
|
||||||
addAmount({ username: user.username, amount: 200 })
|
addAmount({
|
||||||
|
username: user.username,
|
||||||
|
amount: 200,
|
||||||
|
user: user
|
||||||
|
})
|
||||||
"
|
"
|
||||||
:color="color"
|
:color="color"
|
||||||
:disabled="user.locked"
|
:disabled="user.locked"
|
||||||
|
@ -34,7 +76,11 @@
|
||||||
class="creditBtn"
|
class="creditBtn"
|
||||||
block
|
block
|
||||||
@click="
|
@click="
|
||||||
addAmount({ username: user.username, amount: 100 })
|
addAmount({
|
||||||
|
username: user.username,
|
||||||
|
amount: 100,
|
||||||
|
user: user
|
||||||
|
})
|
||||||
"
|
"
|
||||||
:color="color"
|
:color="color"
|
||||||
:disabled="user.locked"
|
:disabled="user.locked"
|
||||||
|
@ -46,7 +92,11 @@
|
||||||
class="creditBtn"
|
class="creditBtn"
|
||||||
block
|
block
|
||||||
@click="
|
@click="
|
||||||
addAmount({ username: user.username, amount: 50 })
|
addAmount({
|
||||||
|
username: user.username,
|
||||||
|
amount: 50,
|
||||||
|
user: user
|
||||||
|
})
|
||||||
"
|
"
|
||||||
:color="color"
|
:color="color"
|
||||||
:disabled="user.locked"
|
:disabled="user.locked"
|
||||||
|
@ -60,7 +110,11 @@
|
||||||
class="creditBtn"
|
class="creditBtn"
|
||||||
block
|
block
|
||||||
@click="
|
@click="
|
||||||
addAmount({ username: user.username, amount: 40 })
|
addAmount({
|
||||||
|
username: user.username,
|
||||||
|
amount: 40,
|
||||||
|
user: user
|
||||||
|
})
|
||||||
"
|
"
|
||||||
:color="color"
|
:color="color"
|
||||||
:disabled="user.locked"
|
:disabled="user.locked"
|
||||||
|
@ -72,7 +126,11 @@
|
||||||
class="creditBtn"
|
class="creditBtn"
|
||||||
block
|
block
|
||||||
@click="
|
@click="
|
||||||
addAmount({ username: user.username, amount: 20 })
|
addAmount({
|
||||||
|
username: user.username,
|
||||||
|
amount: 20,
|
||||||
|
user: user
|
||||||
|
})
|
||||||
"
|
"
|
||||||
:color="color"
|
:color="color"
|
||||||
:disabled="user.locked"
|
:disabled="user.locked"
|
||||||
|
@ -84,7 +142,11 @@
|
||||||
class="creditBtn"
|
class="creditBtn"
|
||||||
block
|
block
|
||||||
@click="
|
@click="
|
||||||
addAmount({ username: user.username, amount: 10 })
|
addAmount({
|
||||||
|
username: user.username,
|
||||||
|
amount: 10,
|
||||||
|
user: user
|
||||||
|
})
|
||||||
"
|
"
|
||||||
:color="color"
|
:color="color"
|
||||||
:disabled="user.locked"
|
:disabled="user.locked"
|
||||||
|
@ -113,6 +175,17 @@
|
||||||
>
|
>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
<v-snackbar
|
||||||
|
v-for="message in messages"
|
||||||
|
:key="messages.indexOf(message)"
|
||||||
|
:color="message.error ? 'error' : 'success'"
|
||||||
|
bottom
|
||||||
|
:timeout="3000"
|
||||||
|
:multi-line="true"
|
||||||
|
v-model="message.visible"
|
||||||
|
>
|
||||||
|
{{ message.message }}
|
||||||
|
</v-snackbar>
|
||||||
</v-container>
|
</v-container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -129,16 +202,21 @@ export default {
|
||||||
props: {},
|
props: {},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
color: 'green accent-4'
|
color: 'green accent-4',
|
||||||
|
menu: true,
|
||||||
|
dialog: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
this.menu = this.menu_from_store
|
||||||
this.getUsers()
|
this.getUsers()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions({
|
...mapActions({
|
||||||
addAmount: 'barUsers/addAmount',
|
addAmount: 'barUsers/addAmount',
|
||||||
getUsers: 'barUsers/getUsers'
|
getUsers: 'barUsers/getUsers',
|
||||||
|
deactivate: 'barUsers/deactivateMenu',
|
||||||
|
commitStorno: 'barUsers/storno'
|
||||||
}),
|
}),
|
||||||
getColor(type) {
|
getColor(type) {
|
||||||
return type === 'credit' ? 'title green--text' : 'title red--text'
|
return type === 'credit' ? 'title green--text' : 'title red--text'
|
||||||
|
@ -152,14 +230,84 @@ export default {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
storno(message) {
|
||||||
|
if (!message.error) {
|
||||||
|
if (!this.under5minutes(message.date)) this.dialog = true
|
||||||
|
else {
|
||||||
|
this.commitStorno({username: message.user.username, amount: message.amount, date: message.date})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
users: 'barUsers/users',
|
users: 'barUsers/users',
|
||||||
filter: 'barUsers/filter',
|
filter: 'barUsers/filter',
|
||||||
loading: 'barUsers/usersLoading'
|
loading: 'barUsers/usersLoading',
|
||||||
})
|
messages: 'barUsers/messages',
|
||||||
|
menu_from_store: 'barUsers/menu'
|
||||||
|
}),
|
||||||
|
under5minutes() {
|
||||||
|
return now => {
|
||||||
|
var actual = new Date()
|
||||||
|
var zero = new Date(0)
|
||||||
|
var date = new Date(actual - now)
|
||||||
|
if (
|
||||||
|
date.getFullYear() === zero.getFullYear() &&
|
||||||
|
date.getMonth() === zero.getMonth() &&
|
||||||
|
date.getDate() === zero.getDate()
|
||||||
|
) {
|
||||||
|
if (date.getMinutes() < 6) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
now() {
|
||||||
|
return now => {
|
||||||
|
var actual = new Date()
|
||||||
|
var zero = new Date(0)
|
||||||
|
var date = new Date(actual - now)
|
||||||
|
if (date.getFullYear() === zero.getFullYear()) {
|
||||||
|
if (date.getMonth() === zero.getMonth()) {
|
||||||
|
if (date.getDate() === zero.getDate()) {
|
||||||
|
if (date.getHours() === zero.getDate()) {
|
||||||
|
if (date.getMinutes() < 1) {
|
||||||
|
return 'vor ' + date.getSeconds() + ' Sekunden'
|
||||||
|
} else if (date.getMinutes() < 10) {
|
||||||
|
return 'vor ' + date.getMinutes() + ' Minuten'
|
||||||
|
} else {
|
||||||
|
return now.getHours() + ':' + now.getMinutes()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return now.getHours() + ':' + now.getMinutes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
now.getDate() +
|
||||||
|
'.' +
|
||||||
|
now.getMonth() +
|
||||||
|
'.' +
|
||||||
|
now.getFullYear() +
|
||||||
|
' ' +
|
||||||
|
now.getHours() +
|
||||||
|
':' +
|
||||||
|
now.getMinutes()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
menu(newValue) {
|
||||||
|
if (!newValue) this.deactivate()
|
||||||
|
},
|
||||||
|
menu_from_store(newValue) {
|
||||||
|
if (newValue) this.menu = this.menu_from_store
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -16,10 +16,13 @@
|
||||||
:search-input.sync="filter"
|
:search-input.sync="filter"
|
||||||
>
|
>
|
||||||
<template v-slot:prepend-inner>
|
<template v-slot:prepend-inner>
|
||||||
<v-icon>{{search_person}}</v-icon>
|
<v-icon>{{ search_person }}</v-icon>
|
||||||
</template>
|
</template>
|
||||||
</v-autocomplete>
|
</v-autocomplete>
|
||||||
<v-btn text @click="addUser">Hinzufügen</v-btn>
|
<v-btn text @click="addUser">Hinzufügen</v-btn>
|
||||||
|
<v-btn @click="clickMenu" icon>
|
||||||
|
<v-icon>{{ menuIcon }}</v-icon>
|
||||||
|
</v-btn>
|
||||||
</v-toolbar-items>
|
</v-toolbar-items>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,7 +30,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { mapGetters, mapActions } from 'vuex'
|
import { mapGetters, mapActions } from 'vuex'
|
||||||
import { mdiAccountSearch } from '@mdi/js'
|
import { mdiAccountSearch, mdiMenu } from '@mdi/js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SearchBar',
|
name: 'SearchBar',
|
||||||
|
@ -36,7 +39,8 @@ export default {
|
||||||
return {
|
return {
|
||||||
user: null,
|
user: null,
|
||||||
filter: '',
|
filter: '',
|
||||||
search_person: mdiAccountSearch
|
search_person: mdiAccountSearch,
|
||||||
|
menuIcon: mdiMenu
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -46,17 +50,24 @@ export default {
|
||||||
...mapActions({
|
...mapActions({
|
||||||
getAllUsers: 'barUsers/getAllUsers',
|
getAllUsers: 'barUsers/getAllUsers',
|
||||||
addCreditList: 'barUsers/addCreditList',
|
addCreditList: 'barUsers/addCreditList',
|
||||||
setFilter: 'barUsers/setFilter'
|
setFilter: 'barUsers/setFilter',
|
||||||
|
activateMenu: 'barUsers/activateMenu',
|
||||||
|
deactivateMenu: 'barUsers/deactivateMenu'
|
||||||
}),
|
}),
|
||||||
addUser() {
|
addUser() {
|
||||||
this.addCreditList(this.user)
|
this.addCreditList(this.user)
|
||||||
this.user = null
|
this.user = null
|
||||||
|
},
|
||||||
|
clickMenu() {
|
||||||
|
if (this.menu) this.deactivateMenu()
|
||||||
|
else this.activateMenu()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
allUsers: 'barUsers/allUsers',
|
allUsers: 'barUsers/allUsers',
|
||||||
loading: 'barUsers/allUsersLoading'
|
loading: 'barUsers/allUsersLoading',
|
||||||
|
menu: 'barUsers/menu'
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import Vue from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import vuetify from './plugins/vuetify';
|
import vuetify from './plugins/vuetify'
|
||||||
|
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,9 @@ const url = {
|
||||||
user: {
|
user: {
|
||||||
config: main + 'user/saveConfig',
|
config: main + 'user/saveConfig',
|
||||||
job: main + 'user/job'
|
job: main + 'user/job'
|
||||||
|
},
|
||||||
|
barU: {
|
||||||
|
storno: main + 'bar/storno'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ import FinanzerNavigation from '../components/finanzer/FinanzerNavigation'
|
||||||
import Overview from '../components/finanzer/Overview'
|
import Overview from '../components/finanzer/Overview'
|
||||||
import User from '../components/finanzer/User'
|
import User from '../components/finanzer/User'
|
||||||
import ServiceManagement from '../components/vorstand/ServiceManagement'
|
import ServiceManagement from '../components/vorstand/ServiceManagement'
|
||||||
import Config from "@/components/user/Config";
|
import Config from '@/components/user/Config'
|
||||||
import Jobs from "@/components/user/Jobs";
|
import Jobs from '@/components/user/Jobs'
|
||||||
|
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter)
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@ const state = {
|
||||||
allUsers: [],
|
allUsers: [],
|
||||||
filter: '',
|
filter: '',
|
||||||
usersLoading: false,
|
usersLoading: false,
|
||||||
allUsersLoading: false
|
allUsersLoading: false,
|
||||||
|
message: [],
|
||||||
|
menu: false
|
||||||
}
|
}
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
@ -70,6 +72,47 @@ const mutations = {
|
||||||
},
|
},
|
||||||
setAllUsersLoading: (state, value) => {
|
setAllUsersLoading: (state, value) => {
|
||||||
state.allUsersLoading = value
|
state.allUsersLoading = value
|
||||||
|
},
|
||||||
|
addMessage: (state, data) => {
|
||||||
|
var message = ''
|
||||||
|
if (data.error) {
|
||||||
|
message =
|
||||||
|
'Konnte ' +
|
||||||
|
(data.amount / 100).toFixed(2) +
|
||||||
|
'€ zu ' +
|
||||||
|
data.user.firstname +
|
||||||
|
' ' +
|
||||||
|
data.user.lastname +
|
||||||
|
' hinzufügen.'
|
||||||
|
} else {
|
||||||
|
message =
|
||||||
|
'' +
|
||||||
|
(data.amount / 100).toFixed(2) +
|
||||||
|
'€ wurde zu ' +
|
||||||
|
data.user.firstname +
|
||||||
|
' ' +
|
||||||
|
data.user.lastname +
|
||||||
|
' hinzugefügt.'
|
||||||
|
}
|
||||||
|
state.message.unshift({
|
||||||
|
message: message,
|
||||||
|
user: data.user,
|
||||||
|
error: data.error,
|
||||||
|
storno: false,
|
||||||
|
visible: true,
|
||||||
|
amount: data.amount,
|
||||||
|
date: new Date()
|
||||||
|
})
|
||||||
|
console.log(state.message)
|
||||||
|
},
|
||||||
|
updateMessage: (state, data) => {
|
||||||
|
var message = state.message.find(msg => {return msg.date - data.date === 0 ? true : false})
|
||||||
|
if (message) {
|
||||||
|
message.storno = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setMenu: (state, value) => {
|
||||||
|
state.menu = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +140,17 @@ const actions = {
|
||||||
{ headers: { Token: rootState.login.user.accessToken } }
|
{ headers: { Token: rootState.login.user.accessToken } }
|
||||||
)
|
)
|
||||||
commit('setUsers', { [response.data.username]: response.data })
|
commit('setUsers', { [response.data.username]: response.data })
|
||||||
|
commit('addMessage', {
|
||||||
|
user: data.user,
|
||||||
|
amount: data.amount,
|
||||||
|
error: false
|
||||||
|
})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
commit('addMessage', {
|
||||||
|
user: data.user,
|
||||||
|
amount: data.amount,
|
||||||
|
error: true
|
||||||
|
})
|
||||||
if (e.response)
|
if (e.response)
|
||||||
if (e.response.status === 401) dispatch('logout', null, { root: true })
|
if (e.response.status === 401) dispatch('logout', null, { root: true })
|
||||||
}
|
}
|
||||||
|
@ -133,8 +186,33 @@ const actions = {
|
||||||
}
|
}
|
||||||
commit('setAllUsersLoading', false)
|
commit('setAllUsersLoading', false)
|
||||||
},
|
},
|
||||||
|
async storno({ commit, rootState, dispatch }, data) {
|
||||||
|
commit('setUsersLoading', true)
|
||||||
|
try {
|
||||||
|
const response = await axios.post(
|
||||||
|
url.barU.storno,
|
||||||
|
{
|
||||||
|
userId: data.username,
|
||||||
|
amount: data.amount
|
||||||
|
},
|
||||||
|
{ headers: { Token: rootState.login.user.accessToken } }
|
||||||
|
)
|
||||||
|
commit('setUsers', { [response.data.username]: response.data })
|
||||||
|
commit('updateMessage', { date: data.date })
|
||||||
|
} catch (e) {
|
||||||
|
if (e.response)
|
||||||
|
if (e.response.status === 401) dispatch('logout', null, { root: true })
|
||||||
|
}
|
||||||
|
commit('setUsersLoading', false)
|
||||||
|
},
|
||||||
setFilter({ commit }, data) {
|
setFilter({ commit }, data) {
|
||||||
commit('setFilter', data)
|
commit('setFilter', data)
|
||||||
|
},
|
||||||
|
activateMenu({ commit }) {
|
||||||
|
commit('setMenu', true)
|
||||||
|
},
|
||||||
|
deactivateMenu({ commit }) {
|
||||||
|
commit('setMenu', false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +231,12 @@ const getters = {
|
||||||
},
|
},
|
||||||
allUsersLoading: state => {
|
allUsersLoading: state => {
|
||||||
return state.allUsersLoading
|
return state.allUsersLoading
|
||||||
|
},
|
||||||
|
messages: state => {
|
||||||
|
return state.message
|
||||||
|
},
|
||||||
|
menu: state => {
|
||||||
|
return state.menu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue