Uebergabe der Dev-Interim-Screens aus HiveGrid-Cloud an den Wireframes-Vault. INDEX + 7 Domaenen-Seiten (CRM, Leads, HR, Files/Tasks, Audit/Notifications, Integrations, Auth/RBAC) mit je Screen: D-*-Ziel, Archetyp, Route, VM, benoetigte ~/ui-Elemente, Actions, States. Layout bleibt Davids freie Hand. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
22 KiB
22 KiB
P17 · HR-Hub (AK-P17a/b → D-HR)
Interim-UI-Referenz (AD-28) für den HR-Hub. Alle Screens rein präsentational (VM als Prop, Route besitzt Loader/Fetcher/Actions). Layout = Davids freie Hand — unten nur ELEMENTE/DATEN/ACTIONS.
~/uiist das gesetzte Baukasten-Inventar;data-ui-id-Marker existieren für Interim-Snapshots. Route-URLs: App-Host, Ordnerroutes/app.$tenant/→/{tenant}/hr/….
HrHubPage · D-HR „HR-Hub-Start" (A1/A6)
- Interim-Screen:
apps/web/app/components/screens/hr/HrHubPage.tsx - Route(n):
/{tenant}/hr(routes/app.$tenant/hr._index.tsx) - Daten (VM): kein
@hivegrid-VM — lokale PropsmoduleActive: boolean,links: HrHubLink[]({ labelKey, href }); Loader gated Connector+Permission und liefert die Quick-Link-Liste - Benötigte UI-Elemente (KEIN Layout): Card, EmptyState · Icons: FeatherArrowRight, FeatherLock
- Interaktionen (Actions): keine Callbacks — Links sind
<a href>(Navigations-Kacheln) - States: Locked (
!moduleActive→ EmptyState mit Lock) / Empty (leere Link-Liste rendert leere Grid) / Permission-Denied via Loader-Gate (404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte:
- Neue UI/UX-Entscheidungen (Hub-Widgets Ankündigungen/Pflichten/Geburtstage kommen laut Header erst als Folge-Nachzug):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrDirectoryPage · D-HR „MA-Verzeichnis" (A2)
- Interim-Screen:
apps/web/app/components/screens/hr/HrDirectoryPage.tsx - Route(n):
/{tenant}/hr/directory(routes/app.$tenant/hr.directory._index.tsx) - Daten (VM):
HrDirectoryVM—packages/view-models/src/hr/hr-directory.vm.ts(nur nicht-sensible Anzeigefelder; Notfallkontakt NUR im Detail) - Benötigte UI-Elemente (KEIN Layout): Avatar, EmptyState, IconButton, Table · Icons: FeatherMail
- Interaktionen (Actions): keine Action-Callbacks — Name-Link → Detail,
mailto:-IconButton - States: Empty (
rows.length===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte:
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrDirectoryDetailPage · D-HR „MA-Detail" (A3)
- Interim-Screen:
apps/web/app/components/screens/hr/HrDirectoryDetailPage.tsx - Route(n):
/{tenant}/hr/directory/{userId}(routes/app.$tenant/hr.directory.$userId.tsx) - Daten (VM): kein VM-Typ-Import — flache Props (
name,email,position,team,isSelf,canRevealEmergency,canEditEmergency,hasEmergencyContact,revealedContact,revealing,saving,savingEmergency); Domain inhr-directory.vm.ts - Benötigte UI-Elemente (KEIN Layout): Breadcrumbs, Button, Card, Dialog, TextInput · Icons: —
- Interaktionen (Actions):
onSaveProfile({position,team}),onRevealEmergency(),onSetEmergency({name,phone,relation}) - States: Self-Edit vs. Read-only (
isSelf) / Emergency: kein Kontakt / gespeichert-nicht-enthüllbar / enthüllt / Reveal-Button / Loading viarevealing/saving/savingEmergency/ Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (On-Demand-Reveal Notfallkontakt, serverseitig auditiert):
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrLeavePage · D-HR „Urlaub" (A2 + A4/A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrLeavePage.tsx - Route(n):
/{tenant}/hr/leave(routes/app.$tenant/hr.leave._index.tsx), URL-Tabs?tab=own|approvals|team - Daten (VM):
HrLeaveOwnVM,HrLeaveApproverVM,HrVacationRequestKind—packages/view-models/src/hr/hr-leave.vm.ts; plus lokalerHrLeaveTeamAbsence - Benötigte UI-Elemente (KEIN Layout): Alert, BadgeFeedback, Button, Card, Dialog, EmptyState, Select, Tabs, TextArea, TextInput,
DateField(tasks) · Icons: FeatherPlus - Interaktionen (Actions):
onSubmit({requestKind,approverUserId,startDate,endDate,note}),onWithdraw(requestId),onReply(requestId,reply),onApprove(requestId),onReject(requestId),onClarify(requestId,question) - States: Empty je Tab (own/approvals/team → EmptyState) / Loading (
status!=="ready"→ null) / Konflikt-Warnung (Alert beihasConflict) / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Overlap-Konflikt als Inline-Warnung):
- Neue UI/UX-Entscheidungen (Approver-Auswahl aktuell freies TextInput = userId):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrSickPage · D-HR „Krank" (A2 + A4)
- Interim-Screen:
apps/web/app/components/screens/hr/HrSickPage.tsx - Route(n):
/{tenant}/hr/sick(routes/app.$tenant/hr.sick._index.tsx), Tabsown|office - Daten (VM):
HrSickLeaveOwnVM,HrSickLeaveOfficeVM,HrSickLeaveRow—packages/view-models/src/hr/hr-sickleave.vm.ts - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, Dialog, EmptyState, Tabs, TextInput,
DateField(tasks) · Icons: FeatherPlus - Interaktionen (Actions):
onReport({startDate,expectedReturnDate}),onReportFor({employeeUserId,startDate}),onAttach(reportId,certificateFileId),onRevealCertificate(reportId),onClose(reportId,returnDate) - States: Empty je Tab (own/office → EmptyState) / AU-Zertifikat nie gerendert, nur Reveal-Action / Loading (Rows via
?? []) / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Zertifikat sensibel, reveal-on-demand):
- Neue UI/UX-Entscheidungen (Attach = File-ID-TextInput; echte Datei-Auswahl offen):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrRequestsPage · D-HR „Anträge" (A2 + A4/A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrRequestsPage.tsx - Route(n):
/{tenant}/hr/requests(routes/app.$tenant/hr.requests._index.tsx), Tabsown|approvals - Daten (VM):
HrRequestOwnVM,HrRequestApproverVM,HrRequestKind—packages/view-models/src/hr/hr-request.vm.ts; plus lokalerHrRequestTemplateOption - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, Dialog, EmptyState, Select, Tabs, TextArea, TextInput · Icons: FeatherPlus
- Interaktionen (Actions):
onSubmit({templateId,requestKind,approverUserId,title,details}),onWithdraw(requestId),onApprove(requestId),onReject(requestId),onClarify(requestId,question) - States: Empty je Tab (own/approvals → EmptyState) / Loading (Rows via
?? []) / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (optionaler Vorlagen-Prefill):
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrPayslipsPage · D-HR „Lohnabrechnungen" (A2)
- Interim-Screen:
apps/web/app/components/screens/hr/HrPayslipsPage.tsx - Route(n):
/{tenant}/hr/payslips(routes/app.$tenant/hr.payslips._index.tsx) - Daten (VM):
HrPayslipOwnVM—packages/view-models/src/hr/hr-payslip.vm.ts - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, EmptyState, Table · Icons: FeatherExternalLink
- Interaktionen (Actions):
onOpen(payslipId)(Öffnen serverseitig auditiert, Route öffnet File) - States: Empty (
rows.length===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Unread-Badge / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte:
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrMyDocumentsPage · D-HR „Eigene Dokumente" (A2)
- Interim-Screen:
apps/web/app/components/screens/hr/HrMyDocumentsPage.tsx - Route(n):
/{tenant}/hr/my-documents(routes/app.$tenant/hr.my-documents.tsx) - Daten (VM):
HrDocumentListVM,HrDocumentKind—packages/view-models/src/hr/hr-document.vm.ts; plus injizierterupload: HrDocumentUploadState(idle/uploading/done/error) - Benötigte UI-Elemente (KEIN Layout): Alert, BadgeFeedback, Button, Dialog, EmptyState, Select, Table, TextInput; native
input[type=date]+input[type=file](bewusste Ausnahme) · Icons: FeatherUpload - Interaktionen (Actions):
onArchive(documentId),onUpload({file,title,documentKind,validUntilIso}),onResetUpload() - States: Empty (
rows.length===0→ EmptyState) / No-Results (Kind-Filter leer → EmptyStateno-results) / Loading (status!=="ready"→ leeres Div) / Upload uploading/error (Alert) / Read-only-Badge (Office-Docs) / Expired-Badge / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Kind-Filter client-seitig, Office-Docs read-only):
- Neue UI/UX-Entscheidungen (Upload-Progress-Darstellung):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrAnnouncementsFeedPage · D-HR „Ankündigungen" (A2)
- Interim-Screen:
apps/web/app/components/screens/hr/HrAnnouncementsFeedPage.tsx - Route(n):
/{tenant}/hr/announcements(routes/app.$tenant/hr.announcements._index.tsx), Filter?unread=1 - Daten (VM):
HrAnnouncementFeedVM—packages/view-models/src/hr/hr-announcement.vm.ts(pinned first) - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Card, EmptyState, LinkButton, Tabs · Icons: FeatherPin
- Interaktionen (Actions): keine Callbacks — Zeilen-Link → Detail, „Verwalten"-Link (
manageHref, beicanManage) - States: Empty (
rows.length===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Ack-Required-Badge / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (pinned zuerst, Unread-Filter):
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrAnnouncementDetailPage · D-HR „Ankündigung Detail" (A3)
- Interim-Screen:
apps/web/app/components/screens/hr/HrAnnouncementDetailPage.tsx - Route(n):
/{tenant}/hr/announcements/{id}(routes/app.$tenant/hr.announcements.$id.tsx) - Daten (VM):
HrAnnouncementDetailVM—packages/view-models/src/hr/hr-announcement.vm.ts(Markdown-Body, Reaktionen, Kommentare 1 Ebene, Read-Receipts) - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, Table, TextInput · Icons: — (Emoji-Reaktionen 👍❤️🎉👀 als Literale)
- Interaktionen (Actions):
onAck(),onReact(reaction),onComment(body) - States: Loading (
status!=="ready"→ leeres Div) / Kommentare-Empty (commentEmptyKey) / Ack-Zustand acknowledged vs. Button / Read-Receipt-Tabelle nur beicanManage/ Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Markdown wird aktuell
whitespace-pre-wraproh gerendert): - Neue UI/UX-Entscheidungen (Reaktions-Set fix vier Emojis):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
- Überschriebene/geänderte Spec-Punkte (Markdown wird aktuell
HrLocationsPage · D-HR „Standorte" (A2 + A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrLocationsPage.tsx - Route(n):
/{tenant}/hr/locations(routes/app.$tenant/hr.locations._index.tsx) - Daten (VM):
HrLocationListVM—packages/view-models/src/hr/hr-location.vm.ts - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Checkbox, Dialog, EmptyState, Table, TextInput · Icons: FeatherPlus
- Interaktionen (Actions):
onCreate({name,city,isDefault}),onSetDefault(locationId),onArchive(locationId) - States: Empty (
rows.length===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Default-Badge / Aktionen nur beicanManage/ Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte:
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrPasswordSafeListPage · D-HR „Passwort-Safe" (A2 + A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrPasswordSafeListPage.tsx - Route(n):
/{tenant}/hr/password-safe(routes/app.$tenant/hr.password-safe._index.tsx) - Daten (VM):
VaultListVM—packages/view-models/src/hr/hr-password-safe.vm.ts(nur zugriffsberechtigte Vaults, keine Secrets) - Benötigte UI-Elemente (KEIN Layout): Button, Card, Dialog, EmptyState, TextInput · Icons: FeatherPlus
- Interaktionen (Actions):
onCreateVault({name,description}) - States: Empty (
rows.length===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Create nur beicanCreate/ Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte:
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrVaultDetailPage · D-HR „Passwort-Safe Detail" (A3 + reveal)
- Interim-Screen:
apps/web/app/components/screens/hr/HrVaultDetailPage.tsx - Route(n):
/{tenant}/hr/password-safe/{vaultId}(routes/app.$tenant/hr.password-safe.$vaultId._index.tsx); Action-only:…$vaultId.reveal.tsx,…$vaultId.export.tsx - Daten (VM):
VaultDetailVM,EntryRow—packages/view-models/src/hr/hr-password-safe.vm.ts(nurhasUsername/hasPassword/hasNotes-Flags,copyAutoClearMs) - Benötigte UI-Elemente (KEIN Layout): Breadcrumbs, Button, Card, CopyToClipboardButton, Dialog, EmptyState, LinkButton, Select, Tag_Label, TextInput · Icons: FeatherPlus
- Interaktionen (Actions):
onReveal(entryId,field): Promise<string|null>,onCreateEntry({title,url,username,password,notes}),onArchiveEntry(entryId),onGrantAccess({targetUserId,permissionLevel}) - States: Empty (
rows.length===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Secret pro Feld reveal-on-demand → copy → Clipboard-Wipe nach 30s (DoD #3) / Aktionen gated viacanWrite/canManageAccess/ Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (SECURITY: Werte nur per audited reveal, Clipboard-Auto-Clear):
- Neue UI/UX-Entscheidungen (Copy-Cleared-Hinweis, Zugriff via userId-TextInput):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrSurveysListPage · D-HR „Umfragen" (A2 + A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrSurveysListPage.tsx - Route(n):
/{tenant}/hr/surveys(routes/app.$tenant/hr.surveys._index.tsx) - Daten (VM):
HrSurveyListVM—packages/view-models/src/hr/hr-survey.vm.ts - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, Checkbox, Dialog, EmptyState, LinkButton, Select, TextInput · Icons: FeatherPlus
- Interaktionen (Actions):
onCreate({title,description,isAnonymous,resultVisibility}),onSetStatus(surveyId,"open"|"close"),onArchive(surveyId) - States: Empty (
rows.length===0→ EmptyState) / Loading (Rows via?? []) / Status-/Anonymous-Badges / Teilnehmen/Ergebnisse/Edit gated (hasSubmitted,canViewResults,canManage) / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte:
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrSurveyParticipationPage · D-HR „Umfrage Teilnahme" (A3/A4)
- Interim-Screen:
apps/web/app/components/screens/hr/HrSurveyParticipationPage.tsx - Route(n):
/{tenant}/hr/surveys/{id}(routes/app.$tenant/hr.surveys.$id.tsx) - Daten (VM):
HrSurveyParticipationVM,HrSurveyItem,HrSurveyItemType—packages/view-models/src/hr/hr-survey.vm.ts - Benötigte UI-Elemente (KEIN Layout): Alert, Button, Card, Checkbox, Dialog, Select, TextInput; native
input[type=date](sanktionierte Ausnahme) · Icons: FeatherPlus - Interaktionen (Actions):
onSubmit(answers: Record<string,string>),onAddItem({itemType,prompt,options,required}),onRemoveItem(itemId) - States: Loading (
status!=="ready"→ leeres Div) / Anonymous-Hinweis (Alert) / bereits abgegeben (Alert success) / offen → Formular / geschlossen (Alert neutral) / Item-Editor nur beicanManage/ Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Item-Typen text/rating_5/nps/choice/boolean/date):
- Neue UI/UX-Entscheidungen (Antwort-Feld-Rendering je Typ):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrSurveyResultsPage · D-HR „Umfrage Ergebnisse" (A3)
- Interim-Screen:
apps/web/app/components/screens/hr/HrSurveyResultsPage.tsx - Route(n):
/{tenant}/hr/surveys/{id}/results(routes/app.$tenant/hr.surveys.$id.results.tsx) - Daten (VM):
HrSurveyResultsVM—packages/view-models/src/hr/hr-survey.vm.ts(Verteilung + Durchschnitt + Freitext) - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Card, EmptyState, Progress · Icons: —
- Interaktionen (Actions): keine (read-only)
- States: Empty (
submissionCount===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Anonymous-Badge / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Interim nutzt Progress-Balken; „richer charts" = expliziter Nachzug lt. Header):
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrAdminAnnouncementsPage · D-HR „Ankündigungen verwalten" (A2 + A4/A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrAdminAnnouncementsPage.tsx - Route(n):
/{tenant}/hr/admin/announcements(routes/app.$tenant/hr.admin.announcements._index.tsx) - Daten (VM): kein
@hivegrid-VM — lokale Propsrows: AdminAnnouncementRow[],audiences: string[] - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, Checkbox, Dialog, EmptyState, Select, TextArea, TextInput,
DateField(tasks) · Icons: FeatherPin, FeatherPlus - Interaktionen (Actions):
onCreate({title,body,audienceKind,audienceRef,requiresAck,pinned,publishAt,expiresAt}),onArchive(announcementId) - States: Empty (
rows.length===0→ EmptyState) / Loading (—, Rows als Prop) / Ack-/Pin-/Audience-Badges / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Audience, Ack, Pin, Schedule/Expiry):
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrAdminPasswordSafePage · D-HR „Passwort-Safe-Verwaltung" (A2/A6)
- Interim-Screen:
apps/web/app/components/screens/hr/HrAdminPasswordSafePage.tsx - Route(n):
/{tenant}/hr/admin/password-safe(routes/app.$tenant/hr.admin.password-safe._index.tsx) - Daten (VM):
AdminVaultListVM—packages/view-models/src/hr/hr-password-safe.vm.ts(alle Tenant-Vaults, Entry-/Access-Counts, NIE Inhalte) - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, EmptyState, Table · Icons: —
- Interaktionen (Actions):
onArchiveVault(vaultId) - States: Empty (
rows.length===0→ EmptyState) / Loading (status!=="ready"→ leeres Div) / Active/Archived-Badge / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Oversight ohne Content-Zugriff):
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrAdminPayslipsPage · D-HR „Lohnabrechnungen verwalten" (A2 + A4)
- Interim-Screen:
apps/web/app/components/screens/hr/HrAdminPayslipsPage.tsx - Route(n):
/{tenant}/hr/admin/payslips(routes/app.$tenant/hr.admin.payslips._index.tsx) - Daten (VM): kein
@hivegrid-VM — lokale Propsrows: PayslipAdminRow[],preview: PayslipPreviewRow[](confidence hard/soft/none),period: {year,month} - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, EmptyState, Table, TextArea, TextInput · Icons: —
- Interaktionen (Actions):
onMatch({periodYear,periodMonth,files}),onConfirm({fileId,employeeUserId,periodYear,periodMonth}) - States: Empty (existing
rows.length===0→ EmptyState) / Preview-Block nur beipreview.length>0/ Loading (Props) / Confidence-Badges / Read/Unread-Badge / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Bulk-Auto-Match-Preview + Per-Row-Confirm):
- Neue UI/UX-Entscheidungen (Files-Input als Freitext-Hint, Assignee als userId-TextInput):
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrAdminRequestTemplatesPage · D-HR „Antragsvorlagen" (A2 + A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrAdminRequestTemplatesPage.tsx - Route(n):
/{tenant}/hr/admin/request-templates(routes/app.$tenant/hr.admin.request-templates._index.tsx) - Daten (VM):
HrRequestTemplateListVM,HrRequestKind—packages/view-models/src/hr/hr-request.vm.ts - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, Dialog, EmptyState, Select, TextInput · Icons: FeatherPlus
- Interaktionen (Actions):
onCreate({requestKind,defaultApproverUserId,title,description}),onToggle(templateId,isActive),onArchive(templateId) - States: Empty (
rows.length===0→ EmptyState) / Loading (Rows via?? []) / Inactive-Badge / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte:
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev:
HrAdminUploadRemindersPage · D-HR „Upload-Erinnerungen" (A2 + A5)
- Interim-Screen:
apps/web/app/components/screens/hr/HrAdminUploadRemindersPage.tsx - Route(n):
/{tenant}/hr/admin/upload-reminders(routes/app.$tenant/hr.admin.upload-reminders._index.tsx) - Daten (VM):
HrReminderListVM—packages/view-models/src/hr/hr-upload-reminder.vm.ts;HrReminderCadenceKindauspackages/view-models/src/hr/reminder-cadence.ts; plus PropsdocumentKinds,audiences - Benötigte UI-Elemente (KEIN Layout): BadgeFeedback, Button, Card, Checkbox, Dialog, EmptyState, Select, TextInput,
DateField(tasks) · Icons: FeatherPlus - Interaktionen (Actions):
onCreate({title,documentKind,cadenceKind,intervalMonths,audienceKind,dueAt,mandatory,escalate}),onSetStatus(reminderId,"active"|"paused"),onArchive(reminderId) - States: Empty (
rows.length===0→ EmptyState) / Loading (Rows via?? []) / Status-Badge active/paused / Permission-Denied (Loader/404) - Davids Delta (offen):
- Überschriebene/geänderte Spec-Punkte (Cadence once/yearly/every_n_months/on_expiry; Dispatch im Worker-Cron):
- Neue UI/UX-Entscheidungen:
- Subframe-Screen-Link(s):
- Offene Fragen an Dev: