Files
tabler/shared/components/cards/UsersList.astro
codecalm f27c70ad38 Fix Prettier formatting regression and Astro type-check errors
`Render Modal as real markup` (#2742) reformatted ~140 files back to
tabs/semicolons, breaking the Prettier config added by the Astro
quality gates (#2749). Re-run prettier --write to restore it, and fix
the type errors it had been masking: HTMLElement casts and `this`
typing in ChangePasswordModalContent/ConfirmDeleteModalContent
scripts, plain-JS syntax in the inline-injected progress.astro script,
narrowed prop unions in Button/Check/Spinner, nullable icon svg casts
in Icons/Rating, and a duplicate firstLetters/invalid `placeholder`
attribute in Select.astro. Also fix shared/vitest.config.mts's stale
`astro/lib/**/*.test.ts` include glob left over from the shared source
restructure, which made `pnpm test` report zero test files.
2026-08-03 01:26:19 +02:00

98 lines
2.9 KiB
Plaintext

---
import Avatar from '@ui/Avatar.astro'
import Icon from '@ui/Icon.astro'
import ListGroup from '@ui/ListGroup.astro'
import ListGroupItem from '@ui/ListGroupItem.astro'
import CardTitle from '@ui/CardTitle.astro'
import people from '@data/people.json'
import commits from '@data/commits.json'
import { randomNumber } from '@shared/lib/pseudo-random'
interface Person {
full_name?: string
photo?: string
last_name?: string
[key: string]: unknown
}
interface Props {
limit?: number
offset?: number
hoverable?: boolean
checkbox?: boolean
/** checked-ids — 1-based indices, e.g. [2, 5, 8] */
checkedIds?: number[]
title?: string
class?: string
/**
* Inert. The lists.html Contacts card passes `hover=true`, but
* users-list.html never reads it — only `hoverable` toggles the star column.
* Declared for call-site compatibility.
*/
hover?: boolean
}
const { limit = 8, offset = 0, hoverable = false, checkbox, checkedIds, title = 'Last commits', class: className } = Astro.props
const colors = ['green', 'red', 'yellow', 'x', 'x']
const commitList = commits as { description: string }[]
const rows = (people as Person[]).slice(offset, offset + limit).map((person, idx) => {
const index = idx + 1 // forloop.index (1-based)
const color = colors[randomNumber(index + 5, 0, colors.length - 1)]
const checked = checkedIds?.includes(index) ?? false
const i = index + offset
return {
person,
color,
checked,
description: commitList[i]?.description,
starColor: checked ? 'text-yellow' : 'text-secondary',
}
})
---
<div class={`card${className ? ` ${className}` : ''}`}>
<div class="card-header">
<CardTitle>{title}</CardTitle>
</div>
<ListGroup flush hoverable={hoverable}>
{
rows.map((row) => (
<ListGroupItem active={row.checked}>
<div class="row align-items-center">
{checkbox ? (
<div class="col-auto">
<input type="checkbox" class="form-check-input" checked={row.checked} />
</div>
) : (
<div class="col-auto">
<span class={`badge${row.color !== 'x' ? ` bg-${row.color}` : ''}`} />
</div>
)}
<div class="col-auto">
<a href="#">
<Avatar person={row.person} />
</a>
</div>
<div class="col text-truncate">
<a href="#" class="text-reset d-block">
{row.person.full_name}
</a>
<div class="d-block text-secondary text-truncate mt-n1">{row.description}</div>
</div>
{hoverable && (
<div class="col-auto">
<a href="#" class={`list-group-item-actions${row.checked ? ' show' : ''}`}>
<Icon name="star" class={row.starColor} />
</a>
</div>
)}
</div>
</ListGroupItem>
))
}
</ListGroup>
</div>