Track person import source and previous names; add source report and edit UX.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -197,6 +197,7 @@ async function importSelected() {
|
||||
mobile: row.mobile,
|
||||
phone: row.phone,
|
||||
email: row.email,
|
||||
importSource: 'phone',
|
||||
};
|
||||
await api.post<PersonDto>('/people', body);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,9 @@ const teams = ref<TeamDto[]>([]);
|
||||
const newName = ref('');
|
||||
const newDesc = ref('');
|
||||
const editingId = ref<string | null>(null);
|
||||
const editingMetaId = ref<string | null>(null);
|
||||
const editName = ref('');
|
||||
const editDesc = ref('');
|
||||
const memberDraft = ref<Record<string, TeamMemberRole>>({});
|
||||
|
||||
const editableUsers = computed(() =>
|
||||
@@ -83,6 +86,7 @@ async function createTeam() {
|
||||
|
||||
function startEdit(team: TeamDto) {
|
||||
editingId.value = team.id;
|
||||
editingMetaId.value = null;
|
||||
const draft: Record<string, TeamMemberRole> = {};
|
||||
for (const m of team.members) {
|
||||
draft[m.userId] = m.role;
|
||||
@@ -90,6 +94,38 @@ function startEdit(team: TeamDto) {
|
||||
memberDraft.value = draft;
|
||||
}
|
||||
|
||||
function startMetaEdit(team: TeamDto) {
|
||||
editingMetaId.value = team.id;
|
||||
editingId.value = null;
|
||||
editName.value = team.name;
|
||||
editDesc.value = team.description || '';
|
||||
}
|
||||
|
||||
async function saveMeta() {
|
||||
if (!editingMetaId.value) return;
|
||||
if (!editName.value.trim()) {
|
||||
error.value = 'نام تیم را وارد کنید.';
|
||||
return;
|
||||
}
|
||||
saving.value = true;
|
||||
error.value = '';
|
||||
try {
|
||||
await api.patch(`/teams/${editingMetaId.value}`, {
|
||||
name: editName.value.trim(),
|
||||
description: editDesc.value.trim(),
|
||||
});
|
||||
ok.value = 'اطلاعات تیم ذخیره شد.';
|
||||
editingMetaId.value = null;
|
||||
await load();
|
||||
} catch (e) {
|
||||
error.value = axios.isAxiosError(e)
|
||||
? String((e.response?.data as { message?: string })?.message ?? 'ذخیره تیم ناموفق بود.')
|
||||
: 'ذخیره تیم ناموفق بود.';
|
||||
} finally {
|
||||
saving.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMember(userId: string) {
|
||||
if (memberDraft.value[userId]) {
|
||||
const next = { ...memberDraft.value };
|
||||
@@ -194,6 +230,7 @@ onMounted(() => {
|
||||
</p>
|
||||
</div>
|
||||
<div v-if="canEdit" class="actions">
|
||||
<UiButton variant="secondary" @click="startMetaEdit(t)">ویرایش</UiButton>
|
||||
<UiButton variant="secondary" @click="startEdit(t)">اعضا</UiButton>
|
||||
<UiButton variant="secondary" @click="removeTeam(t.id)">حذف</UiButton>
|
||||
</div>
|
||||
@@ -208,6 +245,21 @@ onMounted(() => {
|
||||
}}
|
||||
</p>
|
||||
|
||||
<div v-if="editingMetaId === t.id" class="editor">
|
||||
<div class="row">
|
||||
<UiField label="نام تیم">
|
||||
<UiInput v-model="editName" />
|
||||
</UiField>
|
||||
<UiField label="توضیح">
|
||||
<UiInput v-model="editDesc" />
|
||||
</UiField>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<UiButton :loading="saving" @click="saveMeta">ذخیره</UiButton>
|
||||
<UiButton variant="secondary" @click="editingMetaId = null">انصراف</UiButton>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="editingId === t.id" class="editor">
|
||||
<p class="hint">اعضا را انتخاب کنید؛ سرپرست همان عضو تیم است.</p>
|
||||
<label v-for="u in users.filter((x) => x.isActive !== false)" :key="u.id" class="person">
|
||||
|
||||
Reference in New Issue
Block a user