refactor(frontend): restore profile timeline emphasis
This commit is contained in:
parent
caf6eebc0f
commit
d0b42cdaa5
@ -153,24 +153,22 @@ export default function ProfilePage() {
|
||||
bottomPanel={<ProfileContactsPanel rows={contactRows} />}
|
||||
/>
|
||||
|
||||
<div className="grid gap-4 xl:grid-cols-[minmax(0,1.1fr)_minmax(0,0.9fr)] xl:items-start">
|
||||
<ProfileSkillsCard
|
||||
inputValue={skillName}
|
||||
onInputChange={onInputSkillName}
|
||||
onSubmit={() => void handleAddSkill()}
|
||||
submitDisabled={!skillName.trim() || skillsSaving}
|
||||
inputDisabled={skillsSaving}
|
||||
availableSkills={availableSkills}
|
||||
skills={profileSkills}
|
||||
error={skillsError}
|
||||
loading={skillsLoading}
|
||||
onRemoveSkill={(skillId) => void handleRemoveSkill(skillId)}
|
||||
removeDisabled={skillsSaving}
|
||||
emptyText="Навыки пока не указаны"
|
||||
/>
|
||||
<ProfileSkillsCard
|
||||
inputValue={skillName}
|
||||
onInputChange={onInputSkillName}
|
||||
onSubmit={() => void handleAddSkill()}
|
||||
submitDisabled={!skillName.trim() || skillsSaving}
|
||||
inputDisabled={skillsSaving}
|
||||
availableSkills={availableSkills}
|
||||
skills={profileSkills}
|
||||
error={skillsError}
|
||||
loading={skillsLoading}
|
||||
onRemoveSkill={(skillId) => void handleRemoveSkill(skillId)}
|
||||
removeDisabled={skillsSaving}
|
||||
emptyText="Навыки пока не указаны"
|
||||
/>
|
||||
|
||||
<ProfileInfoCard items={infoItems} />
|
||||
</div>
|
||||
<ProfileInfoCard items={infoItems} />
|
||||
|
||||
<EmployeeActionsTimeline
|
||||
actionLoading={null}
|
||||
|
||||
@ -48,9 +48,14 @@ export default function EmployeeActionsTimeline({
|
||||
expandedCommentLength = truncateCommentLength,
|
||||
}: EmployeeActionsTimelineProps) {
|
||||
const [showAll, setShowAll] = useState(false);
|
||||
const canCollapse = Boolean(initialVisibleCount && sortedActions.length > initialVisibleCount);
|
||||
const canCollapse = Boolean(
|
||||
initialVisibleCount && sortedActions.length > initialVisibleCount,
|
||||
);
|
||||
const visibleActions = useMemo(
|
||||
() => (canCollapse && !showAll ? sortedActions.slice(0, initialVisibleCount) : sortedActions),
|
||||
() =>
|
||||
canCollapse && !showAll
|
||||
? sortedActions.slice(0, initialVisibleCount)
|
||||
: sortedActions,
|
||||
[canCollapse, initialVisibleCount, showAll, sortedActions],
|
||||
);
|
||||
|
||||
@ -60,16 +65,9 @@ export default function EmployeeActionsTimeline({
|
||||
|
||||
return (
|
||||
<section className="app-surface rounded-2xl p-5">
|
||||
<div className="mb-4 flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div>
|
||||
<h2 className="app-card-caption">Кадровые события</h2>
|
||||
{!showAll && canCollapse ? (
|
||||
<p className="app-text-muted mt-2 text-sm">
|
||||
Последние {visibleActions.length} из {sortedActions.length}
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<div className="mb-4 flex items-start justify-between gap-4">
|
||||
<h2 className="app-card-caption">Кадровые события</h2>
|
||||
<div className="flex items-center gap-2">
|
||||
{showCountLabel ? (
|
||||
<span className="app-text-muted text-sm">
|
||||
{sortedActions.length}{" "}
|
||||
@ -101,6 +99,12 @@ export default function EmployeeActionsTimeline({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{!showAll && canCollapse ? (
|
||||
<p className="app-text-muted mb-3 text-sm">
|
||||
Последние {visibleActions.length} из {sortedActions.length}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
<div className="space-y-3">
|
||||
{visibleActions.map((action) => {
|
||||
const isCurrent = latestActionId === action.id;
|
||||
@ -111,27 +115,26 @@ export default function EmployeeActionsTimeline({
|
||||
: action.comment;
|
||||
|
||||
return (
|
||||
<div key={action.id} className="relative pl-6">
|
||||
<div key={action.id} className="relative pl-5">
|
||||
<span
|
||||
className="absolute bottom-0 left-[7px] top-0 w-px"
|
||||
className="absolute bottom-0 left-1.5 top-0 w-px"
|
||||
style={{ backgroundColor: tone.lineColor }}
|
||||
/>
|
||||
<span
|
||||
className={[
|
||||
"absolute left-0 top-3 h-[14px] w-[14px] rounded-full border border-[var(--surface-primary)]",
|
||||
isCurrent ? "shadow-[0_0_0_4px_var(--surface-primary)]" : "",
|
||||
].join(" ")}
|
||||
style={{ backgroundColor: tone.lineColor }}
|
||||
/>
|
||||
<div className="app-surface-muted rounded-xl px-4 py-3.5">
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
|
||||
{isCurrent ? (
|
||||
<span
|
||||
className="absolute left-0 top-2 h-3.5 w-3.5 rounded-full border-4 border-[var(--surface-primary)]"
|
||||
style={{ backgroundColor: tone.lineColor }}
|
||||
/>
|
||||
) : null}
|
||||
<div className="app-surface-muted rounded-xl px-4 py-3">
|
||||
<div className="flex flex-col gap-2 md:flex-row md:items-start md:justify-between">
|
||||
<div className="min-w-0">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className={`app-status-pill ${tone.badgeClass}`}>
|
||||
{action.action_display || action.action}
|
||||
</span>
|
||||
{isCurrent ? (
|
||||
<span className="app-pill inline-flex rounded-full px-2 py-0.5 text-xs font-medium">
|
||||
<span className="app-text-muted text-xs font-medium">
|
||||
текущий
|
||||
</span>
|
||||
) : null}
|
||||
@ -142,8 +145,8 @@ export default function EmployeeActionsTimeline({
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-2 self-start">
|
||||
<time className="app-text-muted text-sm">
|
||||
<div className="flex shrink-0 items-start gap-2">
|
||||
<time className="app-text-muted pt-1 text-sm">
|
||||
{formatActionDate(action.date)}
|
||||
</time>
|
||||
{canManageActions && onEditAction && onDeleteAction ? (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user