Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 25 additions & 16 deletions app/components/focus/CreatedIssueCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const props = defineProps<{

const { t } = useI18n()
const localePath = useLocalePath()
const { open: openProfile } = useUserProfileDialog()
const timeAgo = useTimeAgo(computed(() => props.item.updatedAt))

// --- State ---
Expand Down Expand Up @@ -227,24 +228,32 @@ function ciColor(pr: CreatedIssuePR) {
</span>

<!-- Assignees -->
<UTooltip
<span
v-if="item.assignees.length > 0"
:text="item.assignees.map(a => a.login).join(', ')"
class="inline-flex items-center gap-1"
>
<span class="inline-flex items-center gap-1">
<UIcon
name="i-lucide-users"
class="size-3.5"
/>
<UAvatar
v-for="a in item.assignees.slice(0, 3)"
:key="a.login"
:src="a.avatarUrl"
:alt="a.login"
size="3xs"
/>
</span>
</UTooltip>
<UIcon
name="i-lucide-users"
class="size-3.5"
/>
<UTooltip
v-for="a in item.assignees.slice(0, 3)"
:key="a.login"
:text="a.login"
>
<button
type="button"
class="cursor-pointer"
@click.stop.prevent="openProfile(a.login)"
>
<UAvatar
:src="a.avatarUrl"
:alt="a.login"
size="3xs"
/>
</button>
</UTooltip>
</span>

<!-- Linked PRs with review + CI status -->
<UTooltip
Expand Down
24 changes: 10 additions & 14 deletions app/components/focus/InboxUnifiedCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -330,45 +330,41 @@ const issuePreview = computed(() =>
>
{{ t('focus.inbox.reviewers') }}
</span>
<a
<button
v-for="reviewer in item.requestedReviewers"
:key="reviewer.login"
:href="`https://github.com/${reviewer.login}`"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-1 text-xs bg-muted/50 rounded-full px-2 py-0.5 hover:bg-muted transition-colors"
@click.stop
type="button"
class="inline-flex items-center gap-1 text-xs bg-muted/50 rounded-full px-2 py-0.5 hover:bg-muted transition-colors cursor-pointer"
@click.stop="openProfile(reviewer.login)"
>
<UAvatar
:src="reviewer.avatarUrl"
:alt="reviewer.login"
size="3xs"
/>
<span class="text-muted">{{ reviewer.login }}</span>
</a>
</button>

<span
v-if="item.assignees?.length"
class="text-[10px] uppercase tracking-wider text-dimmed font-semibold"
>
{{ t('focus.inbox.assigneesLabel') }}
</span>
<a
<button
v-for="assignee in item.assignees"
:key="assignee.login"
:href="`https://github.com/${assignee.login}`"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center gap-1 text-xs bg-muted/50 rounded-full px-2 py-0.5 hover:bg-muted transition-colors"
@click.stop
type="button"
class="inline-flex items-center gap-1 text-xs bg-muted/50 rounded-full px-2 py-0.5 hover:bg-muted transition-colors cursor-pointer"
@click.stop="openProfile(assignee.login)"
>
<UAvatar
:src="assignee.avatarUrl"
:alt="assignee.login"
size="3xs"
/>
<span class="text-muted">{{ assignee.login }}</span>
</a>
</button>
</div>
</div>
</div>
Expand Down
19 changes: 13 additions & 6 deletions app/components/issue/IssueHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const props = defineProps<{

const { t } = useI18n()
const toast = useToast()
const { open: openProfile } = useUserProfileDialog()

const createdAgo = useTimeAgo(computed(() => props.issue.createdAt))
const updatedAgo = useTimeAgo(computed(() => props.issue.updatedAt))
Expand Down Expand Up @@ -147,12 +148,18 @@ function prStateColor(state: string) {
:key="assignee.login"
class="flex items-center gap-1.5"
>
<UAvatar
:src="assignee.avatarUrl"
:alt="assignee.login"
size="2xs"
/>
<span class="text-sm font-medium text-highlighted hidden sm:inline">{{ assignee.login }}</span>
<button
type="button"
class="inline-flex items-center gap-1.5 cursor-pointer hover:underline"
@click="openProfile(assignee.login)"
>
<UAvatar
:src="assignee.avatarUrl"
:alt="assignee.login"
size="2xs"
/>
<span class="text-sm font-medium text-highlighted hidden sm:inline">{{ assignee.login }}</span>
</button>

<a
v-if="assignee.pr"
Expand Down
25 changes: 18 additions & 7 deletions app/components/issue/IssueRow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const props = defineProps<{

const { t } = useI18n()
const localePath = useLocalePath()
const { open: openProfile } = useUserProfileDialog()
const createdAgo = useTimeAgo(computed(() => props.issue.createdAt))
const updatedAgo = useTimeAgo(computed(() => props.issue.updatedAt))

Expand Down Expand Up @@ -66,14 +67,18 @@ const stateColor = computed(() => {
/>
</span>
</UTooltip>
<span class="inline-flex items-center gap-1">
<button
type="button"
class="inline-flex items-center gap-1 cursor-pointer hover:underline"
@click.stop.prevent="openProfile(issue.author.login)"
>
<UAvatar
:src="issue.author.avatarUrl"
:alt="issue.author.login"
size="3xs"
/>
{{ issue.author.login }}
</span>
</button>
<span>#{{ issue.number }}</span>
<span>{{ createdAgo }}</span>
<span>{{ updatedAgo }}</span>
Expand Down Expand Up @@ -128,11 +133,17 @@ const stateColor = computed(() => {
:key="assignee.login"
:text="assignee.login"
>
<UAvatar
:src="assignee.avatarUrl"
:alt="assignee.login"
size="xs"
/>
<button
type="button"
class="cursor-pointer"
@click.stop.prevent="openProfile(assignee.login)"
>
<UAvatar
:src="assignee.avatarUrl"
:alt="assignee.login"
size="xs"
/>
</button>
</UTooltip>
</div>
</NuxtLink>
Expand Down
21 changes: 14 additions & 7 deletions app/components/issue/IssueSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const props = defineProps<{

const { t } = useI18n()
const { user } = useUserSession()
const { open: openProfile } = useUserProfileDialog()

const repoOwner = computed(() => props.repo.split('/')[0] ?? '')

Expand Down Expand Up @@ -234,13 +235,19 @@ const linksOverflow = computed(() =>
:key="p.login"
:text="p.login"
>
<UAvatar
:src="p.avatarUrl"
:alt="p.login"
size="2xs"
class="ring-1 ring-default"
:class="p.login.toLowerCase() === repoOwner.toLowerCase() ? 'ring-primary/50' : ''"
/>
<button
type="button"
class="cursor-pointer"
@click="openProfile(p.login)"
>
<UAvatar
:src="p.avatarUrl"
:alt="p.login"
size="2xs"
class="ring-1 ring-default"
:class="p.login.toLowerCase() === repoOwner.toLowerCase() ? 'ring-primary/50' : ''"
/>
</button>
</UTooltip>
<button
v-if="participantsOverflow > 0"
Expand Down
19 changes: 13 additions & 6 deletions app/components/repo/RepoStatistics.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const props = defineProps<{
stats: RepoHealthStats
}>()

const { open: openProfile } = useUserProfileDialog()
const lastCommitAgo = useTimeAgo(computed(() => props.stats.lastCommitDate ?? new Date().toISOString()))
const releaseDate = computed(() => props.stats.lastRelease?.publishedAt ?? new Date().toISOString())
const releaseAgo = useTimeAgo(releaseDate)
Expand Down Expand Up @@ -176,12 +177,18 @@ const releaseAgo = useTimeAgo(releaseDate)
:key="contributor.login"
:text="contributor.login"
>
<UAvatar
:src="contributor.avatarUrl"
:alt="contributor.login"
size="xs"
class="ring-2 ring-default"
/>
<button
type="button"
class="cursor-pointer"
@click="openProfile(contributor.login)"
>
<UAvatar
:src="contributor.avatarUrl"
:alt="contributor.login"
size="xs"
class="ring-2 ring-default"
/>
</button>
</UTooltip>
<span
v-if="stats.contributorsCount > 8"
Expand Down
19 changes: 13 additions & 6 deletions app/components/user/UserCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const props = defineProps<{
}>()

const { t } = useI18n()
const { open: openProfile } = useUserProfileDialog()
const timeAgo = useTimeAgo(computed(() => props.date ?? ''))

const roleBadge = computed(() => {
Expand All @@ -29,12 +30,18 @@ const roleBadge = computed(() => {

<template>
<div class="flex items-center gap-2">
<UAvatar
:src="avatarUrl"
:alt="login"
size="2xs"
/>
<span class="text-sm font-medium text-highlighted">{{ login }}</span>
<button
type="button"
class="inline-flex items-center gap-1.5 cursor-pointer hover:underline"
@click.stop="openProfile(login)"
>
<UAvatar
:src="avatarUrl"
:alt="login"
size="2xs"
/>
<span class="text-sm font-medium text-highlighted">{{ login }}</span>
</button>
<UTooltip
v-if="roleBadge"
:text="roleBadge.description"
Expand Down
24 changes: 24 additions & 0 deletions app/components/user/UserChip.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
defineProps<{
login: string
avatarUrl?: string
size?: '3xs' | '2xs' | 'xs'
}>()

const { open } = useUserProfileDialog()
</script>

<template>
<button
type="button"
class="inline-flex items-center gap-1.5 cursor-pointer hover:underline"
@click.stop="open(login)"
>
<UAvatar
:src="avatarUrl ?? `https://github.com/${login}.png?size=40`"
:alt="login"
:size="size ?? '3xs'"
/>
<span class="text-sm text-highlighted truncate">{{ login }}</span>
</button>
</template>
Loading
Loading