Add Didar gap features: lost-reason reports, audit logs, tags, card assignees, and saved-views API.

Ignore Graphify local artifacts and expose new modules in superadmin.
This commit is contained in:
2026-09-26 14:59:48 +03:30
parent 35a618d0af
commit 6463275c3d
30 changed files with 1406 additions and 21 deletions
+21
View File
@@ -71,6 +71,7 @@ const title = ref('');
const type = ref<ActivityType | ''>('');
const priority = ref<ActivityPriority>('medium');
const description = ref('');
const tagsRaw = ref('');
const dueDate = ref('');
const dueTime = ref('10:30');
const durationMinutes = ref(30);
@@ -155,6 +156,7 @@ function resetForm() {
type.value = '';
priority.value = 'medium';
description.value = '';
tagsRaw.value = '';
defaultDue();
durationMinutes.value = 30;
personId.value = '';
@@ -201,6 +203,7 @@ async function load() {
priority.value = data.priority ?? 'medium';
description.value = data.description ?? '';
needsNote.value = Boolean(data.description?.trim());
tagsRaw.value = (data.tags ?? []).join('، ');
splitDue(data.dueAt);
durationMinutes.value = data.durationMinutes ?? 30;
reminderAt.value = data.reminderAt
@@ -240,6 +243,17 @@ async function load() {
}
}
function parseTags(raw: string): string[] {
return [
...new Set(
raw
.split(/[,،#\n]/)
.map((t) => t.trim())
.filter(Boolean),
),
].slice(0, 40);
}
function payload(): CreateActivityRequest {
const due =
dueDate.value && dueTime.value ? new Date(`${dueDate.value}T${dueTime.value}:00`) : null;
@@ -249,6 +263,7 @@ function payload(): CreateActivityRequest {
type: type.value || 'task',
priority: priority.value,
description: description.value || undefined,
tags: parseTags(tagsRaw.value),
dueAt: due && !Number.isNaN(due.getTime()) ? due.toISOString() : null,
durationMinutes: durationMinutes.value || null,
reminderAt: reminder && !Number.isNaN(reminder.getTime()) ? reminder.toISOString() : null,
@@ -573,6 +588,12 @@ watch([id, isNew], () => void load(), { immediate: true });
:rows="8"
placeholder="جزئیات تماس، نتیجه جلسه یا یادداشت مرتبط را بنویسید…"
/>
<label for="activity-tags" class="tags-label">هشتگ / برچسب</label>
<UiInput
id="activity-tags"
v-model="tagsRaw"
placeholder="پیگیری، فوری (با کاما یا #)"
/>
</div>
<p v-if="error" class="error">{{ error }}</p>