feat(activities): let every assignee finish their own share

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-11-09 20:48:43 +03:30
co-authored by Cursor
parent dae3ae3f7e
commit da851bd9e5
10 changed files with 479 additions and 51 deletions
+39 -1
View File
@@ -129,6 +129,7 @@ const personId = ref('');
const leadId = ref('');
const dealId = ref('');
const assigneeIds = ref<string[]>([]);
const completionMode = ref<'any' | 'all'>('any');
const isDone = ref(false);
const needsNote = ref(false);
const reminderAt = ref('');
@@ -440,6 +441,7 @@ function resetForm() {
personId.value = '';
dealId.value = '';
assigneeIds.value = auth.user?.id ? [auth.user.id] : [];
completionMode.value = 'any';
pickedRoleIds.value = [];
pickedTeamIds.value = [];
isDone.value = false;
@@ -528,6 +530,7 @@ async function load() {
: auth.user?.id
? [auth.user.id]
: [];
completionMode.value = data.completionMode === 'all' ? 'all' : 'any';
refreshPickedGroups();
isDone.value = data.status === 'done';
await loadSavedPhotos(data);
@@ -605,6 +608,7 @@ function payload(): CreateActivityRequest {
leadId: leadId.value || null,
assigneeIds: [...assigneeIds.value],
assigneeId: assigneeIds.value[0] || null,
completionMode: assigneeIds.value.length > 1 ? completionMode.value : 'any',
};
}
@@ -978,7 +982,9 @@ async function submit(next: 'detail' | 'new' = 'detail') {
savedId = data.id;
createdActivityId.value = data.id;
if (isDone.value) {
await api.patch(`/activities/${savedId}/complete`);
await api.patch(`/activities/${savedId}/complete`, undefined, {
params: { force: '1' },
});
}
} else {
await api.patch(`/activities/${savedId}`, {
@@ -1269,6 +1275,17 @@ watch([id, isNew], () => void load(), { immediate: true });
</li>
</ul>
</div>
<div v-if="assigneeIds.length > 1" class="completion-mode">
<span>نحوهٔ انجام</span>
<label>
<input v-model="completionMode" type="radio" value="any" />
با انجام یکی کافی است
</label>
<label>
<input v-model="completionMode" type="radio" value="all" />
همهٔ مسئول‌ها باید انجام دهند
</label>
</div>
<small class="hint">
{{
canAssignOthers
@@ -1799,6 +1816,27 @@ watch([id, isNew], () => void load(), { immediate: true });
font-size: 0.75rem;
}
.completion-mode {
display: flex;
flex-wrap: wrap;
gap: 0.65rem 1rem;
margin-top: 0.75rem;
color: #334155;
font-size: 0.88rem;
}
.completion-mode span {
width: 100%;
font-weight: 600;
}
.completion-mode label {
display: inline-flex;
align-items: center;
gap: 0.35rem;
cursor: pointer;
}
.assignee-chips {
display: flex;
flex-wrap: wrap;