Improve team settings search, user sorting, and role badge layout.
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import {
|
||||
import { UiButton, UiEmptyState, UiField, UiInput } from '@/components/ui';
|
||||
import DataAccessPolicyPanel from '@/components/DataAccessPolicyPanel.vue';
|
||||
import { formatLocalDateInput, parseLocalInput, toFaDigits } from '@/lib/jalali';
|
||||
import { matchesSearch } from '@/lib/search';
|
||||
|
||||
const props = defineProps<{
|
||||
users: OrgUserDto[];
|
||||
@@ -74,6 +75,29 @@ const editableUsers = computed(() =>
|
||||
props.users.filter((u) => u.isActive !== false && u.role !== 'owner' && u.role !== 'admin'),
|
||||
);
|
||||
|
||||
const teamsQuery = ref('');
|
||||
const accessQuery = ref('');
|
||||
|
||||
const filteredTeams = computed(() => {
|
||||
const q = teamsQuery.value.trim();
|
||||
if (!q) return teams.value;
|
||||
return teams.value.filter((team) =>
|
||||
matchesSearch(q, [
|
||||
team.name,
|
||||
team.description,
|
||||
...team.members.map((m) => m.fullName),
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
const filteredAccessUsers = computed(() => {
|
||||
const q = accessQuery.value.trim();
|
||||
if (!q) return editableUsers.value;
|
||||
return editableUsers.value.filter((u) =>
|
||||
matchesSearch(q, [u.fullName, u.mobile, u.email, u.orgRoleName, accessSummary(u)]),
|
||||
);
|
||||
});
|
||||
|
||||
async function setPriorArchive(userId: string, enabled: boolean) {
|
||||
priorSavingId.value = userId;
|
||||
priorPick.value = '';
|
||||
@@ -383,14 +407,22 @@ onMounted(() => {
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h3>تیمها</h3>
|
||||
<header class="card-head">
|
||||
<h3>تیمها</h3>
|
||||
<UiInput
|
||||
v-if="teams.length"
|
||||
v-model="teamsQuery"
|
||||
placeholder="جستجوی تیم یا عضو…"
|
||||
/>
|
||||
</header>
|
||||
<UiEmptyState
|
||||
v-if="!loading && !teams.length"
|
||||
title="تیمی تعریف نشده"
|
||||
description="تیم بسازید تا اعضای فروش پروندههای همتیمی را ببینند."
|
||||
/>
|
||||
<p v-else-if="!filteredTeams.length" class="hint">تیمی با این جستجو پیدا نشد.</p>
|
||||
<div v-else class="team-list">
|
||||
<article v-for="t in teams" :key="t.id" class="team">
|
||||
<article v-for="t in filteredTeams" :key="t.id" class="team">
|
||||
<header>
|
||||
<div>
|
||||
<strong>{{ t.name }}</strong>
|
||||
@@ -504,7 +536,14 @@ onMounted(() => {
|
||||
</section>
|
||||
|
||||
<section class="card">
|
||||
<h3>محدوده داده</h3>
|
||||
<header class="card-head">
|
||||
<h3>محدوده داده</h3>
|
||||
<UiInput
|
||||
v-if="editableUsers.length"
|
||||
v-model="accessQuery"
|
||||
placeholder="جستجوی کاربر…"
|
||||
/>
|
||||
</header>
|
||||
<p class="hint">
|
||||
مالک و مدیر همیشه همه را میبینند. پیشفرض از نقش میآید؛ برای کاربر خاص میتوانید فیلتر
|
||||
جدا بگذارید.
|
||||
@@ -514,8 +553,9 @@ onMounted(() => {
|
||||
title="کاربر قابل تنظیم نیست"
|
||||
description="فقط نقشهای فروش و پشتیبانی محدوده داده جدا دارند."
|
||||
/>
|
||||
<p v-else-if="!filteredAccessUsers.length" class="hint">کاربری با این جستجو پیدا نشد.</p>
|
||||
<div v-else class="vis-table">
|
||||
<div v-for="u in editableUsers" :key="u.id" class="vis-user">
|
||||
<div v-for="u in filteredAccessUsers" :key="u.id" class="vis-user">
|
||||
<div class="vis-row">
|
||||
<span>
|
||||
{{ u.fullName }}
|
||||
@@ -567,6 +607,22 @@ onMounted(() => {
|
||||
margin: 0 0 0.75rem;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.card-head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.6rem;
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
.card-head h3 {
|
||||
margin: 0;
|
||||
}
|
||||
.card-head :deep(.field),
|
||||
.card-head :deep(input) {
|
||||
min-width: min(16rem, 100%);
|
||||
max-width: 18rem;
|
||||
}
|
||||
.prior-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user