some initial cleanup

This commit is contained in:
Henry Jameson 2026-06-08 02:13:07 +03:00
commit 4da16acc27
6 changed files with 324 additions and 248 deletions

View file

@ -83,6 +83,13 @@
--__horizontal-gap: 0.75em;
--__vertical-gap: 0.5em;
display: flex;
flex-direction: column;
.list {
flex: 1 1 0;
}
&-item-inner {
display: flex;
align-items: center;

View file

@ -1,16 +1,30 @@
.user-tab {
height: 100%;
}
.UsersTab {
max-height: 100%;
display: grid;
flex-direction: column;
overflow-y: hidden;
.query-label {
padding-right: 10px;
padding-left: 10px;
}
.filters-section {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0.5em 1em;
.filter-input {
width: 200px;
}
> div {
flex: 0 1 auto;
}
.filter-btn-box {
text-align: right;
.filter {
display: block;
margin-bottom: 0.5em;
min-width: 14em;
.query-label {
margin-bottom: 0.5em;
}
> input {
width: 100%;
}
}
}
}

View file

@ -1,249 +1,270 @@
<template>
<div :label="$t('admin_dash.users.management')">
<div
class="setting-item"
>
<h2> {{ $t('admin_dash.users.title') }} </h2>
<ul class="setting-list">
<li>
<label class="query-label"> {{ $t('admin_dash.users.labels.query') }} </label>
<input
v-model="filtersQuery"
class="input string-input filter-input"
@input="reset()"
<div
class="UsersTab"
:label="$t('admin_dash.users.management')"
>
<h3>
{{ $t('admin_dash.users.title') }}
</h3>
<div class="filters-section">
<label class="filter">
<div class="query-label">
{{ $t('admin_dash.users.labels.query') }}
</div>
<input
v-model="filtersQuery"
class="input string-input filter-input"
@input="reset()"
>
</label>
<label class="filter">
<div class="query-label">
{{ $t('admin_dash.users.labels.name') }}
</div>
<input
v-model="filtersName"
class="input string-input filter-input"
@input="reset()"
>
</label>
<label class="filter">
<div class="query-label">
{{ $t('admin_dash.users.labels.email') }}
</div>
<input
v-model="filtersEmail"
class="input string-input filter-input"
@input="reset()"
>
</label>
<div class="filter">
<div class="query-label">
{{ $t('admin_dash.users.labels.origin') }}
</div>
<Select
v-model="filtersOrigin"
@update:model-value="reset"
>
<option
value="all"
>
<label class="query-label"> {{ $t('admin_dash.users.labels.name') }} </label>
<input
v-model="filtersName"
class="input string-input filter-input"
@input="reset()"
{{ $t('admin_dash.users.options.all') }}
</option>
<option
value="local"
>
<label class="query-label"> {{ $t('admin_dash.users.labels.email') }} </label>
<input
v-model="filtersEmail"
class="input string-input filter-input"
@input="reset()"
{{ $t('admin_dash.users.options.only_local') }}
</option>
<option
value="external"
>
</li>
<li>
<label class="query-label"> {{ $t('admin_dash.users.labels.origin') }} </label>
<Select
v-model="filtersOrigin"
@update:model-value="reset"
{{ $t('admin_dash.users.options.only_external') }}
</option>
</Select>
</div>
<div class="filter">
<div class="query-label">
{{ $t('admin_dash.users.labels.activity') }}
</div>
<Select
v-model="filtersActivity"
@update:model-value="reset"
>
<option
value="all"
>
<option
value="all"
>
{{ $t('admin_dash.users.options.all') }}
</option>
<option
value="local"
>
{{ $t('admin_dash.users.options.only_local') }}
</option>
<option
value="external"
>
{{ $t('admin_dash.users.options.only_external') }}
</option>
</Select>
<label class="query-label"> {{ $t('admin_dash.users.labels.activity') }} </label>
<Select
v-model="filtersActivity"
@update:model-value="reset"
{{ $t('admin_dash.users.options.all') }}
</option>
<option
value="active"
>
<option
value="all"
>
{{ $t('admin_dash.users.options.all') }}
</option>
<option
value="active"
>
{{ $t('admin_dash.users.options.only_active') }}
</option>
<option
value="deactivated"
>
{{ $t('admin_dash.users.options.only_deactivated') }}
</option>
</Select>
<label class="query-label"> {{ $t('admin_dash.users.labels.privileges') }} </label>
<Select
v-model="filtersPrivileges"
@update:model-value="reset"
{{ $t('admin_dash.users.options.only_active') }}
</option>
<option
value="deactivated"
>
<option
value="all"
>
{{ $t('admin_dash.users.options.all') }}
</option>
<option
value="admin"
>
{{ $t('admin_dash.users.options.only_admins') }}
</option>
<option
value="modsnadmins"
>
{{ $t('admin_dash.users.options.only_privileged') }}
</option>
<option
value="moderator"
>
{{ $t('admin_dash.users.options.only_moderators') }}
</option>
</Select>
</li>
<li>
<Checkbox
class="query-label"
@update:model-value="v => {filtersNeedApproval = v; reset();}"
{{ $t('admin_dash.users.options.only_deactivated') }}
</option>
</Select>
</div>
<div class="filter">
<div class="query-label">
{{ $t('admin_dash.users.labels.privileges') }}
</div>
<Select
v-model="filtersPrivileges"
@update:model-value="reset"
>
<option
value="all"
>
{{ $t('admin_dash.users.options.only_unapproved') }}
</Checkbox>
<Checkbox
class="query-label"
@update:model-value="v => {filtersUncomfirmed = v; reset();}"
{{ $t('admin_dash.users.options.all') }}
</option>
<option
value="admin"
>
{{ $t('admin_dash.users.options.only_unconfirmed') }}
</Checkbox>
</li>
</ul>
<PageList
ref="userList"
:refresh="true"
:get-key="i => i"
:box-only="true"
:page-size="20"
:fetch-page="(store, opts) => fetchPage(store, opts)"
>
<template #header>
<Popover
ref="dropdown"
trigger="click"
placement="bottom"
{{ $t('admin_dash.users.options.only_admins') }}
</option>
<option
value="modsnadmins"
>
<template #trigger>
<button
class="button button-default btn"
>
{{ $t('admin_dash.users.actions.title') }}
</button>
</template>
<template #content>
<div class="dropdown-menu">
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmActivate')"
>
{{ $t('admin_dash.users.actions.activate') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmDeactivate')"
>
{{ $t('admin_dash.users.actions.deactivate') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmDelete')"
>
{{ $t('admin_dash.users.actions.delete_user') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmGrantAdmin')"
>
{{ $t('admin_dash.users.actions.grant_admin') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmRevokeAdmin')"
>
{{ $t('admin_dash.users.actions.revoke_admin') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmGrantModerator')"
>
{{ $t('admin_dash.users.actions.grant_moderator') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmRevokeModerator')"
>
{{ $t('admin_dash.users.actions.revoke_moderator') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmApprove')"
>
{{ $t('admin_dash.users.actions.approve') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmConfirm')"
>
{{ $t('admin_dash.users.actions.confirm') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmResendEmail')"
>
{{ $t('admin_dash.users.actions.resend_confirmation_email') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmRequirePasswordChange')"
>
{{ $t('admin_dash.users.actions.require_password_change') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmDisableMFA')"
>
{{ $t('admin_dash.users.actions.disable_mfa') }}
</button>
</div>
</div>
</template>
</Popover>
</template>
<template #item="{item}">
<AdminCard :user-details="item" />
</template>
<template #load>
<span> loading </span>
</template>
<template #empty>
<span> no users </span>
</template>
</PageList>
{{ $t('admin_dash.users.options.only_privileged') }}
</option>
<option
value="moderator"
>
{{ $t('admin_dash.users.options.only_moderators') }}
</option>
</Select>
</div>
<div class="filter">
<Checkbox
@update:model-value="v => {filtersNeedApproval = v; reset();}"
>
{{ $t('admin_dash.users.options.only_unapproved') }}
</Checkbox>
</div>
<div class="filter">
<Checkbox
@update:model-value="v => {filtersUncomfirmed = v; reset();}"
>
{{ $t('admin_dash.users.options.only_unconfirmed') }}
</Checkbox>
</div>
</div>
<PageList
ref="userList"
:refresh="true"
:get-key="i => i"
:box-only="true"
:page-size="20"
:fetch-page="(store, opts) => fetchPage(store, opts)"
>
<template #header>
<Popover
ref="dropdown"
trigger="click"
placement="bottom"
>
<template #trigger>
<button
class="button button-default btn"
>
{{ $t('admin_dash.users.actions.title') }}
</button>
</template>
<template #content>
<div class="dropdown-menu">
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmActivate')"
>
{{ $t('admin_dash.users.actions.activate') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmDeactivate')"
>
{{ $t('admin_dash.users.actions.deactivate') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmDelete')"
>
{{ $t('admin_dash.users.actions.delete_user') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmGrantAdmin')"
>
{{ $t('admin_dash.users.actions.grant_admin') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmRevokeAdmin')"
>
{{ $t('admin_dash.users.actions.revoke_admin') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmGrantModerator')"
>
{{ $t('admin_dash.users.actions.grant_moderator') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmRevokeModerator')"
>
{{ $t('admin_dash.users.actions.revoke_moderator') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmApprove')"
>
{{ $t('admin_dash.users.actions.approve') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmConfirm')"
>
{{ $t('admin_dash.users.actions.confirm') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmResendEmail')"
>
{{ $t('admin_dash.users.actions.resend_confirmation_email') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmRequirePasswordChange')"
>
{{ $t('admin_dash.users.actions.require_password_change') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="confirmSelection('confirmDisableMFA')"
>
{{ $t('admin_dash.users.actions.disable_mfa') }}
</button>
</div>
</div>
</template>
</Popover>
</template>
<template #item="{item}">
<AdminCard :user-details="item" />
</template>
<template #load>
<span> loading </span>
</template>
<template #empty>
<span> no users </span>
</template>
</PageList>
<GenericConfirm
ref="confirmActivate"
:title="$t('admin_dash.users.actions.confirm_multi.title')"

View file

@ -36,6 +36,38 @@
margin-top: 0.75em;
}
.toolbar {
display: flex;
flex-wrap: wrap;
gap: 0.5em;
align-items: end;
.header-buttons {
display: flex;
flex: 1 0 auto;
justify-content: end;
align-items: end;
&:not(.btn-group) {
gap: 0.5em;
}
.header-text {
flex: 1 0 auto;
}
}
.button-default {
flex: 0 0 auto;
padding: 0.5em;
font-size: 1rem;
}
.popover-wrapper {
display: flex;
}
}
p {
line-height: 1.5;
margin-left: 2em;

View file

@ -88,6 +88,8 @@
:label="$t('admin_dash.tabs.users')"
icon="user"
data-tab-name="users"
full-width
full-height
>
<UsersTab />
</div>

View file

@ -1291,7 +1291,7 @@
"users": {
"title": "Users",
"labels": {
"query": "Query",
"query": "Search",
"name": "Name",
"email": "Email",
"origin": "Origin",