Audit follow-up to t-paliad-098. The global `.entity-table tbody tr` rule set `cursor: pointer` and a hover background on every row, but six tables across the admin and settings surfaces don't navigate on row click — actions live in inline buttons (admin-team, admin-event-types, admin-partner-units) or the rows are pure read-only summaries (admin audit log, CalDAV sync log). The cursor lied and the hover invite was empty. - Add `.entity-table--readonly` modifier in global.css that resets cursor and neutralises the hover background, including a dark-theme override since the existing `:root[data-theme="dark"] .entity-table tbody tr:hover` rule outranks the base modifier on specificity. - Apply the modifier to the six table instances that don't navigate. The eight tables that DO navigate (projects, deadlines, appointments, checklists templates+instances, project-detail's deadlines/appointments /checklists) already have row click handlers and keep the default clickable affordance.
157 lines
7.9 KiB
TypeScript
157 lines
7.9 KiB
TypeScript
import { h } from "./jsx";
|
|
import { Sidebar } from "./components/Sidebar";
|
|
import { BottomNav } from "./components/BottomNav";
|
|
import { Footer } from "./components/Footer";
|
|
import { PWAHead } from "./components/PWAHead";
|
|
|
|
export function renderAdminEventTypes(): string {
|
|
return "<!DOCTYPE html>" + (
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#BFF355" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<PWAHead />
|
|
<title data-i18n="admin.event_types.title">Event-Typen — Paliad</title>
|
|
<link rel="stylesheet" href="/assets/global.css" />
|
|
</head>
|
|
<body className="has-sidebar">
|
|
<Sidebar currentPath="/admin/event-types" />
|
|
<BottomNav currentPath="/admin/event-types" />
|
|
|
|
<main>
|
|
<section className="tool-page">
|
|
<div className="container">
|
|
<div className="tool-header">
|
|
<div>
|
|
<h1 data-i18n="admin.event_types.heading">Event-Typen</h1>
|
|
<p className="tool-subtitle" data-i18n="admin.event_types.subtitle">
|
|
Firmenweite Event-Typen moderieren: archivieren, zusammenführen, private Typen befördern.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="admin-team-controls">
|
|
<div className="glossar-search-wrap">
|
|
<svg className="glossar-search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<circle cx="11" cy="11" r="8" />
|
|
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
|
</svg>
|
|
<input
|
|
type="text"
|
|
id="aet-search"
|
|
className="glossar-search"
|
|
placeholder="Bezeichnung, Slug oder Author suchen..."
|
|
data-i18n-placeholder="admin.event_types.search.placeholder"
|
|
autocomplete="off"
|
|
/>
|
|
<span className="glossar-count" id="aet-count" />
|
|
</div>
|
|
<label className="admin-team-multi-opt">
|
|
<input type="checkbox" id="aet-show-archived" />
|
|
<span data-i18n="admin.event_types.show_archived">Archivierte anzeigen</span>
|
|
</label>
|
|
</div>
|
|
|
|
<div className="admin-team-actions" id="aet-bulk-actions" style="display:none">
|
|
<span id="aet-bulk-count" className="admin-team-muted" />
|
|
<button className="btn-primary" id="aet-bulk-archive" type="button" data-i18n="admin.event_types.action.archive_selected">
|
|
Ausgewählte archivieren
|
|
</button>
|
|
<button className="btn-primary" id="aet-bulk-merge" type="button" data-i18n="admin.event_types.action.merge_selected">
|
|
Zusammenführen…
|
|
</button>
|
|
</div>
|
|
|
|
<div id="aet-feedback" className="form-msg" style="display:none" />
|
|
|
|
<h3 className="section-heading" data-i18n="admin.event_types.section.firm_wide">Firmenweite Typen</h3>
|
|
|
|
<div className="entity-table-wrap admin-team-table-wrap">
|
|
<table className="entity-table entity-table--readonly admin-team-table">
|
|
<thead>
|
|
<tr>
|
|
<th className="aet-col-check" />
|
|
<th data-i18n="admin.event_types.col.label">Bezeichnung</th>
|
|
<th data-i18n="admin.event_types.col.category">Kategorie</th>
|
|
<th data-i18n="admin.event_types.col.jurisdiction">Jurisdiktion</th>
|
|
<th data-i18n="admin.event_types.col.author">Author</th>
|
|
<th data-i18n="admin.event_types.col.created">Erstellt</th>
|
|
<th data-i18n="admin.event_types.col.usage">Verwendung</th>
|
|
<th data-i18n="admin.event_types.col.actions">Aktionen</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="aet-tbody">
|
|
<tr><td colspan={8} className="admin-team-loading" data-i18n="admin.event_types.loading">Lade...</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div className="entity-empty" id="aet-empty" style="display:none">
|
|
<p data-i18n="admin.event_types.empty">Keine Treffer.</p>
|
|
</div>
|
|
|
|
<h3 className="section-heading" data-i18n="admin.event_types.section.private_pending">
|
|
Private Typen (zur Beförderung)
|
|
</h3>
|
|
<p className="tool-subtitle" data-i18n="admin.event_types.section.private_pending.hint">
|
|
Private Typen anderer Kolleg:innen, sortiert nach Häufigkeit. Befördern macht den Typ firmenweit sichtbar.
|
|
</p>
|
|
|
|
<div className="entity-table-wrap admin-team-table-wrap">
|
|
<table className="entity-table entity-table--readonly admin-team-table">
|
|
<thead>
|
|
<tr>
|
|
<th data-i18n="admin.event_types.col.label">Bezeichnung</th>
|
|
<th data-i18n="admin.event_types.col.category">Kategorie</th>
|
|
<th data-i18n="admin.event_types.col.jurisdiction">Jurisdiktion</th>
|
|
<th data-i18n="admin.event_types.col.author">Author</th>
|
|
<th data-i18n="admin.event_types.col.usage">Verwendung</th>
|
|
<th data-i18n="admin.event_types.col.actions">Aktionen</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="aet-private-tbody">
|
|
<tr><td colspan={6} className="admin-team-loading" data-i18n="admin.event_types.loading">Lade...</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div className="entity-empty" id="aet-private-empty" style="display:none">
|
|
<p data-i18n="admin.event_types.private.empty">Keine privaten Typen.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
{/* Merge modal — list of selected types as candidates, admin picks one
|
|
as winner. Confirms with usage count, then POST /merge atomically
|
|
redirects junction rows + archives losers. */}
|
|
<div className="modal-overlay" id="aet-merge-modal" style="display:none">
|
|
<div className="modal-card">
|
|
<div className="modal-header">
|
|
<h2 data-i18n="admin.event_types.merge.title">Typen zusammenführen</h2>
|
|
<button className="modal-close" id="aet-merge-close" type="button" aria-label="Close">×</button>
|
|
</div>
|
|
<p data-i18n="admin.event_types.merge.body" className="invite-modal-body">
|
|
Wählen Sie den Gewinner-Typ. Die Junction-Einträge der Verlierer werden auf den Gewinner umgeleitet, anschließend werden die Verlierer archiviert.
|
|
</p>
|
|
<form id="aet-merge-form" className="entity-form" autocomplete="off">
|
|
<div id="aet-merge-options" className="aet-merge-options" />
|
|
<p className="form-msg" id="aet-merge-msg" />
|
|
<div className="form-actions">
|
|
<button type="button" className="btn-cancel" id="aet-merge-cancel" data-i18n="common.cancel">Abbrechen</button>
|
|
<button type="submit" className="btn-primary" id="aet-merge-submit" data-i18n="admin.event_types.merge.submit">Zusammenführen</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<Footer />
|
|
<script src="/assets/admin-event-types.js"></script>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|