Compare commits
2 Commits
231a7b0c36
...
6983609c7b
| Author | SHA1 | Date | |
|---|---|---|---|
| 6983609c7b | |||
| 11bc96dff1 |
@ -150,6 +150,6 @@ Lưu vào `docs/changelog/deps-audit-{YYYY-MM-DD}.md` nếu có action.
|
||||
|
||||
## Related
|
||||
|
||||
- `docs/gotchas.md` — 64 bẫy package compat / CI / IIS / Identity / per-NV refactor / SQLite tie-break đã gặp
|
||||
- `docs/gotchas.md` — 65 bẫy package compat / CI / IIS / Identity / per-NV refactor / SQLite tie-break đã gặp
|
||||
- `docs/changelog/migration-todos.md` Phase 5.1 — checklist deps scan CI
|
||||
- `SolutionErp.slnx` + `global.json` — .NET version pin
|
||||
|
||||
@ -63,7 +63,7 @@ Kiến trúc: **.NET 10 Clean Architecture + 2 React FE (admin + user) + SQL Ser
|
||||
| Identity (User/Role/Permission/MenuItem) | `Domain/Identity/` | 1, 3, 11 | Feature-complete (30 demo user — 16 sample + 14 Solutions thật) |
|
||||
| Forms (Template + Clause) | `Domain/Forms/` | 4 | Feature-complete |
|
||||
| Notifications | `Domain/Notifications/` | 6 | In-app + SignalR OK, email SMTP TODO |
|
||||
| **Tests** | `tests/SolutionErp.{Domain,Infrastructure}.Tests/` | — | **263 test pass** (45 Domain + 218 Infra) — CI gate + path filter docs-only skip |
|
||||
| **Tests** | `tests/SolutionErp.{Domain,Infrastructure}.Tests/` | — | **286 test pass** (45 Domain + 241 Infra) — CI gate + path filter docs-only skip |
|
||||
|
||||
### Commit convention
|
||||
|
||||
|
||||
@ -650,14 +650,18 @@ function EmployeeDetailTabs({ detail, onDelete }: { detail: EmployeeDetail; onDe
|
||||
{initials(detail.fullName)}
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<h2 className="truncate text-lg font-bold leading-tight text-white">{detail.fullName ?? '—'}</h2>
|
||||
<div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-white/85">
|
||||
<span className="font-mono">{detail.employeeCode}</span>
|
||||
{detail.departmentName && (<><span className="opacity-50">•</span><span className="truncate">{detail.departmentName}</span></>)}
|
||||
{detail.workLocation && (<><span className="opacity-50">•</span><span className="truncate">{detail.workLocation}</span></>)}
|
||||
<h2 className="truncate text-xl font-extrabold leading-tight text-white drop-shadow-sm">{detail.fullName ?? '—'}</h2>
|
||||
<div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-[13px] font-medium text-white">
|
||||
<span className="font-mono font-semibold tracking-tight">{detail.employeeCode}</span>
|
||||
{detail.departmentName && (<><span className="text-white/55">•</span><span className="truncate">{detail.departmentName}</span></>)}
|
||||
{detail.workLocation && (<><span className="text-white/55">•</span><span className="truncate">{detail.workLocation}</span></>)}
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<span className="inline-flex items-center rounded-full bg-white/20 px-2 py-0.5 text-[11px] font-medium text-white ring-1 ring-white/25">
|
||||
<span className={cn(
|
||||
'inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-bold shadow-sm ring-1 ring-black/5',
|
||||
EmployeeStatusColor[detail.employeeStatus],
|
||||
)}>
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-current opacity-70" />
|
||||
{EmployeeStatusLabel[detail.employeeStatus]}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -650,14 +650,18 @@ function EmployeeDetailTabs({ detail, onDelete }: { detail: EmployeeDetail; onDe
|
||||
{initials(detail.fullName)}
|
||||
</span>
|
||||
<div className="min-w-0">
|
||||
<h2 className="truncate text-lg font-bold leading-tight text-white">{detail.fullName ?? '—'}</h2>
|
||||
<div className="mt-1 flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-white/85">
|
||||
<span className="font-mono">{detail.employeeCode}</span>
|
||||
{detail.departmentName && (<><span className="opacity-50">•</span><span className="truncate">{detail.departmentName}</span></>)}
|
||||
{detail.workLocation && (<><span className="opacity-50">•</span><span className="truncate">{detail.workLocation}</span></>)}
|
||||
<h2 className="truncate text-xl font-extrabold leading-tight text-white drop-shadow-sm">{detail.fullName ?? '—'}</h2>
|
||||
<div className="mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-[13px] font-medium text-white">
|
||||
<span className="font-mono font-semibold tracking-tight">{detail.employeeCode}</span>
|
||||
{detail.departmentName && (<><span className="text-white/55">•</span><span className="truncate">{detail.departmentName}</span></>)}
|
||||
{detail.workLocation && (<><span className="text-white/55">•</span><span className="truncate">{detail.workLocation}</span></>)}
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<span className="inline-flex items-center rounded-full bg-white/20 px-2 py-0.5 text-[11px] font-medium text-white ring-1 ring-white/25">
|
||||
<span className={cn(
|
||||
'inline-flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-bold shadow-sm ring-1 ring-black/5',
|
||||
EmployeeStatusColor[detail.employeeStatus],
|
||||
)}>
|
||||
<span className="h-1.5 w-1.5 rounded-full bg-current opacity-70" />
|
||||
{EmployeeStatusLabel[detail.employeeStatus]}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user