Skip to content

Commit 56848b0

Browse files
committed
feat(triage): wire live pickers into drawer for linked projects
1 parent db4f968 commit 56848b0

1 file changed

Lines changed: 100 additions & 39 deletions

File tree

apps/dashboard/app/components/report-drawer/triage-footer.vue

Lines changed: 100 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ import type {
1111
ReportStatus,
1212
ReportSummaryDTO,
1313
} from "@reprojs/shared"
14+
import LabelsPicker from "./pickers/labels-picker.vue"
15+
import AssigneesPicker from "./pickers/assignees-picker.vue"
16+
import MilestonePicker from "./pickers/milestone-picker.vue"
1417
import UnlinkDialog from "~/components/integrations/github/unlink-dialog.vue"
1518
import { safeHref } from "~/composables/use-safe-href"
19+
import { useGithubIntegration } from "~/composables/use-github-integration"
1620
1721
interface Props {
1822
projectId: string
@@ -42,6 +46,11 @@ const githubReady = computed(
4246
() => Boolean(githubConfig.value?.installed) && githubConfig.value?.status === "connected",
4347
)
4448
49+
// Per-project integration state — drives the live picker section
50+
const projectIdRef = toRef(() => props.projectId)
51+
const { state: integrationState } = useGithubIntegration(projectIdRef)
52+
const isLinked = computed(() => integrationState.value.isLinked)
53+
4554
const tagDraft = ref("")
4655
const posting = ref(false)
4756
const unlinkOpen = ref(false)
@@ -209,14 +218,35 @@ const open = reactive({
209218
</div>
210219
<div class="flex items-center gap-3">
211220
<label class="w-20 shrink-0 text-xs font-medium text-muted">Assignee</label>
212-
<USelectMenu
213-
v-model="primaryAssignee"
214-
:items="assigneeItems"
215-
value-key="value"
216-
size="sm"
217-
class="flex-1 min-w-0"
218-
:disabled="!canEdit || posting"
219-
/>
221+
<template v-if="isLinked">
222+
<AssigneesPicker
223+
:project-id="projectId"
224+
:model-value="{
225+
dashboardUserIds: report.assignees.filter((a) => a.id).map((a) => a.id as string),
226+
githubLogins: report.assignees
227+
.filter((a) => !a.id && a.githubLogin)
228+
.map((a) => a.githubLogin as string),
229+
}"
230+
:disabled="!canEdit || posting"
231+
class="flex-1 min-w-0"
232+
@update:model-value="
233+
patch({
234+
assigneeIds: $event.dashboardUserIds,
235+
githubAssigneeLogins: $event.githubLogins,
236+
})
237+
"
238+
/>
239+
</template>
240+
<template v-else>
241+
<USelectMenu
242+
v-model="primaryAssignee"
243+
:items="assigneeItems"
244+
value-key="value"
245+
size="sm"
246+
class="flex-1 min-w-0"
247+
:disabled="!canEdit || posting"
248+
/>
249+
</template>
220250
</div>
221251
<div class="flex items-center gap-3">
222252
<label class="w-20 shrink-0 text-xs font-medium text-muted">Priority</label>
@@ -229,55 +259,86 @@ const open = reactive({
229259
:disabled="!canEdit || posting"
230260
/>
231261
</div>
262+
<template v-if="isLinked">
263+
<div class="flex items-center gap-3">
264+
<label class="w-20 shrink-0 text-xs font-medium text-muted">Milestone</label>
265+
<MilestonePicker
266+
:project-id="projectId"
267+
:model-value="
268+
report.milestoneNumber !== null && report.milestoneTitle !== null
269+
? {
270+
number: report.milestoneNumber as number,
271+
title: report.milestoneTitle as string,
272+
}
273+
: null
274+
"
275+
:disabled="!canEdit || posting"
276+
class="flex-1 min-w-0"
277+
@update:model-value="patch({ milestone: $event })"
278+
/>
279+
</div>
280+
</template>
232281
</div>
233282
</section>
234283

235284
<div class="border-t border-default/60" />
236285

237-
<!-- Tags — proper chips with hashtag + dismiss, input lives in the
238-
same row so the editor feels contiguous with the tag pile. -->
286+
<!-- Tags / Labels — when repo-linked, shows the live label picker;
287+
otherwise the manual tag-chip editor. -->
239288
<section>
240289
<button
241290
type="button"
242291
class="flex w-full items-center justify-between gap-2 mb-3 text-xs font-semibold uppercase tracking-[0.14em] text-muted hover:text-default transition-colors"
243292
:aria-expanded="open.tags"
244293
@click="open.tags = !open.tags"
245294
>
246-
<span>Tags</span>
295+
<span>{{ isLinked ? "Labels" : "Tags" }}</span>
247296
<UIcon
248297
name="i-heroicons-chevron-down"
249298
class="size-4 transition-transform"
250299
:class="open.tags ? '' : '-rotate-90'"
251300
/>
252301
</button>
253-
<div v-show="open.tags" class="flex flex-wrap gap-1.5 items-center">
254-
<span
255-
v-for="t in report.tags"
256-
:key="t"
257-
:class="[
258-
'inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-xs font-medium',
259-
'bg-primary/10 text-primary ring-1 ring-primary/20',
260-
canEdit ? 'cursor-pointer hover:bg-primary/15 transition-colors' : '',
261-
]"
262-
@click="canEdit ? removeTag(t) : null"
263-
>
264-
<UIcon name="i-heroicons-hashtag" class="size-3" />
265-
<span>{{ t }}</span>
266-
<UIcon v-if="canEdit" name="i-heroicons-x-mark" class="size-3 opacity-60" />
267-
</span>
268-
<UInput
269-
v-if="canEdit"
270-
v-model="tagDraft"
271-
placeholder="Add tag…"
272-
size="sm"
273-
variant="soft"
274-
icon="i-heroicons-plus"
275-
class="w-28"
276-
@keydown.enter.prevent="addTag"
277-
/>
278-
<span v-if="!canEdit && report.tags.length === 0" class="text-xs text-muted italic">
279-
None
280-
</span>
302+
<div v-show="open.tags">
303+
<template v-if="isLinked">
304+
<LabelsPicker
305+
:project-id="projectId"
306+
:model-value="report.tags"
307+
:disabled="!canEdit || posting"
308+
@update:model-value="patch({ tags: $event })"
309+
/>
310+
</template>
311+
<template v-else>
312+
<div class="flex flex-wrap gap-1.5 items-center">
313+
<span
314+
v-for="t in report.tags"
315+
:key="t"
316+
:class="[
317+
'inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-xs font-medium',
318+
'bg-primary/10 text-primary ring-1 ring-primary/20',
319+
canEdit ? 'cursor-pointer hover:bg-primary/15 transition-colors' : '',
320+
]"
321+
@click="canEdit ? removeTag(t) : null"
322+
>
323+
<UIcon name="i-heroicons-hashtag" class="size-3" />
324+
<span>{{ t }}</span>
325+
<UIcon v-if="canEdit" name="i-heroicons-x-mark" class="size-3 opacity-60" />
326+
</span>
327+
<UInput
328+
v-if="canEdit"
329+
v-model="tagDraft"
330+
placeholder="Add tag…"
331+
size="sm"
332+
variant="soft"
333+
icon="i-heroicons-plus"
334+
class="w-28"
335+
@keydown.enter.prevent="addTag"
336+
/>
337+
<span v-if="!canEdit && report.tags.length === 0" class="text-xs text-muted italic">
338+
None
339+
</span>
340+
</div>
341+
</template>
281342
</div>
282343
</section>
283344

0 commit comments

Comments
 (0)