Merge branch 'admin-users' into shigusegubu-themes3

This commit is contained in:
Henry Jameson 2026-06-12 18:58:21 +03:00
commit ef06ede51b
7 changed files with 185 additions and 141 deletions

View file

@ -3,6 +3,11 @@
margin: 0.5em 2em; margin: 0.5em 2em;
} }
.setting-section {
margin-left: 0.5em;
margin-right: 0.5em;
}
.toolbar { .toolbar {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;

View file

@ -1,4 +1,5 @@
.FrontendsTab { .FrontendsTab {
padding: 0 1em;
.cards-list { .cards-list {
padding: 0; padding: 0;
} }
@ -34,7 +35,8 @@
h5 { h5 {
margin: 0; margin: 0;
font-size: 1.15em font-size: 1.15em;
text-transform: capitalize;
} }
dl { dl {

View file

@ -2,14 +2,26 @@
max-height: 100%; max-height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow-y: hidden; padding: 0;
h3 {
margin-left: 0.5em;
margin-right: 0.5em;
}
.splitter {
max-height: 100%;
display: flex;
overflow-y: hidden;
}
.filters-section { .filters-section {
display: grid; display: flex;
grid-template-columns: repeat(auto-fit, minmax(15em, 1fr)); flex-direction: column;
grid-auto-columns: 1fr; gap: 1em;
grid-auto-flow: row; border-right: 1px solid var(--border);
gap: 0.5em 1em; padding: 0 1em;
margin-right: 1em;
> div { > div {
flex: 0 1 auto; flex: 0 1 auto;
@ -17,7 +29,6 @@
.filter { .filter {
display: block; display: block;
margin-bottom: 0.5em;
min-width: 14em; min-width: 14em;
.query-label { .query-label {
@ -29,4 +40,8 @@
} }
} }
} }
.users-list {
flex: 1 0 30em;
}
} }

View file

@ -6,140 +6,143 @@
<h3> <h3>
{{ $t('admin_dash.users.title') }} {{ $t('admin_dash.users.title') }}
</h3> </h3>
<div class="filters-section"> <div class="splitter">
<label class="filter"> <div class="filters-section">
<div class="query-label"> <label class="filter">
{{ $t('admin_dash.users.labels.query') }} <div class="query-label">
</div> {{ $t('admin_dash.users.labels.nickname') }}
<input </div>
v-model="filtersQuery" <input
class="input string-input filter-input" v-model="filtersQuery"
> class="input string-input filter-input"
</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"
>
</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"
>
</label>
<div class="filter">
<div class="query-label">
{{ $t('admin_dash.users.labels.origin') }}
</div>
<Select
v-model="filtersOrigin"
>
<option
value="all"
> >
{{ $t('admin_dash.users.options.all') }} </label>
</option> <label class="filter">
<option <div class="query-label">
value="local" {{ $t('admin_dash.users.labels.name') }}
</div>
<input
v-model="filtersName"
class="input string-input filter-input"
> >
{{ $t('admin_dash.users.options.only_local') }} </label>
</option> <label class="filter">
<option <div class="query-label">
value="external" {{ $t('admin_dash.users.labels.email') }}
</div>
<input
v-model="filtersEmail"
class="input string-input filter-input"
> >
{{ $t('admin_dash.users.options.only_external') }} </label>
</option> <div class="filter">
</Select> <div class="query-label">
</div> {{ $t('admin_dash.users.labels.origin') }}
<div class="filter"> </div>
<div class="query-label"> <Select
{{ $t('admin_dash.users.labels.activity') }} v-model="filtersOrigin"
</div> >
<Select <option
v-model="filtersActivity" value="all"
> >
<option {{ $t('admin_dash.users.options.all') }}
value="all" </option>
> <option
{{ $t('admin_dash.users.options.all') }} value="local"
</option> >
<option {{ $t('admin_dash.users.options.only_local') }}
value="active" </option>
> <option
{{ $t('admin_dash.users.options.only_active') }} value="external"
</option> >
<option {{ $t('admin_dash.users.options.only_external') }}
value="deactivated" </option>
> </Select>
{{ $t('admin_dash.users.options.only_deactivated') }} </div>
</option> <div class="filter">
</Select> <div class="query-label">
</div> {{ $t('admin_dash.users.labels.activity') }}
<div class="filter"> </div>
<div class="query-label"> <Select
{{ $t('admin_dash.users.labels.privileges') }} v-model="filtersActivity"
</div> >
<Select v-model="filtersPrivileges"> <option
<option value="all"
value="all" >
> {{ $t('admin_dash.users.options.all') }}
{{ $t('admin_dash.users.options.all') }} </option>
</option> <option
<option value="active"
value="admin" >
> {{ $t('admin_dash.users.options.only_active') }}
{{ $t('admin_dash.users.options.only_admins') }} </option>
</option> <option
<option value="deactivated"
value="modsnadmins" >
> {{ $t('admin_dash.users.options.only_deactivated') }}
{{ $t('admin_dash.users.options.only_privileged') }} </option>
</option> </Select>
<option </div>
value="moderator" <div class="filter">
> <div class="query-label">
{{ $t('admin_dash.users.options.only_moderators') }} {{ $t('admin_dash.users.labels.privileges') }}
</option> </div>
</Select> <Select v-model="filtersPrivileges">
</div> <option
<div class="filter"> value="all"
<Checkbox v-model="filtersNeedApproval"> >
{{ $t('admin_dash.users.options.only_unapproved') }} {{ $t('admin_dash.users.options.all') }}
</Checkbox> </option>
</div> <option
<div class="filter"> value="admin"
<Checkbox v-model="filtersUnconfirmed"> >
{{ $t('admin_dash.users.options.only_unconfirmed') }} {{ $t('admin_dash.users.options.only_admins') }}
</Checkbox> </option>
<option
value="modsnadmins"
>
{{ $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 v-model="filtersNeedApproval">
{{ $t('admin_dash.users.options.only_unapproved') }}
</Checkbox>
</div>
<div class="filter">
<Checkbox v-model="filtersUnconfirmed">
{{ $t('admin_dash.users.options.only_unconfirmed') }}
</Checkbox>
</div>
</div> </div>
<List
ref="usersList"
class="users-list"
:fetch-function="fetchUsers"
selectable
scrollable
@select="onSelect"
>
<template #header="{selected}">
<ModerationTools :users="selected" />
</template>
<template #item="{item}">
<AdminUserCard :user-id="item.id" />
</template>
<template #load>
<span> loading </span>
</template>
<template #empty>
<span> no users </span>
</template>
</List>
</div> </div>
<List
ref="usersList"
:fetch-function="fetchUsers"
selectable
scrollable
@select="onSelect"
>
<template #header="{selected}">
<ModerationTools :users="selected" />
</template>
<template #item="{item}">
<AdminUserCard :user-id="item.id" />
</template>
<template #load>
<span> loading </span>
</template>
<template #empty>
<span> no users </span>
</template>
</List>
</div> </div>
</template> </template>
<script src="./users_tab.js"></script> <script src="./users_tab.js"></script>

View file

@ -160,19 +160,25 @@ export default {
'tab-content-wrapper', 'tab-content-wrapper',
active ? '-active' : '-hidden', active ? '-active' : '-hidden',
] ]
const slotWrapperClasses = [
'tab-slot-wrapper',
active ? '-active' : '-hidden',
]
const contentClasses = ['tab-content'] const contentClasses = ['tab-content']
if (props['full-width'] || props['full-width'] === '') { if (props['full-width'] || props['full-width'] != null) {
contentClasses.push('-full-width') contentClasses.push('-full-width')
wrapperClasses.push('-full-width') wrapperClasses.push('-full-width')
slotWrapperClasses.push('-full-width')
} }
if (props['full-height'] || props['full-width'] === '') { if (props['full-height'] || props['full-width'] != null) {
contentClasses.push('-full-height') contentClasses.push('-full-height')
wrapperClasses.push('-full-height') wrapperClasses.push('-full-height')
slotWrapperClasses.push('-full-height')
} }
return ( return (
<div class={wrapperClasses}> <div class={wrapperClasses}>
<div class="tab-mobile-header">{header}</div> <div class="tab-mobile-header">{header}</div>
<div class="tab-slot-wrapper"> <div class={slotWrapperClasses}>
<div class={contentClasses}>{renderSlot}</div> <div class={contentClasses}>{renderSlot}</div>
</div> </div>
</div> </div>

View file

@ -49,6 +49,16 @@
grid-template-areas: ". content ."; grid-template-areas: ". content .";
flex-direction: column; flex-direction: column;
&.-full-width {
padding-left: 0;
padding-right: 0;
}
&.-full-height {
padding-top: 0;
padding-bottom: 0;
}
.tab-content { .tab-content {
grid-area: content; grid-area: content;
@ -57,6 +67,8 @@
} }
&.-full-height { &.-full-height {
display: flex;
flex-direction: column;
height: 100%; height: 100%;
> * { > * {

View file

@ -1297,7 +1297,8 @@
"local_id": "Local ID", "local_id": "Local ID",
"labels": { "labels": {
"query": "Search", "query": "Search",
"name": "Name", "nickname": "@handle",
"name": "Display Name",
"name_colon": "Name:", "name_colon": "Name:",
"email": "Email", "email": "Email",
"email_colon": "Email:", "email_colon": "Email:",