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; --__horizontal-gap: 0.75em;
--__vertical-gap: 0.5em; --__vertical-gap: 0.5em;
display: flex;
flex-direction: column;
.list {
flex: 1 1 0;
}
&-item-inner { &-item-inner {
display: flex; display: flex;
align-items: center; align-items: center;

View file

@ -1,16 +1,30 @@
.user-tab { .UsersTab {
height: 100%; max-height: 100%;
} display: grid;
flex-direction: column;
overflow-y: hidden;
.query-label { .filters-section {
padding-right: 10px; display: grid;
padding-left: 10px; grid-template-columns: 1fr 1fr 1fr;
} gap: 0.5em 1em;
.filter-input { > div {
width: 200px; flex: 0 1 auto;
} }
.filter-btn-box { .filter {
text-align: right; 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> <template>
<div :label="$t('admin_dash.users.management')"> <div
<div class="UsersTab"
class="setting-item" :label="$t('admin_dash.users.management')"
> >
<h2> {{ $t('admin_dash.users.title') }} </h2> <h3>
<ul class="setting-list"> {{ $t('admin_dash.users.title') }}
<li> </h3>
<label class="query-label"> {{ $t('admin_dash.users.labels.query') }} </label> <div class="filters-section">
<input <label class="filter">
v-model="filtersQuery" <div class="query-label">
class="input string-input filter-input" {{ $t('admin_dash.users.labels.query') }}
@input="reset()" </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> {{ $t('admin_dash.users.options.all') }}
<input </option>
v-model="filtersName" <option
class="input string-input filter-input" value="local"
@input="reset()"
> >
<label class="query-label"> {{ $t('admin_dash.users.labels.email') }} </label> {{ $t('admin_dash.users.options.only_local') }}
<input </option>
v-model="filtersEmail" <option
class="input string-input filter-input" value="external"
@input="reset()"
> >
</li> {{ $t('admin_dash.users.options.only_external') }}
<li> </option>
<label class="query-label"> {{ $t('admin_dash.users.labels.origin') }} </label> </Select>
<Select </div>
v-model="filtersOrigin" <div class="filter">
@update:model-value="reset" <div class="query-label">
{{ $t('admin_dash.users.labels.activity') }}
</div>
<Select
v-model="filtersActivity"
@update:model-value="reset"
>
<option
value="all"
> >
<option {{ $t('admin_dash.users.options.all') }}
value="all" </option>
> <option
{{ $t('admin_dash.users.options.all') }} value="active"
</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"
> >
<option {{ $t('admin_dash.users.options.only_active') }}
value="all" </option>
> <option
{{ $t('admin_dash.users.options.all') }} value="deactivated"
</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"
> >
<option {{ $t('admin_dash.users.options.only_deactivated') }}
value="all" </option>
> </Select>
{{ $t('admin_dash.users.options.all') }} </div>
</option> <div class="filter">
<option <div class="query-label">
value="admin" {{ $t('admin_dash.users.labels.privileges') }}
> </div>
{{ $t('admin_dash.users.options.only_admins') }} <Select
</option> v-model="filtersPrivileges"
<option @update:model-value="reset"
value="modsnadmins" >
> <option
{{ $t('admin_dash.users.options.only_privileged') }} value="all"
</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_unapproved') }} {{ $t('admin_dash.users.options.all') }}
</Checkbox> </option>
<Checkbox <option
class="query-label" value="admin"
@update:model-value="v => {filtersUncomfirmed = v; reset();}"
> >
{{ $t('admin_dash.users.options.only_unconfirmed') }} {{ $t('admin_dash.users.options.only_admins') }}
</Checkbox> </option>
</li> <option
</ul> value="modsnadmins"
<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> {{ $t('admin_dash.users.options.only_privileged') }}
<button </option>
class="button button-default btn" <option
> value="moderator"
{{ $t('admin_dash.users.actions.title') }} >
</button> {{ $t('admin_dash.users.options.only_moderators') }}
</template> </option>
<template #content> </Select>
<div class="dropdown-menu"> </div>
<div class="menu-item dropdown-item"> <div class="filter">
<button <Checkbox
class="main-button" @update:model-value="v => {filtersNeedApproval = v; reset();}"
@click="confirmSelection('confirmActivate')" >
> {{ $t('admin_dash.users.options.only_unapproved') }}
{{ $t('admin_dash.users.actions.activate') }} </Checkbox>
</button> </div>
</div> <div class="filter">
<div class="menu-item dropdown-item"> <Checkbox
<button @update:model-value="v => {filtersUncomfirmed = v; reset();}"
class="main-button" >
@click="confirmSelection('confirmDeactivate')" {{ $t('admin_dash.users.options.only_unconfirmed') }}
> </Checkbox>
{{ $t('admin_dash.users.actions.deactivate') }} </div>
</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>
</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 <GenericConfirm
ref="confirmActivate" ref="confirmActivate"
:title="$t('admin_dash.users.actions.confirm_multi.title')" :title="$t('admin_dash.users.actions.confirm_multi.title')"

View file

@ -36,6 +36,38 @@
margin-top: 0.75em; 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 { p {
line-height: 1.5; line-height: 1.5;
margin-left: 2em; margin-left: 2em;

View file

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

View file

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