mAi: #88 - Verfahrensablauf: column axis reframed to user-perspective
Replaces the misleading Proaktiv/Reaktiv column pair with a static
"Unsere Seite" / "Gericht" / "Gegnerseite" axis ("WE always on the
left", per m's t-paliad-257 ask). The side toggle now drives row
PLACEMENT into the ours/opponent buckets — the column labels stay
truthful regardless of which physical party occupies them.
Old framing lied half the time: Klägerseite is sometimes proactive
(filing the claim) and sometimes reactive (responding to a CCR),
so "Proaktiv (Klägerseite)" was wrong whenever the user's perspective
flipped. New axis is purely positional with semantic labels.
Changes:
- frontend/src/client/views/verfahrensablauf-core.ts:
• ColumnsRow fields proactive/reactive → ours/opponent.
• renderColumnsBody picks static "Unsere Seite" / "Gegnerseite"
labels — no more variant-by-side label keys.
• bucketDeadlinesIntoColumns routes the user's party into `ours`
when opts.side ∈ {"defendant"}; default (null) keeps the legacy
"we are claimant" fallback so claimant-on-left layout survives.
- verfahrensablauf-core.test.ts: rewritten expectations on the new
ours/opponent fields. Added two new tests pinning the WE-on-left
semantics and the side+appellant interaction (side=defendant +
appellant=claimant → "both" collapses into opponent).
- fristenrechner.ts: wires currentPerspective into renderColumnsBody
as `side` so the columns honour the chip-strip perspective.
Without this, a defendant-perspective user would see claimant
filings under the "Unsere Seite" header — the old code didn't
need the wire-up because the labels weren't perspective-aware.
- i18n.ts: replaces deadlines.col.proactive(.defendant) +
deadlines.col.reactive(.claimant) with deadlines.col.ours +
deadlines.col.opponent ("Unsere Seite"/"Client Side",
"Gegnerseite"/"Opponent Side"). Court key unchanged.
- i18n-keys.ts: regenerated key union.
- global.css: .fr-col-proactive/.fr-col-reactive renamed to
.fr-col-ours/.fr-col-opponent.
Out of scope (kept intact):
- Side and appellant URL-state plumbing.
- Appellant selector for Appeal-type proceedings (separate axis).
- Project-default side-from-our_side wiring — /tools/verfahrensablauf
has no project context, and /tools/fristenrechner already does this
via applyOurSidePredefine().
Build: bun run build clean (2794 keys), go build ./... clean.
Tests: 112 frontend tests pass (was 110, +2 new); all Go tests
cached green.
This commit is contained in:
@@ -429,8 +429,13 @@ function renderProcedureResults(data: DeadlineResponse) {
|
||||
<span class="timeline-trigger-date">${t("deadlines.trigger.label")}: ${formatDate(data.triggerDate)}</span>
|
||||
</div>`;
|
||||
|
||||
// Pass the chip-strip perspective through as `side` so the column
|
||||
// bucketer keeps the user's own party on the left (Unsere Seite) —
|
||||
// t-paliad-257: the old Proaktiv/Reaktiv labels lied when the user
|
||||
// was on the defendant side, the new labels demand we route the
|
||||
// user's party into the `ours` column.
|
||||
const bodyHtml = procedureView === "columns"
|
||||
? renderColumnsBody(data, { editable: true, showNotes })
|
||||
? renderColumnsBody(data, { editable: true, showNotes, side: currentPerspective })
|
||||
: renderTimelineBody(data, { showParty: true, editable: true, showNotes });
|
||||
|
||||
container.innerHTML = headerHtml + bodyHtml;
|
||||
|
||||
@@ -302,11 +302,9 @@ const translations: Record<Lang, Record<string, string>> = {
|
||||
"deadlines.view.timeline": "Zeitstrahl",
|
||||
"deadlines.view.columns": "Spalten",
|
||||
"deadlines.notes.show": "Hinweise anzeigen",
|
||||
"deadlines.col.proactive": "Proaktiv (Klägerseite)",
|
||||
"deadlines.col.proactive.defendant": "Proaktiv (Beklagtenseite)",
|
||||
"deadlines.col.ours": "Unsere Seite",
|
||||
"deadlines.col.court": "Gericht",
|
||||
"deadlines.col.reactive": "Reaktiv (Beklagtenseite)",
|
||||
"deadlines.col.reactive.claimant": "Reaktiv (Klägerseite)",
|
||||
"deadlines.col.opponent": "Gegnerseite",
|
||||
"deadlines.col.both": "Beide Parteien",
|
||||
// Trigger-event mode (PR-2 \u2014 youpc-parity)
|
||||
"deadlines.mode.procedure": "Verfahrensablauf",
|
||||
@@ -3268,11 +3266,9 @@ const translations: Record<Lang, Record<string, string>> = {
|
||||
"deadlines.view.timeline": "Timeline",
|
||||
"deadlines.view.columns": "Columns",
|
||||
"deadlines.notes.show": "Show details",
|
||||
"deadlines.col.proactive": "Proactive (Claimant side)",
|
||||
"deadlines.col.proactive.defendant": "Proactive (Defendant side)",
|
||||
"deadlines.col.ours": "Client Side",
|
||||
"deadlines.col.court": "Court",
|
||||
"deadlines.col.reactive": "Reactive (Defendant side)",
|
||||
"deadlines.col.reactive.claimant": "Reactive (Claimant side)",
|
||||
"deadlines.col.opponent": "Opponent Side",
|
||||
"deadlines.col.both": "Both parties",
|
||||
"deadlines.adjusted": "Adjusted",
|
||||
"deadlines.adjusted.reason": "weekend/holiday",
|
||||
|
||||
@@ -67,17 +67,20 @@ describe("deadlineCardHtml — editable=true emits click-to-edit attrs", () => {
|
||||
});
|
||||
});
|
||||
|
||||
// Pure column-routing behaviour pinned by m/paliad#81. Hits
|
||||
// bucketDeadlinesIntoColumns directly so the assertions stay in
|
||||
// pure-Node territory (renderColumnsBody goes through escHtml ->
|
||||
// Pure column-routing behaviour. Originally pinned by m/paliad#81
|
||||
// (side + appellant axes), re-framed by m/paliad#88: the column
|
||||
// axis is now "Unsere Seite vs Gegnerseite" ("WE always on the
|
||||
// left") instead of the misleading Proaktiv/Reaktiv pair.
|
||||
// Hits bucketDeadlinesIntoColumns directly so the assertions stay
|
||||
// in pure-Node territory (renderColumnsBody goes through escHtml ->
|
||||
// document.createElement which isn't available in plain bun test).
|
||||
//
|
||||
// Scenario fixture mirrors the UPC Appeal "both parties" case m
|
||||
// pasted into #81: every filing rule carries party='both' so the
|
||||
// legacy mirror path duplicates every row across proactive +
|
||||
// reactive. With ?appellant= set, the duplicate must collapse to a
|
||||
// single row in the appellant's column.
|
||||
describe("bucketDeadlinesIntoColumns — side+appellant column routing (m/paliad#81)", () => {
|
||||
// legacy mirror path duplicates every row across both columns.
|
||||
// With ?appellant= set, the duplicate must collapse to a single
|
||||
// row in the appellant's column.
|
||||
describe("bucketDeadlinesIntoColumns — side+appellant column routing (m/paliad#81, #88)", () => {
|
||||
const both = (name: string, due: string): CalculatedDeadline => ({
|
||||
code: name,
|
||||
name,
|
||||
@@ -96,39 +99,48 @@ describe("bucketDeadlinesIntoColumns — side+appellant column routing (m/paliad
|
||||
party,
|
||||
});
|
||||
|
||||
test("default (no opts) mirrors 'both' rules into proactive AND reactive — legacy behaviour preserved", () => {
|
||||
test("default (no opts) mirrors 'both' rules into ours AND opponent — legacy behaviour preserved", () => {
|
||||
const rows = bucketDeadlinesIntoColumns([both("Notice of Appeal", "2026-07-23")]);
|
||||
expect(rows).toHaveLength(1);
|
||||
expect(rows[0].proactive.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].reactive.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].ours.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].opponent.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].court).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("appellant=claimant collapses 'both' rules into proactive only — no mirror", () => {
|
||||
test("default (no side) places claimant on the left (ours) — 'we are claimant' fallback", () => {
|
||||
const rows = bucketDeadlinesIntoColumns([
|
||||
partySpecific("claimant", "Klageschrift", "2026-01-01"),
|
||||
partySpecific("defendant", "Klageerwiderung", "2026-04-01"),
|
||||
]);
|
||||
expect(rows[0].ours.map((d) => d.name)).toEqual(["Klageschrift"]);
|
||||
expect(rows[1].opponent.map((d) => d.name)).toEqual(["Klageerwiderung"]);
|
||||
});
|
||||
|
||||
test("appellant=claimant collapses 'both' rules into ours when side=claimant (or default)", () => {
|
||||
const rows = bucketDeadlinesIntoColumns(
|
||||
[both("Notice of Appeal", "2026-07-23"), both("Statement of Grounds", "2026-09-23")],
|
||||
{ appellant: "claimant" },
|
||||
);
|
||||
expect(rows.map((r) => r.proactive.map((d) => d.name))).toEqual([
|
||||
expect(rows.map((r) => r.ours.map((d) => d.name))).toEqual([
|
||||
["Notice of Appeal"],
|
||||
["Statement of Grounds"],
|
||||
]);
|
||||
rows.forEach((r) => expect(r.reactive).toHaveLength(0));
|
||||
rows.forEach((r) => expect(r.opponent).toHaveLength(0));
|
||||
});
|
||||
|
||||
test("appellant=defendant collapses 'both' rules into reactive only", () => {
|
||||
test("appellant=defendant collapses 'both' rules into opponent when side=null/claimant", () => {
|
||||
const rows = bucketDeadlinesIntoColumns(
|
||||
[both("Notice of Appeal", "2026-07-23")],
|
||||
{ appellant: "defendant" },
|
||||
);
|
||||
expect(rows[0].proactive).toHaveLength(0);
|
||||
expect(rows[0].reactive.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].ours).toHaveLength(0);
|
||||
expect(rows[0].opponent.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
});
|
||||
|
||||
test("side=defendant swaps which column owns claimant vs defendant rules", () => {
|
||||
// claimant filing must land in REACTIVE (claimant is the opposing
|
||||
// side from the defendant user's perspective), defendant filing in
|
||||
// PROACTIVE. Court rules always go to court.
|
||||
test("side=defendant flips which party owns 'ours' vs 'opponent' — WE always on the left", () => {
|
||||
// User is on the defendant side: defendant filings land in 'ours'
|
||||
// (left), claimant filings land in 'opponent' (right). Court rules
|
||||
// stay in court regardless of side.
|
||||
const rows = bucketDeadlinesIntoColumns(
|
||||
[
|
||||
partySpecific("claimant", "Klageschrift", "2026-01-01"),
|
||||
@@ -137,20 +149,33 @@ describe("bucketDeadlinesIntoColumns — side+appellant column routing (m/paliad
|
||||
],
|
||||
{ side: "defendant" },
|
||||
);
|
||||
expect(rows[0].reactive.map((d) => d.name)).toEqual(["Klageschrift"]);
|
||||
expect(rows[1].proactive.map((d) => d.name)).toEqual(["Klageerwiderung"]);
|
||||
expect(rows[0].opponent.map((d) => d.name)).toEqual(["Klageschrift"]);
|
||||
expect(rows[1].ours.map((d) => d.name)).toEqual(["Klageerwiderung"]);
|
||||
expect(rows[2].court.map((d) => d.name)).toEqual(["Urteil"]);
|
||||
});
|
||||
|
||||
test("side=defendant + appellant=defendant routes 'both' into PROACTIVE (user's own column)", () => {
|
||||
test("side=defendant + appellant=defendant routes 'both' into 'ours' (user's own column)", () => {
|
||||
// The user is the defendant AND the appellant, so the appellant's
|
||||
// column == the user's own column == proactive after the swap.
|
||||
// column == the user's own column == ours after the swap.
|
||||
const rows = bucketDeadlinesIntoColumns(
|
||||
[both("Notice of Appeal", "2026-07-23")],
|
||||
{ side: "defendant", appellant: "defendant" },
|
||||
);
|
||||
expect(rows[0].proactive.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].reactive).toHaveLength(0);
|
||||
expect(rows[0].ours.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].opponent).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("side=defendant + appellant=claimant routes 'both' into opponent (claimant ≠ us)", () => {
|
||||
// Side flip + appellant axis combined: the claimant is the appellant
|
||||
// but NOT us, so the collapsed 'both' row lands in the opponent
|
||||
// column (right). This is the UPC Appeal "they appealed, we
|
||||
// respond" scenario.
|
||||
const rows = bucketDeadlinesIntoColumns(
|
||||
[both("Notice of Appeal", "2026-07-23")],
|
||||
{ side: "defendant", appellant: "claimant" },
|
||||
);
|
||||
expect(rows[0].opponent.map((d) => d.name)).toEqual(["Notice of Appeal"]);
|
||||
expect(rows[0].ours).toHaveLength(0);
|
||||
});
|
||||
|
||||
test("rows align across columns by dueDate so same-day events stay on one grid row", () => {
|
||||
@@ -161,8 +186,8 @@ describe("bucketDeadlinesIntoColumns — side+appellant column routing (m/paliad
|
||||
partySpecific("court", "C", sameDate),
|
||||
]);
|
||||
expect(rows).toHaveLength(1);
|
||||
expect(rows[0].proactive.map((d) => d.name)).toEqual(["A"]);
|
||||
expect(rows[0].reactive.map((d) => d.name)).toEqual(["B"]);
|
||||
expect(rows[0].ours.map((d) => d.name)).toEqual(["A"]);
|
||||
expect(rows[0].opponent.map((d) => d.name)).toEqual(["B"]);
|
||||
expect(rows[0].court.map((d) => d.name)).toEqual(["C"]);
|
||||
});
|
||||
|
||||
@@ -172,7 +197,7 @@ describe("bucketDeadlinesIntoColumns — side+appellant column routing (m/paliad
|
||||
partySpecific("claimant", "Statement of Claim", "2026-01-01"),
|
||||
partySpecific("court", "Decision", ""),
|
||||
]);
|
||||
expect(rows.map((r) => [r.proactive, r.court, r.reactive].flat().map((d) => d.name))).toEqual([
|
||||
expect(rows.map((r) => [r.ours, r.court, r.opponent].flat().map((d) => d.name))).toEqual([
|
||||
["Statement of Claim"],
|
||||
["Oral Hearing"],
|
||||
["Decision"],
|
||||
|
||||
@@ -422,42 +422,47 @@ export function renderTimelineBody(data: DeadlineResponse, opts: CardOpts = { sh
|
||||
return html;
|
||||
}
|
||||
|
||||
// Three-column timeline layout: Proactive | Court | Reactive.
|
||||
// Three-column timeline layout: Unsere Seite | Gericht | Gegnerseite.
|
||||
//
|
||||
// Column assignment per deadline (see m/paliad#81):
|
||||
// The columns are user-perspective ("WE are always on the left", per
|
||||
// t-paliad-257 / m/paliad#88). The old Proaktiv/Reaktiv axis lied:
|
||||
// Klägerseite is sometimes proactive (filing the claim) and sometimes
|
||||
// reactive (responding to a counterclaim), so the static "Proaktiv =
|
||||
// Klägerseite" label-pair was wrong half the time. The new axis is
|
||||
// "ours vs opponent" — the side toggle picks who WE are in this
|
||||
// proceeding (Klägerseite vs Beklagtenseite, i.e. patentee vs alleged
|
||||
// infringer / Einsprechender vs Patentinhaber, etc.), and rule
|
||||
// placement re-resolves around that pick.
|
||||
//
|
||||
// - party=claimant → proactive
|
||||
// - party=defendant → reactive
|
||||
// - party=court → court
|
||||
// - party=both → BOTH proactive AND reactive (mirror).
|
||||
// Column assignment per deadline (default opts.side === null keeps
|
||||
// the legacy claimant-on-the-left layout — i.e. "we are claimant"):
|
||||
//
|
||||
// - party=claimant → ours when side ∈ {null,"claimant"}, else opponent
|
||||
// - party=defendant → opponent when side ∈ {null,"claimant"}, else ours
|
||||
// - party=court → court (independent of side)
|
||||
// - party=both → BOTH ours AND opponent (mirror)
|
||||
//
|
||||
// When `opts.appellant` is set (claimant|defendant), "both" rows
|
||||
// collapse to a single row in the appellant's column. The intent is
|
||||
// role-swap proceedings (UPC Appeal, Counterclaim, …) where the
|
||||
// "both" tag really means "either party files, depending on who
|
||||
// initiated" — once you pick the initiator, the duplicate goes away.
|
||||
// Hard rule from the issue: "When set, 'both parties' rows collapse
|
||||
// to one row in the appellant's column." This is a UI projection
|
||||
// only; the deadline_rules schema is unchanged. A follow-up issue
|
||||
// can enrich per-rule role tagging so respondent-side filings
|
||||
// (Response to Appeal, Cross-Appeal) land in the respondent's
|
||||
// column — out of scope for #81.
|
||||
//
|
||||
// `opts.side` controls the column LABELS: side=defendant swaps the
|
||||
// "Proactive (Klägerseite)" / "Reactive (Beklagtenseite)" headers
|
||||
// so the user's own side is the proactive (= "your filings") column.
|
||||
// It does NOT filter deadlines — the user still sees all deadlines
|
||||
// in the proceeding. Default `side=null` keeps the legacy
|
||||
// claimant-on-the-left layout. Unscheduled (court-set) rows trail
|
||||
// the dated tail, each keyed by sequence-order so e.g. Urteil
|
||||
// precedes Berufungseinlegung.
|
||||
// collapse to a single row in the appellant's column — the intent is
|
||||
// role-swap proceedings (UPC Appeal, Counterclaim, …) where "both"
|
||||
// really means "either party files, depending on who initiated".
|
||||
// Appellant axis is independent of `side`: in an Appeal CoA, the
|
||||
// appellant selector pins which party appealed; the side toggle
|
||||
// still picks which of those is us.
|
||||
export type Side = "claimant" | "defendant" | null;
|
||||
|
||||
// Internal column-position alias. "ours" is always rendered in the
|
||||
// left grid column ("Unsere Seite"); "opponent" is always the right
|
||||
// column ("Gegnerseite"). Field names mirror the labels so the
|
||||
// bucketing primitive reads as a direct mapping.
|
||||
type ColumnPosition = "ours" | "opponent";
|
||||
|
||||
export interface ColumnsBodyOpts {
|
||||
editable?: boolean;
|
||||
showNotes?: boolean;
|
||||
// side: which side the user is on. Drives column-label swap;
|
||||
// does NOT filter rows. Default null = claimant-on-the-left.
|
||||
// side: which side the user is on. Drives column placement;
|
||||
// does NOT filter rows. Default null = claimant-on-the-left
|
||||
// (i.e. "ours = claimant", legacy default).
|
||||
side?: Side;
|
||||
// appellant: which side initiated the appeal / counterclaim.
|
||||
// When set, party=both rows go to the appellant's column ONLY
|
||||
@@ -471,9 +476,9 @@ export interface ColumnsBodyOpts {
|
||||
// document.createElement (no jsdom in this repo).
|
||||
export interface ColumnsRow {
|
||||
key: string;
|
||||
proactive: CalculatedDeadline[];
|
||||
ours: CalculatedDeadline[];
|
||||
court: CalculatedDeadline[];
|
||||
reactive: CalculatedDeadline[];
|
||||
opponent: CalculatedDeadline[];
|
||||
}
|
||||
|
||||
export interface BucketingOpts {
|
||||
@@ -484,17 +489,20 @@ export interface BucketingOpts {
|
||||
// bucketDeadlinesIntoColumns is the pure routing primitive that
|
||||
// renderColumnsBody uses. Extracted as its own export so the per-row
|
||||
// column placement (including the side-swap + appellant-collapse
|
||||
// logic from m/paliad#81) is unit-testable without a DOM. The
|
||||
// returned rows are sorted: dated rows ascending by dueDate, then
|
||||
// unscheduled rows in declaration order (each keyed by sequence).
|
||||
// logic from m/paliad#81 and the user-perspective re-frame from
|
||||
// m/paliad#88) is unit-testable without a DOM. The returned rows are
|
||||
// sorted: dated rows ascending by dueDate, then unscheduled rows in
|
||||
// declaration order (each keyed by sequence).
|
||||
export function bucketDeadlinesIntoColumns(
|
||||
deadlines: CalculatedDeadline[],
|
||||
opts: BucketingOpts = {},
|
||||
): ColumnsRow[] {
|
||||
const userSide: Side = opts.side ?? null;
|
||||
const claimantColumn: "proactive" | "reactive" = userSide === "defendant" ? "reactive" : "proactive";
|
||||
const defendantColumn: "proactive" | "reactive" = claimantColumn === "proactive" ? "reactive" : "proactive";
|
||||
const appellantColumn: "proactive" | "reactive" | null =
|
||||
// Default (side=null) treats the user as claimant — keeps the
|
||||
// legacy claimant-on-the-left layout when no perspective is picked.
|
||||
const claimantColumn: ColumnPosition = userSide === "defendant" ? "opponent" : "ours";
|
||||
const defendantColumn: ColumnPosition = claimantColumn === "ours" ? "opponent" : "ours";
|
||||
const appellantColumn: ColumnPosition | null =
|
||||
opts.appellant === "claimant" ? claimantColumn
|
||||
: opts.appellant === "defendant" ? defendantColumn
|
||||
: null;
|
||||
@@ -504,7 +512,7 @@ export function bucketDeadlinesIntoColumns(
|
||||
const ensureRow = (key: string): ColumnsRow => {
|
||||
let r = rowsMap.get(key);
|
||||
if (!r) {
|
||||
r = { key, proactive: [], court: [], reactive: [] };
|
||||
r = { key, ours: [], court: [], opponent: [] };
|
||||
rowsMap.set(key, r);
|
||||
}
|
||||
return r;
|
||||
@@ -529,8 +537,8 @@ export function bucketDeadlinesIntoColumns(
|
||||
// in appellant's column. Mirror suppressed.
|
||||
row[appellantColumn].push(dl);
|
||||
} else {
|
||||
row.proactive.push(dl);
|
||||
row.reactive.push(dl);
|
||||
row.ours.push(dl);
|
||||
row.opponent.push(dl);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -552,17 +560,14 @@ export function bucketDeadlinesIntoColumns(
|
||||
export function renderColumnsBody(data: DeadlineResponse, opts: ColumnsBodyOpts = {}): string {
|
||||
const userSide: Side = opts.side ?? null;
|
||||
const rows = bucketDeadlinesIntoColumns(data.deadlines, { side: userSide, appellant: opts.appellant });
|
||||
const appellantColumn: "proactive" | "reactive" | null =
|
||||
opts.appellant === "claimant" ? (userSide === "defendant" ? "reactive" : "proactive")
|
||||
: opts.appellant === "defendant" ? (userSide === "defendant" ? "proactive" : "reactive")
|
||||
: null;
|
||||
const appellantPinned = opts.appellant === "claimant" || opts.appellant === "defendant";
|
||||
|
||||
const cardOpts: CardOpts = { showParty: false, editable: opts.editable, showNotes: opts.showNotes };
|
||||
|
||||
// Collapsed "both" rows lose their mirror tag — there's no longer
|
||||
// a sibling row to mirror to, so the "↔ beide Seiten" hint would
|
||||
// be misleading. Keep it for the legacy mirror path.
|
||||
const showMirrorTag = appellantColumn === null;
|
||||
const showMirrorTag = !appellantPinned;
|
||||
|
||||
const renderCell = (items: CalculatedDeadline[]): string => {
|
||||
if (items.length === 0) {
|
||||
@@ -585,25 +590,19 @@ export function renderColumnsBody(data: DeadlineResponse, opts: ColumnsBodyOpts
|
||||
const headerCell = (label: string, cls: string) =>
|
||||
`<div class="fr-col-header ${cls}">${escHtml(label)}</div>`;
|
||||
|
||||
// Column-label swap when side=defendant: the user's own side stays
|
||||
// labelled "Proaktiv" (their filings) and the opposing side is
|
||||
// "Reaktiv". Default keeps the legacy claimant=proactive labels.
|
||||
const proactiveLabel = userSide === "defendant"
|
||||
? t("deadlines.col.proactive.defendant")
|
||||
: t("deadlines.col.proactive");
|
||||
const reactiveLabel = userSide === "defendant"
|
||||
? t("deadlines.col.reactive.claimant")
|
||||
: t("deadlines.col.reactive");
|
||||
|
||||
// Static labels — "Unsere Seite" is always the left column, regardless
|
||||
// of which physical party (claimant vs defendant) occupies it. The
|
||||
// bucketing primitive already routes the user's side into the `ours`
|
||||
// bucket, so the header truth-fully describes the column contents.
|
||||
let html = '<div class="fr-columns-view">';
|
||||
html += headerCell(proactiveLabel, "fr-col-proactive");
|
||||
html += headerCell(t("deadlines.col.ours"), "fr-col-ours");
|
||||
html += headerCell(t("deadlines.col.court"), "fr-col-court");
|
||||
html += headerCell(reactiveLabel, "fr-col-reactive");
|
||||
html += headerCell(t("deadlines.col.opponent"), "fr-col-opponent");
|
||||
|
||||
for (const row of rows) {
|
||||
html += renderCell(row.proactive);
|
||||
html += renderCell(row.ours);
|
||||
html += renderCell(row.court);
|
||||
html += renderCell(row.reactive);
|
||||
html += renderCell(row.opponent);
|
||||
}
|
||||
html += "</div>";
|
||||
return html;
|
||||
|
||||
@@ -1142,10 +1142,8 @@ export type I18nKey =
|
||||
| "deadlines.col.court"
|
||||
| "deadlines.col.due"
|
||||
| "deadlines.col.event_type"
|
||||
| "deadlines.col.proactive"
|
||||
| "deadlines.col.proactive.defendant"
|
||||
| "deadlines.col.reactive"
|
||||
| "deadlines.col.reactive.claimant"
|
||||
| "deadlines.col.opponent"
|
||||
| "deadlines.col.ours"
|
||||
| "deadlines.col.rule"
|
||||
| "deadlines.col.status"
|
||||
| "deadlines.col.title"
|
||||
|
||||
@@ -3629,7 +3629,7 @@ input[type="range"]::-moz-range-thumb {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.fr-col-header.fr-col-proactive {
|
||||
.fr-col-header.fr-col-ours {
|
||||
background: var(--status-blue-bg);
|
||||
color: var(--status-blue-fg);
|
||||
}
|
||||
@@ -3639,7 +3639,7 @@ input[type="range"]::-moz-range-thumb {
|
||||
color: var(--status-blue-soft-fg);
|
||||
}
|
||||
|
||||
.fr-col-header.fr-col-reactive {
|
||||
.fr-col-header.fr-col-opponent {
|
||||
background: var(--status-amber-bg);
|
||||
color: var(--status-amber-fg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user