wip
This commit is contained in:
parent
4a0be19607
commit
7d3f46c529
13 changed files with 137 additions and 828 deletions
|
|
@ -57,7 +57,7 @@ const List = {
|
||||||
return new Set(this.finalItems.map(this.getKey))
|
return new Set(this.finalItems.map(this.getKey))
|
||||||
},
|
},
|
||||||
filteredSelected() {
|
filteredSelected() {
|
||||||
return [ ...this.allKeys.values().filter((key) => this.selected.has(key))]
|
return [...this.allKeys.values().filter((key) => this.selected.has(key))]
|
||||||
},
|
},
|
||||||
allSelected() {
|
allSelected() {
|
||||||
return this.selected.size === this.finalItems.length
|
return this.selected.size === this.finalItems.length
|
||||||
|
|
@ -70,7 +70,7 @@ const List = {
|
||||||
},
|
},
|
||||||
finalItems() {
|
finalItems() {
|
||||||
return this.externalItems || this.items
|
return this.externalItems || this.items
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
window.addEventListener('scroll', this.scrollLoad)
|
window.addEventListener('scroll', this.scrollLoad)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<basic-user-card :user="user">
|
<BasicUserCard :user="user">
|
||||||
<div class="mute-card-content-container">
|
<div class="mute-card-content-container">
|
||||||
<span
|
<span
|
||||||
v-if="muted && muteExpiryAvailable"
|
v-if="muted && muteExpiryAvailable"
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
:is-mute="true"
|
:is-mute="true"
|
||||||
/>
|
/>
|
||||||
</teleport>
|
</teleport>
|
||||||
</basic-user-card>
|
</BasicUserCard>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./mute_card.js"></script>
|
<script src="./mute_card.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -1,291 +1,49 @@
|
||||||
import Checkbox from 'src/components/checkbox/checkbox.vue'
|
import { defineAsyncComponent } from 'vue'
|
||||||
import GenericConfirm from 'src/components/confirm_modal/generic_confirm.vue'
|
|
||||||
import TextConfirm from 'src/components/confirm_modal/text_confirm.vue'
|
import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
|
||||||
import Modal from 'src/components/modal/modal.vue'
|
|
||||||
import List from 'src/components/list/list.vue'
|
import { useAdminUsersStore } from 'src/stores/adminUsers.js'
|
||||||
import Popover from 'src/components/popover/popover.vue'
|
|
||||||
import Select from 'src/components/select/select.vue'
|
|
||||||
import AdminStatusCard from 'src/components/settings_modal/admin_tabs/admin_status_card.vue'
|
|
||||||
import BasicUserCard from '../../basic_user_card/basic_user_card.vue'
|
|
||||||
|
|
||||||
const AdminCard = {
|
const AdminCard = {
|
||||||
props: {
|
props: {
|
||||||
/**
|
userId: {
|
||||||
* minimal user info
|
type: String
|
||||||
* @type {import('vue').PropType<{
|
|
||||||
* id: string,
|
|
||||||
* _original: {
|
|
||||||
* is_approved: boolean;
|
|
||||||
* is_confirmed: boolean;
|
|
||||||
* };
|
|
||||||
* }>}
|
|
||||||
*/
|
|
||||||
userDetails: {
|
|
||||||
type: Object,
|
|
||||||
required: true,
|
|
||||||
/**
|
|
||||||
* @param {any} u
|
|
||||||
* @returns {u is { id: string; _original: { is_approved; is_confirmed: boolean; } } }
|
|
||||||
*/
|
|
||||||
validator(u) {
|
|
||||||
return (
|
|
||||||
typeof u.id === 'string' &&
|
|
||||||
typeof u._original === 'object' &&
|
|
||||||
typeof u._original.is_approved === 'boolean' &&
|
|
||||||
typeof u._original.is_confirmed === 'boolean'
|
|
||||||
)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
progress: false,
|
|
||||||
detailsExpanded: false,
|
|
||||||
topLevelExpanded: false, // REMOVE
|
|
||||||
jsonExpanded: false,
|
|
||||||
timelineExpanded: false,
|
|
||||||
justApproved: false,
|
|
||||||
justConfirmed: false,
|
|
||||||
justDeleted: false,
|
|
||||||
showDirect: false,
|
|
||||||
showReblogs: false,
|
|
||||||
timelineSorting: 'des',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
/**
|
|
||||||
* checks if the user is defined
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
isLoaded() {
|
|
||||||
return typeof this.user !== 'undefined'
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {object} user info
|
|
||||||
*/
|
|
||||||
user() {
|
|
||||||
return this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {object} user relationship
|
|
||||||
*/
|
|
||||||
relationship() {
|
|
||||||
return this.$store.getters.relationship(this.userDetails.id)
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {boolean} is user local
|
|
||||||
*/
|
|
||||||
isLocal() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
if (typeof u !== 'undefined') {
|
|
||||||
return u.is_local === true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {boolean} is user admin
|
|
||||||
*/
|
|
||||||
isAdmin() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
if (typeof u !== 'undefined') {
|
|
||||||
return u.rights.admin === true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {boolean} is user moderator
|
|
||||||
*/
|
|
||||||
isModerator() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
if (typeof u !== 'undefined') {
|
|
||||||
return u.rights.moderator === true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {boolean} is user active
|
|
||||||
*/
|
|
||||||
isActivated() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
if (typeof u !== 'undefined') {
|
|
||||||
return u.deactivated === false
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {boolean} has this user been confirmed
|
|
||||||
*/
|
|
||||||
isConfirmed() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
return u._original.is_confirmed === true || this.justConfirmed === true
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @returns {boolean} has this user been approved
|
|
||||||
*/
|
|
||||||
isApproved() {
|
|
||||||
return (
|
|
||||||
this.userDetails._original.is_approved === true ||
|
|
||||||
this.justApproved === true
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
BasicUserCard,
|
BasicUserCard,
|
||||||
Checkbox,
|
ModerationTools: defineAsyncComponent(
|
||||||
List,
|
() => import('src/components/moderation_tools/moderation_tools.vue'),
|
||||||
AdminStatusCard,
|
),
|
||||||
Modal,
|
|
||||||
Popover,
|
|
||||||
GenericConfirm,
|
|
||||||
Select,
|
|
||||||
TextConfirm,
|
|
||||||
},
|
},
|
||||||
methods: {
|
computed: {
|
||||||
/**
|
user() {
|
||||||
* @param {boolean} v set admin status
|
return this.$store.getters.findUser(this.userId)
|
||||||
*/
|
|
||||||
setAdmin(v) {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
if (v === true) {
|
|
||||||
this.$store.dispatch('adminAddUserToAdminGroup', u)
|
|
||||||
} else {
|
|
||||||
this.$store.dispatch('adminRemoveUserFromAdminGroup', u)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/**
|
userAdminData() {
|
||||||
* @param {boolean} v set moderator status
|
return useAdminUsersStore().getUser(this.userId)
|
||||||
*/
|
|
||||||
setModerator(v) {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
if (v === true) {
|
|
||||||
this.$store.dispatch('adminAddUserToModeratorGroup', u)
|
|
||||||
} else {
|
|
||||||
this.$store.dispatch('adminRemoveUserFromModeratorGroup', u)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/**
|
relationship() {
|
||||||
* @param {boolean} v set activation status
|
return this.$store.getters.relationship(this.userId)
|
||||||
*/
|
|
||||||
setActivation(v) {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
if (v === true) {
|
|
||||||
this.$store.dispatch('adminActivateUser', u)
|
|
||||||
} else {
|
|
||||||
this.$store.dispatch('adminDeactivateUser', u)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
/**
|
isLocal() {
|
||||||
* confirm this user
|
return this.user.is_local
|
||||||
*/
|
|
||||||
confirmUser() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
this.$store.dispatch('adminConfirmUser', u)
|
|
||||||
this.just_confirmed = true
|
|
||||||
},
|
},
|
||||||
/**
|
isAdmin() {
|
||||||
* try resending the confirmation email
|
return this.user.rights.admin
|
||||||
*/
|
|
||||||
resendConfirmationEmail() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
this.$store.dispatch('adminResendConfirmationEmail', u)
|
|
||||||
},
|
},
|
||||||
/**
|
isModerator() {
|
||||||
* approve this user
|
return this.user.rights.moderator
|
||||||
*/
|
|
||||||
approveUser() {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
this.$store.dispatch('adminApproveUser', u)
|
|
||||||
},
|
},
|
||||||
/**
|
isActivated() {
|
||||||
* update user info from server
|
return !this.user.deactivated
|
||||||
*/
|
|
||||||
forceUpdateUser() {
|
|
||||||
this.$store.dispatch('fetchUser', this.userDetails.id)
|
|
||||||
},
|
},
|
||||||
/**
|
isApproved() {
|
||||||
* delete selected statuses
|
return this.userAdminData.is_approved
|
||||||
*/
|
|
||||||
deleteSelection() {
|
|
||||||
const l = this.$refs.timelineList
|
|
||||||
const s = l.getSelected()
|
|
||||||
s.forEach((p) => this.$store.dispatch('deleteStatus', p))
|
|
||||||
l.reset()
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* delete this user. keep in mind that user deletion is not intuitive in pleroma backend.
|
|
||||||
* it actually deletes all content of a user. the user itself will keep showing up in search results.
|
|
||||||
*/
|
|
||||||
deleteUser() {
|
|
||||||
if (!this.justDeleted) {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
this.$store.dispatch('adminDeleteUser', u)
|
|
||||||
this.justDeleted = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @param {string} text name of tag to be added to user
|
|
||||||
*/
|
|
||||||
addUserTag(text) {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
this.$store
|
|
||||||
.dispatch('adminTagUser', { user: u, tag: text })
|
|
||||||
.then(() => this.$store.dispatch('fetchUser', this.userDetails.id))
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @param {string} text name of tag to be removed from user
|
|
||||||
*/
|
|
||||||
removeUserTag(text) {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
this.$store
|
|
||||||
.dispatch('adminUntagUser', { user: u, tag: text })
|
|
||||||
.then(() => this.$store.dispatch('fetchUser', this.userDetails.id))
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* @param {object} store
|
|
||||||
* @param {object} opts
|
|
||||||
* @returns {Promise<Array<object>>} statuses
|
|
||||||
*/
|
|
||||||
async fetchStatuses(store, opts) {
|
|
||||||
const u = this.$store.getters.findUser(this.userDetails.id)
|
|
||||||
const res = store.dispatch('adminListStatuses', {
|
|
||||||
user: u,
|
|
||||||
opts: {
|
|
||||||
pageSize: opts.pageSize,
|
|
||||||
godmode: this.showDirect,
|
|
||||||
withReblogs: this.showReblogs,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
return res.then((r) => {
|
|
||||||
const a = r.activities
|
|
||||||
console.log(this.timelineSorting)
|
|
||||||
if (this.timelineSorting === 'des') {
|
|
||||||
return [...a].sort(
|
|
||||||
(a, b) => new Date(b.created_at) - new Date(a.created_at),
|
|
||||||
)
|
|
||||||
} else if (this.timelineSorting === 'asc') {
|
|
||||||
return [...a].sort(
|
|
||||||
(a, b) => new Date(a.created_at) - new Date(b.created_at),
|
|
||||||
)
|
|
||||||
} else return []
|
|
||||||
})
|
|
||||||
},
|
|
||||||
confirmAction(box) {
|
|
||||||
this.$refs[box].show()
|
|
||||||
this.$refs.dropdownuser.hidePopover()
|
|
||||||
},
|
|
||||||
userActionConfirmed(action) {
|
|
||||||
this.$store.dispatch(
|
|
||||||
action,
|
|
||||||
this.$store.getters.findUser(this.userDetails.id),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
statusActionConfirmed(action, opts) {
|
|
||||||
const s = this.$refs.statusList.getSelected()
|
|
||||||
s.forEach((p) => {
|
|
||||||
this.$store.dispatch(action, { id: p.id, ...(opts || {}) })
|
|
||||||
})
|
|
||||||
this.reset()
|
|
||||||
},
|
},
|
||||||
|
isConfirmed() {
|
||||||
|
return this.userAdminData.is_confirmed
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,9 @@
|
||||||
.inline-layout {
|
.AdminCard {
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert {
|
.right-side {
|
||||||
text-shadow: none;
|
align-items: baseline;
|
||||||
}
|
justify-content: end;
|
||||||
|
display: flex;
|
||||||
.user-role {
|
}
|
||||||
display: inline-block;
|
|
||||||
vertical-align: baseline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modalfix::before {
|
|
||||||
opacity: 1.0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,528 +1,56 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="!isLoaded">
|
<template v-if="!user">
|
||||||
<FAIcon
|
<FAIcon
|
||||||
icon="circle-notch"
|
icon="circle-notch"
|
||||||
spin
|
spin
|
||||||
size="lg"
|
size="lg"
|
||||||
/>
|
/>
|
||||||
</div>
|
</template>
|
||||||
<div v-else>
|
<template v-else>
|
||||||
<div class="inline-layout">
|
<BasicUserCard
|
||||||
<BasicUserCard :user="user" />
|
class="AdminCard"
|
||||||
<label
|
:user="user"
|
||||||
v-if="isAdmin"
|
|
||||||
class="alert neutral user-role"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.indicator.admin') }}
|
|
||||||
</label>
|
|
||||||
<label
|
|
||||||
v-if="isModerator"
|
|
||||||
class="alert neutral user-role"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.indicator.moderator') }}
|
|
||||||
</label>
|
|
||||||
<label
|
|
||||||
v-if="isActivated"
|
|
||||||
class="alert info user-role"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.indicator.active') }}
|
|
||||||
</label>
|
|
||||||
<label
|
|
||||||
v-if="!isActivated"
|
|
||||||
class="alert error user-role"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.indicator.deactivated') }}
|
|
||||||
</label>
|
|
||||||
<label
|
|
||||||
v-if="isConfirmed"
|
|
||||||
class="alert neutral user-role"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.indicator.confirmed') }}
|
|
||||||
</label>
|
|
||||||
<button
|
|
||||||
class="button button-default btn"
|
|
||||||
type="button"
|
|
||||||
@click="detailsExpanded = true"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.details.button') }}
|
|
||||||
</button>
|
|
||||||
<Popover
|
|
||||||
ref="dropdownuser"
|
|
||||||
trigger="click"
|
|
||||||
placement="top"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<button
|
|
||||||
class="button button-default btn"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.title') }}
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
<template #content>
|
|
||||||
<div
|
|
||||||
v-if="!isActivated"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmActivate')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.activate') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="isActivated"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmDeactivate')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.deactivate') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmDeleteUser')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.delete_user') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="!isAdmin"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmGrantAdmin')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.grant_admin') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="isAdmin"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmRevokeAdmin')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.revoke_admin') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="!isModerator"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmGrantModerator')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.grant_moderator') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="isModerator"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmRevokeModerator')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.revoke_moderator') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="isApproved"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmApprove')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.approve') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="isConfirmed"
|
|
||||||
class="dropdown-menu"
|
|
||||||
>
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmConfirm')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.confirm') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmResendConfirmationEmail')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.resend_confirmation_email') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmRequirePasswordChange')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.require_password_change') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmDisableMFA')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.disable_mfa') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-if="detailsExpanded"
|
|
||||||
>
|
>
|
||||||
<Modal
|
<div class="right-side">
|
||||||
class="settings-modal"
|
<label
|
||||||
:no-background="false"
|
v-if="isAdmin"
|
||||||
@backdrop-clicked="() => { detailsExpanded = false }"
|
class="alert neutral user-role"
|
||||||
>
|
>
|
||||||
<div class="settings-modal-panel panel">
|
{{ $t('admin_dash.users.indicator.admin') }}
|
||||||
<div class="panel-heading">
|
</label>
|
||||||
<h1 class="title">
|
<label
|
||||||
{{ $t('admin_dash.users.details.title') }}
|
v-if="isModerator"
|
||||||
</h1>
|
class="alert neutral user-role"
|
||||||
<button
|
>
|
||||||
class="btn button-default"
|
{{ $t('admin_dash.users.indicator.moderator') }}
|
||||||
:title="$t('general.close')"
|
</label>
|
||||||
@click="() => { detailsExpanded = false }"
|
<label
|
||||||
>
|
v-if="isActivated"
|
||||||
<FAIcon
|
class="alert info user-role"
|
||||||
icon="times"
|
>
|
||||||
fixed-width
|
{{ $t('admin_dash.users.indicator.active') }}
|
||||||
/>
|
</label>
|
||||||
</button>
|
<label
|
||||||
</div>
|
v-if="!isActivated"
|
||||||
<div
|
class="alert error user-role"
|
||||||
class="panel-body"
|
>
|
||||||
style="overflow-y: auto;"
|
{{ $t('admin_dash.users.indicator.deactivated') }}
|
||||||
>
|
</label>
|
||||||
<h2 class="title">
|
<label
|
||||||
{{ $t('admin_dash.users.details.overview') }}
|
v-if="isConfirmed"
|
||||||
</h2>
|
class="alert neutral user-role"
|
||||||
<ul
|
>
|
||||||
class="setting-list"
|
{{ $t('admin_dash.users.indicator.confirmed') }}
|
||||||
style="columns: 2;"
|
</label>
|
||||||
>
|
<ModerationTools
|
||||||
<li>
|
class="moderation-menu"
|
||||||
{{ $t('admin_dash.users.details.id') }}
|
:user="user"
|
||||||
</li>
|
/>
|
||||||
<li>
|
</div>
|
||||||
{{ $t('admin_dash.users.details.actor_type') }}
|
</BasicUserCard>
|
||||||
</li>
|
</template>
|
||||||
<li>
|
|
||||||
{{ $t('admin_dash.users.details.roles') }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ $t('admin_dash.users.details.account_type') }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ $t('admin_dash.users.details.status') }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ user.id }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
{{ $t('admin_dash.users.details.actor_types.' + user.actor_type.toLowerCase()) }}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span v-if="user.rights.admin === true"> {{ $t('admin_dash.users.details.admin') }} </span>
|
|
||||||
<span v-if="user.rights.admin === true && user.rights.moderator === true"> , </span>
|
|
||||||
<span v-if="user.rights.moderator === true"> {{ $t('admin_dash.users.details.moderator') }} </span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span v-if="user.is_local"> {{ $t('admin_dash.users.details.local') }} </span>
|
|
||||||
<span v-else> {{ $t('admin_dash.users.details.remote') }} </span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span v-if="user.deactivated === false"> {{ $t('admin_dash.users.details.active') }} </span>
|
|
||||||
<span v-else> {{ $t('admin_dash.users.details.inactive') }} </span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<h2 class="title">
|
|
||||||
{{ $t('admin_dash.users.details.tags') }}
|
|
||||||
</h2>
|
|
||||||
<ul class="setting-list">
|
|
||||||
<li
|
|
||||||
v-for="tag in user.tags"
|
|
||||||
:key="tag"
|
|
||||||
>
|
|
||||||
{{ tag }}
|
|
||||||
<button
|
|
||||||
class="button button-default btn"
|
|
||||||
@click="removeUserTag(tag)"
|
|
||||||
>
|
|
||||||
<FAIcon
|
|
||||||
icon="minus"
|
|
||||||
size="lg"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<button
|
|
||||||
class="button button-default btn"
|
|
||||||
@click="$refs.addTextBox.show()"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.tags.add_new') }}
|
|
||||||
<FAIcon
|
|
||||||
icon="plus"
|
|
||||||
size="lg"
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
<PageList
|
|
||||||
ref="timelineList"
|
|
||||||
:refresh="true"
|
|
||||||
:get-key="i => i"
|
|
||||||
:box-only="true"
|
|
||||||
:page-size="20"
|
|
||||||
:single-page="true"
|
|
||||||
:fetch-page="(store, opts) => fetchStatuses(store, opts)"
|
|
||||||
>
|
|
||||||
<template #header>
|
|
||||||
<Checkbox
|
|
||||||
v-model="showDirect"
|
|
||||||
@update:model-value="() => $refs.timelineList.reset()"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.filters.show_direct') }}
|
|
||||||
</Checkbox>
|
|
||||||
<Checkbox
|
|
||||||
v-model="showReblogs"
|
|
||||||
@update:model-value="() => $refs.timelineList.reset()"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.filters.show_reblogs') }}
|
|
||||||
</Checkbox>
|
|
||||||
<Select
|
|
||||||
v-model="timelineSorting"
|
|
||||||
@update:model-value="() => $refs.timelineList.reset()"
|
|
||||||
>
|
|
||||||
<option value="asc">
|
|
||||||
{{ $t('admin_dash.users.filters.ascending') }}
|
|
||||||
</option>
|
|
||||||
<option value="des">
|
|
||||||
{{ $t('admin_dash.users.filters.descending') }}
|
|
||||||
</option>
|
|
||||||
</Select>
|
|
||||||
<Popover
|
|
||||||
ref="dropdownstatus"
|
|
||||||
trigger="click"
|
|
||||||
placement="top"
|
|
||||||
>
|
|
||||||
<template #trigger>
|
|
||||||
<button
|
|
||||||
class="button button-default btn"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.actions.title') }}
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
<p> wrap </p>
|
|
||||||
<template #content>
|
|
||||||
<div class="dropdown-menu">
|
|
||||||
<div class="menu-item dropdown-item">
|
|
||||||
<button
|
|
||||||
class="main-button"
|
|
||||||
@click="confirmAction('confirmDeleteStatus')"
|
|
||||||
>
|
|
||||||
{{ $t('admin_dash.users.delete_status') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<p> set sensitive </p>
|
|
||||||
<p> unset sensitive </p>
|
|
||||||
<p> make public </p>
|
|
||||||
<p> make unlisted </p>
|
|
||||||
<p> make private </p>
|
|
||||||
<p> make direct </p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</Popover>
|
|
||||||
</template>
|
|
||||||
<template #item="{item}">
|
|
||||||
<AdminStatusCard
|
|
||||||
:status-details="item"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #empty>
|
|
||||||
<p> {{ $t('admin_dash.users.user_has_no_posts') }} </p>
|
|
||||||
</template>
|
|
||||||
<template #load>
|
|
||||||
<FAIcon
|
|
||||||
icon="circle-notch"
|
|
||||||
spin
|
|
||||||
size="lg"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</PageList>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Modal>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmActivate"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.activate')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminActivateUser')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmDeactivate"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.deactivate')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminDeactivateUser')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmDeleteUser"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.delete_user')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminDeleteUser')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmGrantAdmin"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.grant_admin')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminAddUserToAdminGroup')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmRevokeAdmin"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.revoke_admin')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminRemoveUserFromAdminGroup')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmGrantModerator"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.grant_moderator')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminAddUserToModeratorGroup')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmRevokeModerator"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.revoke_moderator')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminRemoveUserFromModeratorGroup')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmApprove"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.approve')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminApproveUser')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmConfirm"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.confirm')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminConfirmUser')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmResendConfirmationEmail"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.resend_confirmation_email')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminResendConfirmationEmail')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmRequirePasswordChange"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.require_password_change')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminRequirePasswordChange')"
|
|
||||||
/>
|
|
||||||
<GenericConfirm
|
|
||||||
ref="confirmDisableMFA"
|
|
||||||
style="z-index: 10000;"
|
|
||||||
:title="$t('admin_dash.users.actions.confirm_single.title')"
|
|
||||||
:message="$t('admin_dash.users.actions.confirm_single.disable_mfa')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="userActionConfirmed('adminDisableMFA')"
|
|
||||||
/>
|
|
||||||
<TextConfirm
|
|
||||||
ref="addTextBox"
|
|
||||||
style="z-index: 10001;"
|
|
||||||
:title="$t('admin_dash.users.tags.add_new')"
|
|
||||||
:message="$t('admin_dash.users.tags.new_title')"
|
|
||||||
:cancel-text="$t('admin_dash.users.actions.no')"
|
|
||||||
:confirm-text="$t('admin_dash.users.actions.yes')"
|
|
||||||
@action="addUserTag"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script src="./admin_card.js"></script>
|
<script src="./admin_card.js"></script>
|
||||||
<style lang="scss" src="./admin_card.scss"></style>
|
|
||||||
<style lang="scss" src="../settings_modal.scss"></style>
|
|
||||||
<!--<style lang="scss">
|
|
||||||
.admin-card-content-container {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
button {
|
<style lang="scss" src="./admin_card.scss"></style>
|
||||||
width: 10em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>-->
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ import Select from 'src/components/select/select.vue'
|
||||||
import AdminCard from 'src/components/settings_modal/admin_tabs/admin_card.vue'
|
import AdminCard from 'src/components/settings_modal/admin_tabs/admin_card.vue'
|
||||||
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
|
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
|
||||||
|
|
||||||
|
import { useAdminUsersStore } from 'src/stores/adminUsers.js'
|
||||||
|
|
||||||
const UsersTab = {
|
const UsersTab = {
|
||||||
provide() {
|
provide() {
|
||||||
return {
|
return {
|
||||||
|
|
@ -113,9 +115,7 @@ const UsersTab = {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchUsers(page) {
|
fetchUsers(page) {
|
||||||
console.log(page)
|
return useAdminUsersStore().fetchAdminUsers({
|
||||||
return this.$store
|
|
||||||
.dispatch('fetchAdminUsers', {
|
|
||||||
...this.fetchOptions,
|
...this.fetchOptions,
|
||||||
page,
|
page,
|
||||||
})
|
})
|
||||||
|
|
@ -148,10 +148,10 @@ const UsersTab = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
fetchOptions () {
|
fetchOptions() {
|
||||||
this.$refs.usersList.reset()
|
this.$refs.usersList.reset()
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default UsersTab
|
export default UsersTab
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,11 @@
|
||||||
</Popover>
|
</Popover>
|
||||||
</template>
|
</template>
|
||||||
<template #item="{item}">
|
<template #item="{item}">
|
||||||
<AdminCard :user-details="item" />
|
<AdminCard
|
||||||
|
:user-id="item.id"
|
||||||
|
:confirmed="item.is_confirmed"
|
||||||
|
:suggested="item.is_suggested"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #load>
|
<template #load>
|
||||||
<span> loading </span>
|
<span> loading </span>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { get, map, reject, isEmpty } from 'lodash'
|
import { get, isEmpty, map, reject } from 'lodash'
|
||||||
|
|
||||||
import Autosuggest from 'src/components/autosuggest/autosuggest.vue'
|
import Autosuggest from 'src/components/autosuggest/autosuggest.vue'
|
||||||
import BlockCard from 'src/components/block_card/block_card.vue'
|
import BlockCard from 'src/components/block_card/block_card.vue'
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@
|
||||||
width: 10em;
|
width: 10em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocks, .mutes {
|
.blocks,
|
||||||
|
.mutes {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
|
|
||||||
|
|
@ -103,10 +103,10 @@ const UserProfile = {
|
||||||
this.footerRef = el
|
this.footerRef = el
|
||||||
},
|
},
|
||||||
fetchUsers(group) {
|
fetchUsers(group) {
|
||||||
return () => this
|
return () =>
|
||||||
.$store
|
this.$store
|
||||||
.dispatch('fetch' + group, this.userId)
|
.dispatch('fetch' + group, this.userId)
|
||||||
.then((result) => ({ items: result }))
|
.then((result) => ({ items: result }))
|
||||||
},
|
},
|
||||||
load(userNameOrId) {
|
load(userNameOrId) {
|
||||||
const startFetchingTimeline = (timeline, userId) => {
|
const startFetchingTimeline = (timeline, userId) => {
|
||||||
|
|
|
||||||
|
|
@ -151,9 +151,9 @@ const adminSettingsStorage = {
|
||||||
adminApproveUser(store, user) {
|
adminApproveUser(store, user) {
|
||||||
return store.rootState.api.backendInteractor.adminApproveUser({ user })
|
return store.rootState.api.backendInteractor.adminApproveUser({ user })
|
||||||
},
|
},
|
||||||
adminListStatuses(store, { user, opts }) {
|
adminListStatuses(store, { userId, opts }) {
|
||||||
return store.rootState.api.backendInteractor.adminListStatuses({
|
return store.rootState.api.backendInteractor.adminListStatuses({
|
||||||
user,
|
userId,
|
||||||
opts,
|
opts,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1740,17 +1740,19 @@ const adminApproveUser = ({ user: { screen_name: nickname }, credentials }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const adminListStatuses = ({
|
const adminListStatuses = ({
|
||||||
user: { id },
|
userId,
|
||||||
opts: { pageSize, godmode, withReblogs },
|
pageSize = 20,
|
||||||
|
godmode,
|
||||||
|
withReblogs,
|
||||||
credentials,
|
credentials,
|
||||||
}) => {
|
}) => {
|
||||||
const url = PLEROMA_ADMIN_LIST_STATUSES_URL(
|
const url = PLEROMA_ADMIN_LIST_STATUSES_URL(
|
||||||
id,
|
userId,
|
||||||
pageSize,
|
pageSize,
|
||||||
godmode,
|
godmode,
|
||||||
withReblogs,
|
withReblogs,
|
||||||
)
|
)
|
||||||
return promisedRequest({ url: url, credentials, method: 'GET' })
|
return promisedRequest({ url, credentials, method: 'GET' })
|
||||||
}
|
}
|
||||||
|
|
||||||
const adminChangeStatusScope = ({
|
const adminChangeStatusScope = ({
|
||||||
|
|
|
||||||
26
src/stores/adminUsers.js
Normal file
26
src/stores/adminUsers.js
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
|
export const useAdminUsersStore = defineStore('adminUsers', {
|
||||||
|
state: () => ({
|
||||||
|
users: new Map()
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getUser(state) {
|
||||||
|
return (id) => state.users.get(id)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
async fetchAdminUsers(opts) {
|
||||||
|
const data = await window.vuex.state.api.backendInteractor.adminListUsers({
|
||||||
|
opts,
|
||||||
|
})
|
||||||
|
|
||||||
|
data.users.forEach((user) => {
|
||||||
|
window.vuex.dispatch('fetchUserIfMissing', user.id),
|
||||||
|
this.users.set(user.id, user)
|
||||||
|
})
|
||||||
|
|
||||||
|
return data
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
Loading…
Add table
Add a link
Reference in a new issue