Merge branch 'user-page-apollo-toast-packages' into monterail_vue3_migration

This commit is contained in:
Kamila 2024-07-26 08:03:22 +02:00
commit 462fcd7eef
13 changed files with 530 additions and 680 deletions

View File

@ -82,6 +82,7 @@ declare module 'vue' {
IPhCaretDown: typeof import('~icons/ph/caret-down')['default']
IPhCaretUpFill: typeof import('~icons/ph/caret-up-fill')['default']
IPhEnvelope: typeof import('~icons/ph/envelope')['default']
IPhXCircle: typeof import('~icons/ph/x-circle')['default']
NavBar: typeof import('./src/components/NavBar.vue')['default']
NotFoundPage: typeof import('./src/components/NotFoundPage.vue')['default']
OpenCreationsTable: typeof import('./src/components/Tables/OpenCreationsTable.vue')['default']
@ -97,7 +98,8 @@ declare module 'vue' {
UserQuery: typeof import('./src/components/UserQuery.vue')['default']
}
export interface ComponentCustomProperties {
vBModal: typeof import('bootstrap-vue-next')['vBModal']
vBToggle: typeof import('bootstrap-vue-next')['vBToggle']
vBTooltip: typeof import('bootstrap-vue-next')['vBTooltip']
}
}

View File

@ -4,7 +4,7 @@ const path = require('path')
// Host & Port
const hostname = '127.0.0.1'
const port = process.env.PORT || 8080
const port = import.meta.env.PORT || 8080
// Express Server
const app = express()

View File

@ -3,16 +3,13 @@
<BToastOrchestrator />
<default-layout v-if="$store.state.token" />
<router-view v-else></router-view>
<BModalOrchestrator />
</div>
</template>
<script>
<script setup>
import defaultLayout from '@/layouts/defaultLayout'
export default {
name: 'App',
components: { defaultLayout },
}
import { BModalOrchestrator } from 'bootstrap-vue-next'
</script>
<style>
.pointer {

View File

@ -1,125 +1,100 @@
<template>
<div class="change-user-role-formular">
<div class="shadow p-3 mb-5 bg-white rounded">
<div v-if="!$store.state.moderator.roles.includes('ADMIN')" class="m-3 mb-4">
{{ roles.find((role) => role.value === currentRole).text }}
<div v-if="!isModeratorRoleAdmin" class="m-3 mb-4">
{{ roles.find((role) => role.value === currentRole.value).text }}
</div>
<div v-else-if="item.userId === $store.state.moderator.id" class="m-3 mb-4">
<div v-else-if="item.userId === moderatorId" class="m-3 mb-4">
{{ $t('userRole.notChangeYourSelf') }}
</div>
<div v-else class="m-3">
<label for="role" class="mr-3">{{ $t('userRole.selectLabel') }}</label>
<b-form-select v-model="roleSelected" class="role-select" :options="roles" />
<BFormSelect v-model="roleSelected" class="role-select" :options="roles" />
<div class="mt-3 mb-5">
<b-button
v-b-modal.user-role-modal
variant="danger"
:disabled="currentRole === roleSelected"
@click="showModal()"
>
<BButton variant="danger" @click="showModal">
<!-- :disabled="currentRole.value === roleSelected.value" -->
{{ $t('change_user_role') }}
</b-button>
</BButton>
</div>
</div>
</div>
</div>
</template>
<script>
import { setUserRole } from '../graphql/setUserRole'
<script setup>
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { BButton, BFormSelect } from 'bootstrap-vue-next'
import { useMutation } from '@vue/apollo-composable'
import { setUserRole as setUserRoleMutation } from '../graphql/setUserRole'
import { useStore } from 'vuex'
import { useAppToast } from '@/composables/useToast'
const { t } = useI18n()
const store = useStore()
const { toastError, toastSuccess } = useAppToast()
const rolesValues = {
ADMIN: 'ADMIN',
MODERATOR: 'MODERATOR',
USER: 'USER',
}
export default {
name: 'ChangeUserRoleFormular',
props: {
item: {
type: Object,
required: true,
},
},
emits: ['update-roles'],
data() {
return {
currentRole: this.getCurrentRole(),
roleSelected: this.getCurrentRole(),
roles: [
{ value: rolesValues.USER, text: this.$t('userRole.selectRoles.user') },
{ value: rolesValues.MODERATOR, text: this.$t('userRole.selectRoles.moderator') },
{ value: rolesValues.ADMIN, text: this.$t('userRole.selectRoles.admin') },
],
}
},
methods: {
getCurrentRole() {
if (this.item.roles.length) return rolesValues[this.item.roles[0]]
return rolesValues.USER
},
showModal() {
this.$bvModal
.msgBoxConfirm(
this.$t('overlay.changeUserRole.question', {
username: `${this.item.firstName} ${this.item.lastName}`,
newRole:
this.roleSelected === rolesValues.ADMIN
? this.$t('userRole.selectRoles.admin')
: this.roleSelected === rolesValues.MODERATOR
? this.$t('userRole.selectRoles.moderator')
: this.$t('userRole.selectRoles.user'),
}),
{
cancelTitle: this.$t('overlay.cancel'),
centered: true,
hideHeaderClose: true,
title: this.$t('overlay.changeUserRole.title'),
okTitle: this.$t('overlay.changeUserRole.yes'),
okVariant: 'danger',
},
)
.then((okClicked) => {
if (okClicked) {
this.setUserRole(this.roleSelected, this.currentRole)
}
})
.catch((error) => {
this.toastError(error.message)
})
},
setUserRole(newRole, oldRole) {
const role = this.roles.find((role) => {
return role.value === newRole
})
const roleText = role.text
const roleValue = role.value
this.$apollo
.mutate({
mutation: setUserRole,
variables: {
userId: this.item.userId,
role: role.value,
},
})
.then((result) => {
this.$emit('update-roles', {
userId: this.item.userId,
roles: roleValue === 'USER' ? [] : [roleValue],
})
this.toastSuccess(
this.$t('userRole.successfullyChangedTo', {
role: roleText,
}),
)
})
.catch((error) => {
this.roleSelected = oldRole
this.toastError(error.message)
})
},
const props = defineProps({
item: {
type: Object,
required: true,
},
})
const getCurrentRole = () => {
if (props.item.roles.length) return rolesValues[props.item.roles[0]]
return rolesValues.USER
}
const currentRole = ref(getCurrentRole())
const roleSelected = ref(getCurrentRole())
const emit = defineEmits(['update-roles', 'show-modal', 'select-role'])
const isModeratorRoleAdmin = computed(() => store.state.moderator.roles.includes('ADMIN'))
const moderatorId = computed(() => store.state.moderator.id)
const roles = computed(() => [
{ value: rolesValues.USER, text: t('userRole.selectRoles.user') },
{ value: rolesValues.MODERATOR, text: t('userRole.selectRoles.moderator') },
{ value: rolesValues.ADMIN, text: t('userRole.selectRoles.admin') },
])
const showModal = async () => {
emit('show-modal')
}
const { mutate: setUserRole } = useMutation(setUserRoleMutation)
const updateUserRole = (newRole, oldRole) => {
const role = roles.value.find((role) => role.value === newRole)
const roleText = role.text
const roleValue = role.value
setUserRole({
userId: props.item.userId,
role: role.value,
})
.then(() => {
emit('update-roles', {
userId: props.item.userId,
roles: roleValue === 'USER' ? [] : [roleValue],
})
toastSuccess(
t('userRole.successfullyChangedTo', {
role: roleText,
}),
)
})
.catch((error) => {
roleSelected.value = oldRole
toastError(error.message)
})
}
defineExpose({ currentRole, roleSelected, updateUserRole })
</script>
<style>

View File

@ -1,60 +1,62 @@
<template>
<div class="component-confirm-register-mail">
<div class="shadow p-3 mb-5 bg-white rounded">
<div v-if="checked">{{ $t('unregister_mail.text_true') }}</div>
<div v-if="props.checked">{{ $t('unregister_mail.text_true') }}</div>
<div v-else>
{{
dateLastSend === ''
? $t('unregister_mail.never_sent', { email })
: $t('unregister_mail.text_false', { date: dateLastSend, email })
props.dateLastSend === ''
? $t('unregister_mail.never_sent', { email: props.email })
: $t('unregister_mail.text_false', { date: props.dateLastSend, email: props.email })
}}
<!-- Using components -->
<b-input-group :prepend="$t('unregister_mail.info')" class="mt-3">
<b-form-input readonly :value="email"></b-form-input>
<b-input-group-append>
<b-button variant="outline-success" class="test-button" @click="sendRegisterMail">
<BInputGroup :prepend="$t('unregister_mail.info')" class="mt-3">
<BFormInput v-model="email" readonly />
<BInputGroupText>
<BButton variant="outline-success" class="test-button" @click="sendRegisterMail">
{{ $t('unregister_mail.button') }}
</b-button>
</b-input-group-append>
</b-input-group>
</BButton>
</BInputGroupText>
</BInputGroup>
</div>
</div>
</div>
</template>
<script>
<script setup>
import { ref } from 'vue'
import { sendActivationEmail } from '../graphql/sendActivationEmail'
import { BButton, BFormInput, BInputGroup, BInputGroupText } from 'bootstrap-vue-next'
import { useI18n } from 'vue-i18n'
import { useMutation } from '@vue/apollo-composable'
import { useAppToast } from '@/composables/useToast'
export default {
name: 'ConfirmRegisterMail',
props: {
checked: {
type: Boolean,
},
email: {
type: String,
},
dateLastSend: {
type: String,
},
const props = defineProps({
checked: {
type: Boolean,
},
methods: {
sendRegisterMail() {
this.$apollo
.mutate({
mutation: sendActivationEmail,
variables: {
email: this.email,
},
})
.then(() => {
this.toastSuccess(this.$t('unregister_mail.success', { email: this.email }))
})
.catch((error) => {
this.toastError(this.$t('unregister_mail.error', { message: error.message }))
})
},
email: {
type: String,
},
dateLastSend: {
type: String,
},
})
const { t } = useI18n()
const { toastError, toastSuccess } = useAppToast()
const email = ref(props.email)
const { mutate: activateEmail } = useMutation(sendActivationEmail)
const sendRegisterMail = async () => {
try {
await activateEmail({
email: email.value,
})
toastSuccess(t('unregister_mail.success', { email: email.value }))
} catch (error) {
toastError(t('unregister_mail.error', { message: error.message }))
}
}
</script>
<style>

View File

@ -30,7 +30,7 @@
</template>
<script setup>
import CONFIG from '../config'
import { BTr } from 'bootstrap-vue-next'
import { BTr, BCol } from 'bootstrap-vue-next'
const year = new Date().getFullYear()
const version = CONFIG.APP_VERSION

View File

@ -14,13 +14,17 @@
name="month-selection"
/>
</div>
<div v-if="selected" class="m-4">
<div v-if="selected" class="m-4 d-flex">
<label>{{ $t('creation_form.select_value') }}</label>
<div>
<BInputGroup prepend="GDD" append=".00">
<BFormInput v-model="value" type="number" :min="rangeMin" :max="rangeMax" />
</BInputGroup>
<BInputGroup prepend="0" :append="String(rangeMax)" class="mt-3">
<BInputGroup
prepend="0"
:append="String(rangeMax)"
class="mt-3 flex-nowrap align-items-center"
>
<BFormInput v-model="value" type="range" :min="rangeMin" :max="rangeMax" step="10" />
</BInputGroup>
</div>
@ -37,13 +41,11 @@
/>
</div>
</div>
<div class="m-4 d-flex">
<BCol class="text-left">
<BButton type="reset" variant="danger" @click="onReset()">
{{ $t('creation_form.reset') }}
</BButton>
</BCol>
<div class="text-right">
<div class="buttons-wrapper d-flex justify-content-between">
<BButton type="reset" variant="danger" @click="onReset()">
{{ $t('creation_form.reset') }}
</BButton>
<div>
<BButton
v-if="pagetype === 'PageCreationConfirm'"
type="button"
@ -74,6 +76,7 @@
<script setup>
import { ref, watch, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { useAppToast } from '@/composables/useToast'
import { useMutation, useQuery } from '@vue/apollo-composable'
import { useStore } from 'vuex'
import { adminCreateContribution } from '../graphql/adminCreateContribution'
@ -84,11 +87,11 @@ import {
BForm,
BInputGroup,
BButton,
BCol,
BFormTextarea,
} from 'bootstrap-vue-next'
const { radioOptions } = useCreationMonths()
const { toastError, toastSuccess } = useAppToast()
const props = defineProps({
pagetype: {
@ -156,16 +159,16 @@ const submitCreation = async () => {
store.commit('openCreationsPlus', 1)
// toast.success(
// t('creation_form.toasted', {
// value: value.value,
// email: props.item.email,
// }),
// )
toastSuccess(
t('creation_form.toasted', {
value: value.value,
email: props.item.email,
}),
)
onReset()
} catch (error) {
// toast.error(error.message)
toastError(error.message)
onReset()
} finally {
refetch()
@ -182,3 +185,8 @@ watch(
},
)
</script>
<style scoped>
.buttons-wrapper {
margin: 1.5rem 2.4rem;
}
</style>

View File

@ -1,16 +1,16 @@
<template>
<div class="component-creation-transaction-list">
<div class="h3">{{ $t('transactionlist.title') }}</div>
<b-table striped hover :fields="fields" :items="items">
<BTable striped hover :fields="fields" :items="items">
<template #cell(contributionDate)="data">
<div class="font-weight-bold">
{{ $d(new Date(data.item.contributionDate), 'month') }}
</div>
<div>{{ $d(new Date(data.item.contributionDate)) }}</div>
</template>
</b-table>
</BTable>
<div>
<b-pagination
<BPagination
v-model="currentPage"
pills
size="lg"
@ -18,101 +18,96 @@
:total-rows="rows"
align="center"
:hide-ellipsis="true"
></b-pagination>
<b-button v-b-toggle.collapse-1 variant="light" size="sm">{{ $t('help.help') }}</b-button>
<b-collapse id="collapse-1" class="mt-2">
/>
<BButton v-b-toggle="'collapse-1'" variant="light" size="sm">{{ t('help.help') }}</BButton>
<BCollapse id="collapse-1" class="mt-2">
<div>
{{ $t('transactionlist.submitted') }} {{ $t('math.equals') }}
{{ $t('help.transactionlist.submitted') }}
{{ t('transactionlist.submitted') }} {{ t('math.equals') }}
{{ t('help.transactionlist.submitted') }}
</div>
<div>
{{ $t('transactionlist.period') }} {{ $t('math.equals') }}
{{ $t('help.transactionlist.periods') }}
{{ t('transactionlist.period') }} {{ t('math.equals') }}
{{ t('help.transactionlist.periods') }}
</div>
<div>
{{ $t('transactionlist.confirmed') }} {{ $t('math.equals') }}
{{ $t('help.transactionlist.confirmed') }}
{{ t('transactionlist.confirmed') }} {{ t('math.equals') }}
{{ t('help.transactionlist.confirmed') }}
</div>
<div>
{{ $t('transactionlist.status') }} {{ $t('math.equals') }}
{{ $t('help.transactionlist.status') }}
{{ t('transactionlist.status') }} {{ t('math.equals') }}
{{ t('help.transactionlist.status') }}
</div>
</b-collapse>
</BCollapse>
</div>
</div>
</template>
<script>
<script setup>
import { ref, watch } from 'vue'
import { useQuery } from '@vue/apollo-composable'
import { adminListContributions } from '../graphql/adminListContributions'
export default {
name: 'CreationTransactionList',
props: {
userId: { type: Number, required: true },
},
data() {
return {
items: [],
rows: 0,
currentPage: 1,
perPage: 10,
fields: [
{
key: 'createdAt',
label: this.$t('transactionlist.submitted'),
formatter: (value, key, item) => {
return this.$d(new Date(value))
},
},
{
key: 'contributionDate',
label: this.$t('transactionlist.period'),
},
{
key: 'confirmedAt',
label: this.$t('transactionlist.confirmed'),
formatter: (value, key, item) => {
if (value) {
return this.$d(new Date(value))
} else {
return null
}
},
},
{
key: 'status',
label: this.$t('transactionlist.status'),
},
{
key: 'amount',
label: this.$t('transactionlist.amount'),
formatter: (value, key, item) => {
return `${value} GDD`
},
},
{ key: 'memo', label: this.$t('transactionlist.memo'), class: 'text-break' },
],
}
},
apollo: {
AdminListContributions: {
query() {
return adminListContributions
},
variables() {
return {
currentPage: this.currentPage,
pageSize: this.perPage,
order: 'DESC',
userId: parseInt(this.userId),
}
},
update({ adminListContributions }) {
this.rows = adminListContributions.contributionCount
this.items = adminListContributions.contributionList
},
error({ message }) {
this.toastError(message)
},
import { BTable, BPagination, BButton, BCollapse, vBToggle } from 'bootstrap-vue-next'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const props = defineProps({
userId: { type: Number, required: true },
})
const items = ref([])
const rows = ref(0)
const currentPage = ref(1)
const perPage = ref(10)
const fields = [
{
key: 'createdAt',
label: t('transactionlist.submitted'),
formatter: (value) => {
return new Date(value).toLocaleDateString()
},
},
}
{
key: 'contributionDate',
label: t('transactionlist.period'),
},
{
key: 'confirmedAt',
label: t('transactionlist.confirmed'),
formatter: (value) => {
return value ? new Date(value).toLocaleDateString() : null
},
},
{
key: 'status',
label: t('transactionlist.status'),
},
{
key: 'amount',
label: t('transactionlist.amount'),
formatter: (value) => {
return `${value} GDD`
},
},
{ key: 'memo', label: t('transactionlist.memo'), class: 'text-break' },
]
const { result, refetch } = useQuery(adminListContributions, {
currentPage: currentPage.value,
pageSize: perPage.value,
order: 'DESC',
userId: props.userId,
})
watch(result, (newResult) => {
if (newResult && newResult.adminListContributions) {
rows.value = newResult.adminListContributions.contributionCount
items.value = newResult.adminListContributions.contributionList
}
})
watch(currentPage, () => {
refetch()
})
</script>

View File

@ -1,127 +1,95 @@
<template>
<div class="deleted-user-formular">
<div v-if="item.userId === $store.state.moderator.id" class="mt-5 mb-5">
<div v-if="isUserModerator" class="mt-5 mb-5">
{{ $t('removeNotSelf') }}
</div>
<div v-else class="mt-5">
<div class="mt-3 mb-5">
<b-button
<BButton
v-if="!item.deletedAt"
v-b-modal.delete-user-modal
variant="danger"
@click="showDeleteModal()"
@click="showDeleteModal"
>
{{ $t('delete_user') }}
</b-button>
<b-button v-else v-b-modal.delete-user-modal variant="success" @click="showUndeleteModal()">
</BButton>
<BButton v-else v-b-modal.delete-user-modal variant="success" @click="showUndeleteModal">
{{ $t('undelete_user') }}
</b-button>
</BButton>
</div>
</div>
</div>
</template>
<script>
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'
import { useApolloClient } from '@vue/apollo-composable'
import { BButton, vBModal } from 'bootstrap-vue-next'
import { deleteUser } from '../graphql/deleteUser'
import { unDeleteUser } from '../graphql/unDeleteUser'
import { useAppToast } from '@/composables/useToast'
export default {
name: 'DeletedUser',
props: {
item: {
type: Object,
required: true,
},
},
emits: ['update-deleted-at'],
methods: {
showDeleteModal() {
this.$bvModal
.msgBoxConfirm(
this.$t('overlay.deleteUser.question', {
username: `${this.item.firstName} ${this.item.lastName}`,
}),
{
cancelTitle: this.$t('overlay.cancel'),
centered: true,
hideHeaderClose: true,
title: this.$t('overlay.deleteUser.title'),
okTitle: this.$t('overlay.deleteUser.yes'),
okVariant: 'danger',
static: true,
},
)
.then((okClicked) => {
if (okClicked) {
this.deleteUser()
}
})
.catch((error) => {
this.toastError(error.message)
})
},
showUndeleteModal() {
this.$bvModal
.msgBoxConfirm(
this.$t('overlay.undeleteUser.question', {
username: `${this.item.firstName} ${this.item.lastName}`,
}),
{
cancelTitle: this.$t('overlay.cancel'),
centered: true,
hideHeaderClose: true,
title: this.$t('overlay.undeleteUser.title'),
okTitle: this.$t('overlay.undeleteUser.yes'),
okVariant: 'success',
},
)
.then((okClicked) => {
if (okClicked) {
this.unDeleteUser()
}
})
.catch((error) => {
this.toastError(error.message)
})
},
deleteUser() {
this.$apollo
.mutate({
mutation: deleteUser,
variables: {
userId: this.item.userId,
},
})
.then((result) => {
this.$emit('update-deleted-at', {
userId: this.item.userId,
deletedAt: result.data.deleteUser,
})
})
.catch((error) => {
this.toastError(error.message)
})
},
unDeleteUser() {
this.$apollo
.mutate({
mutation: unDeleteUser,
variables: {
userId: this.item.userId,
},
})
.then((result) => {
this.$emit('update-deleted-at', {
userId: this.item.userId,
deletedAt: result.data.unDeleteUser,
})
})
.catch((error) => {
this.toastError(error.message)
})
},
const props = defineProps({
item: {
type: Object,
required: true,
},
})
const emit = defineEmits(['update-deleted-at', 'show-delete-modal', 'show-undelete-modal'])
const { client } = useApolloClient()
const store = useStore()
const { toastError } = useAppToast()
const isUserModerator = computed(() => props.item.userId === store.state.moderator.id)
const showDeleteModal = () => {
emit('show-delete-modal')
}
const showUndeleteModal = () => {
emit('show-undelete-modal')
}
const deleteUserMutation = async () => {
try {
const result = await client.mutate({
mutation: deleteUser,
variables: {
userId: props.item.userId,
},
})
emit('update-deleted-at', {
userId: props.item.userId,
deletedAt: result.data.deleteUser,
})
} catch (error) {
toastError(error.message)
}
}
const undeleteUserMutation = async () => {
try {
const result = await client.mutate({
mutation: unDeleteUser,
variables: {
userId: props.item.userId,
},
})
emit('update-deleted-at', {
userId: props.item.userId,
deletedAt: result.data.unDeleteUser,
})
} catch (error) {
toastError(error.message)
}
}
defineExpose({ deleteUserMutation, undeleteUserMutation })
</script>
<style>
.input-group-text {
background-color: rgb(255 252 205);

View File

@ -56,6 +56,7 @@ import {
BNavbarBrand,
BBadge,
BNavbarToggle,
vBToggle,
vBColorMode,
} from 'bootstrap-vue-next'
import { useRoute } from 'vue-router'

View File

@ -32,7 +32,7 @@
style="color: #f5365c"
class="align-center mr-3"
/>
<!-- <b-icon
<!-- <BAvatar
v-if="!row.item.hasElopage"
variant="danger"
class="mr-3"
@ -77,18 +77,35 @@
"
/>
</BTab>
<!-- <BTab :title="$t('creationList')" :disabled="row.item.deletedAt !== null">
<BTab :title="$t('creationList')" :disabled="row.item.deletedAt !== null">
<creation-transaction-list v-if="!row.item.deletedAt" :user-id="row.item.userId" />
</BTab>
<BTab :title="$t('transactionlink.name')" :disabled="row.item.deletedAt !== null">
<transaction-link-list v-if="!row.item.deletedAt" :user-id="row.item.userId" />
</BTab>
<BTab :title="$t('userRole.tabTitle')">
<change-user-role-formular :item="row.item" @update-roles="updateRoles" />
</BTab> -->
<!-- <BTab v-if="store.state.moderator.roles.includes('ADMIN')" :title="$t('delete_user')">
<deleted-user-formular :item="row.item" @update-deleted-at="updateDeletedAt" />
</BTab> -->
<change-user-role-formular
ref="userChangeForm"
:item="row.item"
@update-roles="updateRoles"
@show-modal="showModal"
/>
</BTab>
<BTab v-if="store.state.moderator.roles.includes('ADMIN')" :title="$t('delete_user')">
<deleted-user-formular
v-if="!row.item.deletedAt"
ref="deletedUserForm"
:item="row.item"
@update-deleted-at="updateDeletedAt"
@show-delete-modal="showDeleteModal"
/>
<deleted-user-formular
v-else
ref="undeletedUserForm"
:item="row.item"
@show-undelete-modal="showUndeleteModal"
/>
</BTab>
</BTabs>
</BCard>
</template>
@ -96,10 +113,21 @@
</div>
</template>
<script setup>
import { ref, nextTick, onMounted, watch } from 'vue'
import { BTable, BAvatar, BTab, BTabs, BCard } from 'bootstrap-vue-next'
import { ref, nextTick, onMounted, watch, computed } from 'vue'
import { BTable, BAvatar, BTab, BTabs, BCard, useModalController } from 'bootstrap-vue-next'
import { useStore } from 'vuex'
import { useI18n } from 'vue-i18n'
import { useAppToast } from '@/composables/useToast'
import CreationFormular from '../CreationFormular.vue'
import ConfirmRegisterMailFormular from '../ConfirmRegisterMailFormular.vue'
import CreationTransactionList from '../CreationTransactionList.vue'
import TransactionLinkList from '../TransactionLinkList.vue'
import ChangeUserRoleFormular from '../ChangeUserRoleFormular.vue'
const { t } = useI18n()
const { confirm } = useModalController()
const store = useStore()
const { toastError } = useAppToast()
const props = defineProps({
items: {
@ -112,32 +140,118 @@ const props = defineProps({
},
})
// const emit = defineEmits(['update-roles', 'update-deleted-at'])
const rolesValues = {
ADMIN: 'ADMIN',
MODERATOR: 'MODERATOR',
USER: 'USER',
}
const userChangeForm = ref()
const deletedUserForm = ref()
const undeletedUserForm = ref()
const myItems = ref()
const creationUserData = ref({})
const rowDetails = ref()
onMounted(() => {
setTimeout(() => {
myItems.value = props.items.map((item) => {
return { ...item, _showDetails: false }
const showModal = async () => {
await confirm?.({
props: {
cancelTitle: t('overlay.cancel'),
centered: true,
hideHeaderClose: true,
title: t('overlay.changeUserRole.title'),
okTitle: t('overlay.changeUserRole.yes'),
okVariant: 'danger',
body: t('overlay.changeUserRole.question', {
username: `${selectedRow.value.firstName} ${selectedRow.value.lastName}`,
newRole:
userChangeForm.value.roleSelected === rolesValues.ADMIN
? t('userRole.selectRoles.admin')
: userChangeForm.value.roleSelected === rolesValues.MODERATOR
? t('userRole.selectRoles.moderator')
: t('userRole.selectRoles.user'),
}),
},
})
.then((ok) => {
if (ok) {
userChangeForm.value.updateUserRole(
userChangeForm.value.roleSelected,
userChangeForm.value.currentRole,
)
}
})
.catch((error) => {
toastError(error.message)
})
}
// myItems.value
}, 500)
})
const showDeleteModal = async () => {
await confirm?.({
props: {
cancelTitle: t('overlay.cancel'),
centered: true,
hideHeaderClose: true,
title: t('overlay.deleteUser.title'),
okTitle: t('overlay.deleteUser.yes'),
okVariant: 'danger',
static: true,
body: t('overlay.deleteUser.question', {
username: `${selectedRow.value.firstName} ${selectedRow.value.lastName}`,
}),
},
})
.then((ok) => {
if (ok) {
deletedUserForm.value.deleteUserMutation()
}
})
.catch((error) => {
toastError(error.message)
})
}
const showUndeleteModal = async () => {
await confirm?.({
props: {
cancelTitle: t('overlay.cancel'),
centered: true,
hideHeaderClose: true,
title: t('overlay.undeleteUser.title'),
okTitle: t('overlay.undeleteUser.yes'),
okVariant: 'success',
body: t('overlay.undeleteUser.question', {
username: `${selectedRow.value.firstName} ${selectedRow.value.lastName}`,
}),
},
})
.then((ok) => {
if (ok) {
undeletedUserForm.value.undeleteUserMutation()
}
})
.catch((error) => {
toastError(error.message)
})
}
const updateUserData = (rowItem, newCreation) => {
rowItem.creation = newCreation
}
// const updateRoles = ({ userId, roles }) => {
// emit('update-roles', userId, roles)
// }
//
// const updateDeletedAt = ({ userId, deletedAt }) => {
// emit('update-deleted-at', userId, deletedAt)
// }
const updateRoles = ({ userId, roles }) => {
emit('update-roles', userId, roles)
}
const updateDeletedAt = ({ userId, deletedAt }) => {
emit('update-deleted-at', userId, deletedAt)
}
const emit = defineEmits(['update-roles', 'update-deleted-at'])
const selectedRow = computed(() => {
return myItems.value.find((obj) => obj._showDetails)
})
const onRowClicked = async (item) => {
const status = myItems.value.find((obj) => {
@ -166,4 +280,12 @@ watch(
})
},
)
onMounted(() => {
setTimeout(() => {
myItems.value = props.items.map((item) => {
return { ...item, _showDetails: false }
})
}, 500)
})
</script>

View File

@ -1,10 +1,10 @@
<template>
<div class="transaction-link-list">
<div v-if="items.length > 0">
<div class="h3">{{ $t('transactionlink.name') }}</div>
<b-table striped hover :fields="fields" :items="items"></b-table>
<div class="h3">{{ t('transactionlink.name') }}</div>
<BTable striped hover :fields="fields" :items="items"></BTable>
</div>
<b-pagination
<BPagination
v-model="currentPage"
pills
size="lg"
@ -12,95 +12,80 @@
:total-rows="rows"
align="center"
:hide-ellipsis="true"
></b-pagination>
/>
</div>
</template>
<script>
<script setup>
import { ref, watch, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { BTable, BPagination } from 'bootstrap-vue-next'
import { listTransactionLinksAdmin } from '../graphql/listTransactionLinksAdmin.js'
export default {
name: 'TransactionLinkList',
props: {
userId: { type: Number, required: true },
import { useQuery } from '@vue/apollo-composable'
import { useAppToast } from '@/composables/useToast'
const props = defineProps({
userId: { type: Number, required: true },
})
const { t, d } = useI18n()
const { toastError } = useAppToast()
const items = ref([])
const rows = ref(0)
const currentPage = ref(1)
const perPage = ref(5)
const fields = computed(() => [
{
key: 'createdAt',
label: t('transactionlink.created'),
formatter: (value) => d(new Date(value)),
},
data() {
return {
items: [],
rows: 0,
currentPage: 1,
perPage: 5,
}
{
key: 'amount',
label: t('transactionlist.amount'),
formatter: (value) => `${value} GDD`,
},
computed: {
fields() {
return [
{
key: 'createdAt',
label: this.$t('transactionlink.created'),
formatter: (value, key, item) => {
return this.$d(new Date(value))
},
},
{
key: 'amount',
label: this.$t('transactionlist.amount'),
formatter: (value, key, item) => {
return `${value} GDD`
},
},
{ key: 'memo', label: this.$t('transactionlist.memo'), class: 'text-break' },
{
key: 'validUntil',
label: this.$t('transactionlink.valid_until'),
formatter: (value, key, item) => {
return this.$d(new Date(value))
},
},
{
key: 'status',
label: 'status',
formatter: (value, key, item) => {
// deleted
if (item.deletedAt) return this.$t('deleted') + ': ' + this.$d(new Date(item.deletedAt))
// redeemed
if (item.redeemedAt)
return this.$t('redeemed') + ': ' + this.$d(new Date(item.redeemedAt))
// expired
if (new Date() > new Date(item.validUntil))
return this.$t('expired') + ': ' + this.$d(new Date(item.validUntil))
// open
return this.$t('open')
},
},
]
{ key: 'memo', label: t('transactionlist.memo'), class: 'text-break' },
{
key: 'validUntil',
label: t('transactionlink.valid_until'),
formatter: (value) => d(new Date(value)),
},
{
key: 'status',
label: 'status',
formatter: (value, key, item) => {
if (item.deletedAt) return `${t('deleted')}: ${d(new Date(item.deletedAt))}`
if (item.redeemedAt) return `${t('redeemed')}: ${d(new Date(item.redeemedAt))}`
if (new Date() > new Date(item.validUntil))
return `${t('expired')}: ${d(new Date(item.validUntil))}`
return t('open')
},
},
watch: {
currentPage() {
this.getListTransactionLinks()
},
},
created() {
this.getListTransactionLinks()
},
methods: {
getListTransactionLinks() {
this.$apollo
.query({
query: listTransactionLinksAdmin,
variables: {
currentPage: this.currentPage,
pageSize: this.perPage,
userId: this.userId,
},
})
.then((result) => {
this.rows = result.data.listTransactionLinksAdmin.count
this.items = result.data.listTransactionLinksAdmin.links
})
.catch((error) => {
this.toastError(error.message)
})
},
},
}
])
const { result, error, refetch } = useQuery(listTransactionLinksAdmin, () => ({
currentPage: currentPage.value,
pageSize: perPage.value,
userId: props.userId,
}))
watch(result, (newResult) => {
if (newResult && newResult.listTransactionLinksAdmin) {
rows.value = newResult.listTransactionLinksAdmin.count
items.value = newResult.listTransactionLinksAdmin.links
}
})
watch(error, (err) => {
if (err) {
toastError(error.message)
}
})
watch([currentPage, perPage], () => {
refetch()
})
</script>

View File

@ -1083,31 +1083,6 @@
exec-sh "^0.3.2"
minimist "^1.2.0"
"@csstools/css-parser-algorithms@^2.7.1":
version "2.7.1"
resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz#6d93a8f7d8aeb7cd9ed0868f946e46f021b6aa70"
integrity sha512-2SJS42gxmACHgikc1WGesXLIT8d/q2l0UFM7TaEeIzdFCE/FPMtTiizcPGGJtlPo2xuQzY09OhrLTzRxqJqwGw==
"@csstools/css-tokenizer@^2.4.1":
version "2.4.1"
resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.4.1.tgz#1d8b2e200197cf5f35ceb07ca2dade31f3a00ae8"
integrity sha512-eQ9DIktFJBhGjioABJRtUucoWR2mwllurfnM8LuNGAqX3ViZXaUchqk+1s7jjtkFiT9ySdACsFEA3etErkALUg==
"@csstools/media-query-list-parser@^2.1.13":
version "2.1.13"
resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.13.tgz#f00be93f6bede07c14ddf51a168ad2748e4fe9e5"
integrity sha512-XaHr+16KRU9Gf8XLi3q8kDlI18d5vzKSKCY510Vrtc9iNR0NJzbY9hhTmwhzYZj/ZwGL4VmB3TA9hJW0Um2qFA==
"@csstools/selector-specificity@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz#63085d2995ca0f0e55aa8b8a07d69bfd48b844fe"
integrity sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==
"@dual-bundle/import-meta-resolve@^4.1.0":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz#519c1549b0e147759e7825701ecffd25e5819f7b"
integrity sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==
"@esbuild/android-arm@0.15.18":
version "0.15.18"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz#266d40b8fdcf87962df8af05b76219bc786b4f80"
@ -2457,16 +2432,6 @@ ajv@^6.12.4:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^8.0.1:
version "8.17.1"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6"
integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==
dependencies:
fast-deep-equal "^3.1.3"
fast-uri "^3.0.1"
json-schema-traverse "^1.0.0"
require-from-string "^2.0.2"
ansi-escapes@^4.2.1, ansi-escapes@^4.3.1:
version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
@ -2755,11 +2720,6 @@ assign-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367"
integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@ -3411,11 +3371,6 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
balanced-match@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9"
integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@ -3822,11 +3777,6 @@ color-name@^1.1.4, color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colord@^2.9.3:
version "2.9.3"
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@ -3935,16 +3885,6 @@ core-js@^3.30.2:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9"
integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==
cosmiconfig@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d"
integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==
dependencies:
env-paths "^2.2.1"
import-fresh "^3.3.0"
js-yaml "^4.1.0"
parse-json "^5.2.0"
cross-env@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
@ -3972,19 +3912,6 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
css-functions-list@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.2.tgz#9a54c6dd8416ed25c1079cd88234e927526c1922"
integrity sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==
css-tree@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20"
integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==
dependencies:
mdn-data "2.0.30"
source-map-js "^1.0.1"
css@^2.1.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929"
@ -4370,11 +4297,6 @@ entities@^4.2.0, entities@^4.4.0, entities@^4.5.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
env-paths@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
@ -5110,16 +5032,6 @@ fast-levenshtein@^2.0.6:
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fast-uri@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134"
integrity sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==
fastest-levenshtein@^1.0.16:
version "1.0.16"
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5"
integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
fastq@^1.6.0:
version "1.17.1"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47"
@ -5141,13 +5053,6 @@ file-entry-cache@^6.0.1:
dependencies:
flat-cache "^3.0.4"
file-entry-cache@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-9.0.0.tgz#4478e7ceaa5191fa9676a2daa7030211c31b1e7e"
integrity sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==
dependencies:
flat-cache "^5.0.0"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
@ -5241,15 +5146,7 @@ flat-cache@^3.0.4:
keyv "^4.5.3"
rimraf "^3.0.2"
flat-cache@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-5.0.0.tgz#26c4da7b0f288b408bb2b506b2cb66c240ddf062"
integrity sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==
dependencies:
flatted "^3.3.1"
keyv "^4.5.4"
flatted@^3.2.9, flatted@^3.3.1:
flatted@^3.2.9:
version "3.3.1"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
@ -5441,22 +5338,6 @@ glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
once "^1.3.0"
path-is-absolute "^1.0.0"
global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
dependencies:
global-prefix "^3.0.0"
global-prefix@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97"
integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==
dependencies:
ini "^1.3.5"
kind-of "^6.0.2"
which "^1.3.1"
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
@ -5494,11 +5375,6 @@ globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"
globjoin@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
@ -5658,11 +5534,6 @@ html-tags@^2.0.0:
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-2.0.0.tgz#10b30a386085f43cede353cc8fa7cb0deeea668b"
integrity sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==
html-tags@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce"
integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==
htmlparser2@^8.0.0:
version "8.0.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
@ -5730,7 +5601,7 @@ ieee754@^1.1.13:
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore@^5.0.5, ignore@^5.1.1, ignore@^5.2.0, ignore@^5.3.1:
ignore@^5.0.5, ignore@^5.1.1, ignore@^5.2.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef"
integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==
@ -5740,7 +5611,7 @@ immutable@^4.0.0:
resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.7.tgz#c70145fc90d89fb02021e65c84eb0226e4e5a381"
integrity sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==
import-fresh@^3.2.1, import-fresh@^3.3.0:
import-fresh@^3.2.1:
version "3.3.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
@ -5774,7 +5645,7 @@ inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@^1.3.4, ini@^1.3.5:
ini@^1.3.4:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@ -5990,11 +5861,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
is-plain-object@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
is-potential-custom-element-name@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
@ -7182,11 +7048,6 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
json-schema-traverse@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
@ -7221,7 +7082,7 @@ jsonfile@^4.0.0:
optionalDependencies:
graceful-fs "^4.1.6"
keyv@^4.5.3, keyv@^4.5.4:
keyv@^4.5.3:
version "4.5.4"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
@ -7337,11 +7198,6 @@ lodash.merge@^4.6.2:
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lodash.truncate@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
lodash@^4.17.11, lodash@^4.17.15, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@ -7436,26 +7292,11 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
mathml-tag-names@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
mdn-data@2.0.30:
version "2.0.30"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc"
integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
media-typer@0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
meow@^13.2.0:
version "13.2.0"
resolved "https://registry.yarnpkg.com/meow/-/meow-13.2.0.tgz#6b7d63f913f984063b3cc261b6e8800c4cd3474f"
integrity sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@ -7495,7 +7336,7 @@ micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"
micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.7:
micromatch@^4.0.2, micromatch@^4.0.4:
version "4.0.7"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5"
integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==
@ -8139,11 +7980,6 @@ postcss-safe-parser@^6.0.0:
resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1"
integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
postcss-safe-parser@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz#6273d4e5149e286db5a45bc6cf6eafcad464014a"
integrity sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==
postcss-scss@^4.0.3, postcss-scss@^4.0.9:
version "4.0.9"
resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.9.tgz#a03c773cd4c9623cb04ce142a52afcec74806685"
@ -8520,11 +8356,6 @@ require-directory@^2.1.1:
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
require-from-string@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
require-main-filename@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
@ -8870,15 +8701,6 @@ slash@^4.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
slice-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==
dependencies:
ansi-styles "^4.0.0"
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@ -8909,7 +8731,7 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.0:
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2, source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
@ -9039,7 +8861,7 @@ string-length@^5.0.1:
char-regex "^2.0.0"
strip-ansi "^7.0.1"
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@ -9106,7 +8928,7 @@ strip-ansi@^3.0.0:
dependencies:
ansi-regex "^2.0.0"
strip-ansi@^7.0.1, strip-ansi@^7.1.0:
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
@ -9276,14 +9098,6 @@ supports-hyperlinks@^2.0.0:
has-flag "^4.0.0"
supports-color "^7.0.0"
supports-hyperlinks@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz#c711352a5c89070779b4dad54c05a2f14b15c94b"
integrity sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==
dependencies:
has-flag "^4.0.0"
supports-color "^7.0.0"
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"
@ -9317,17 +9131,6 @@ synckit@^0.9.1:
"@pkgr/core" "^0.1.0"
tslib "^2.6.2"
table@^6.8.2:
version "6.8.2"
resolved "https://registry.yarnpkg.com/table/-/table-6.8.2.tgz#c5504ccf201213fa227248bdc8c5569716ac6c58"
integrity sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==
dependencies:
ajv "^8.0.1"
lodash.truncate "^4.4.2"
slice-ansi "^4.0.0"
string-width "^4.2.3"
strip-ansi "^6.0.1"
terminal-link@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994"
@ -10024,7 +9827,7 @@ which-typed-array@^1.1.14, which-typed-array@^1.1.15:
gopd "^1.0.1"
has-tostringtag "^1.0.2"
which@^1.2.9, which@^1.3.1:
which@^1.2.9:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@ -10085,14 +9888,6 @@ write-file-atomic@^3.0.0:
signal-exit "^3.0.2"
typedarray-to-buffer "^3.1.5"
write-file-atomic@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7"
integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==
dependencies:
imurmurhash "^0.1.4"
signal-exit "^4.0.1"
ws@^7.4.6:
version "7.5.10"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9"