feat : add collaborators multi-select to TaskModal
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -170,6 +170,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Collaborators -->
|
||||||
|
<div v-if="collaboratorOptions.length" class="mt-5">
|
||||||
|
<p class="mb-2 text-sm font-medium text-neutral-700">Collaborateurs</p>
|
||||||
|
<div class="flex flex-wrap gap-2">
|
||||||
|
<label
|
||||||
|
v-for="user in collaboratorOptions"
|
||||||
|
:key="user.value"
|
||||||
|
class="cursor-pointer rounded-full px-3 py-1 text-xs font-semibold transition-all"
|
||||||
|
:class="form.collaboratorIds.includes(user.value)
|
||||||
|
? 'bg-primary-500 text-white shadow-sm'
|
||||||
|
: 'bg-neutral-100 text-neutral-600 hover:bg-neutral-200'"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="hidden"
|
||||||
|
:value="user.value"
|
||||||
|
:checked="form.collaboratorIds.includes(user.value)"
|
||||||
|
@change="toggleCollaborator(user.value)"
|
||||||
|
/>
|
||||||
|
{{ user.label }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Description -->
|
<!-- Description -->
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<MalioInputTextArea
|
<MalioInputTextArea
|
||||||
@@ -544,6 +568,7 @@ const form = reactive({
|
|||||||
effortId: null as number | null,
|
effortId: null as number | null,
|
||||||
priorityId: null as number | null,
|
priorityId: null as number | null,
|
||||||
assigneeId: null as number | null,
|
assigneeId: null as number | null,
|
||||||
|
collaboratorIds: [] as number[],
|
||||||
groupId: null as number | null,
|
groupId: null as number | null,
|
||||||
tagIds: [] as number[],
|
tagIds: [] as number[],
|
||||||
clientTicketId: null as number | null,
|
clientTicketId: null as number | null,
|
||||||
@@ -586,6 +611,18 @@ const userOptions = computed(() =>
|
|||||||
props.users.map(u => ({ label: u.username, value: u.id }))
|
props.users.map(u => ({ label: u.username, value: u.id }))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const collaboratorOptions = computed(() =>
|
||||||
|
props.users
|
||||||
|
.filter(u => u.id !== form.assigneeId)
|
||||||
|
.map(u => ({ label: u.username, value: u.id }))
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(() => form.assigneeId, (newAssigneeId) => {
|
||||||
|
if (newAssigneeId) {
|
||||||
|
form.collaboratorIds = form.collaboratorIds.filter(id => id !== newAssigneeId)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const groupOptions = computed(() => {
|
const groupOptions = computed(() => {
|
||||||
let filtered = props.groups.filter(g => !g.archived)
|
let filtered = props.groups.filter(g => !g.archived)
|
||||||
if (showProjectSelect.value && form.projectId) {
|
if (showProjectSelect.value && form.projectId) {
|
||||||
@@ -624,6 +661,12 @@ function toggleTag(id: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleCollaborator(userId: number) {
|
||||||
|
const idx = form.collaboratorIds.indexOf(userId)
|
||||||
|
if (idx >= 0) form.collaboratorIds.splice(idx, 1)
|
||||||
|
else form.collaboratorIds.push(userId)
|
||||||
|
}
|
||||||
|
|
||||||
const weekDays = computed(() => [
|
const weekDays = computed(() => [
|
||||||
{ value: 'monday', label: t('tasks.planning.days.mon') },
|
{ value: 'monday', label: t('tasks.planning.days.mon') },
|
||||||
{ value: 'tuesday', label: t('tasks.planning.days.tue') },
|
{ value: 'tuesday', label: t('tasks.planning.days.tue') },
|
||||||
@@ -648,6 +691,7 @@ function populateForm(task: Task | null) {
|
|||||||
form.effortId = task.effort?.id ?? null
|
form.effortId = task.effort?.id ?? null
|
||||||
form.priorityId = task.priority?.id ?? null
|
form.priorityId = task.priority?.id ?? null
|
||||||
form.assigneeId = task.assignee?.id ?? null
|
form.assigneeId = task.assignee?.id ?? null
|
||||||
|
form.collaboratorIds = task.collaborators?.map(c => c.id) ?? []
|
||||||
form.groupId = task.group?.id ?? null
|
form.groupId = task.group?.id ?? null
|
||||||
form.tagIds = task.tags.map(t => t.id)
|
form.tagIds = task.tags.map(t => t.id)
|
||||||
form.clientTicketId = task.clientTicket?.id ?? null
|
form.clientTicketId = task.clientTicket?.id ?? null
|
||||||
@@ -694,6 +738,7 @@ function populateForm(task: Task | null) {
|
|||||||
form.effortId = null
|
form.effortId = null
|
||||||
form.priorityId = null
|
form.priorityId = null
|
||||||
form.assigneeId = null
|
form.assigneeId = null
|
||||||
|
form.collaboratorIds = []
|
||||||
form.groupId = null
|
form.groupId = null
|
||||||
form.tagIds = []
|
form.tagIds = []
|
||||||
form.clientTicketId = null
|
form.clientTicketId = null
|
||||||
@@ -906,6 +951,7 @@ async function handleSubmit() {
|
|||||||
effort: form.effortId ? `/api/task_efforts/${form.effortId}` : null,
|
effort: form.effortId ? `/api/task_efforts/${form.effortId}` : null,
|
||||||
priority: form.priorityId ? `/api/task_priorities/${form.priorityId}` : null,
|
priority: form.priorityId ? `/api/task_priorities/${form.priorityId}` : null,
|
||||||
assignee: form.assigneeId ? `/api/users/${form.assigneeId}` : null,
|
assignee: form.assigneeId ? `/api/users/${form.assigneeId}` : null,
|
||||||
|
collaborators: form.collaboratorIds.map(id => `/api/users/${id}`),
|
||||||
group: form.groupId ? `/api/task_groups/${form.groupId}` : null,
|
group: form.groupId ? `/api/task_groups/${form.groupId}` : null,
|
||||||
project: `/api/projects/${resolvedProjectId.value}`,
|
project: `/api/projects/${resolvedProjectId.value}`,
|
||||||
tags: form.tagIds.map(id => `/api/task_tags/${id}`),
|
tags: form.tagIds.map(id => `/api/task_tags/${id}`),
|
||||||
|
|||||||
Reference in New Issue
Block a user