Skip to content

fix(compliance): group the Rapport view by report headline, tags as a caption (#1188) - #1203

Merged
renemadsen merged 1 commit into
stablefrom
feat/1188-rapport-by-report-headline
Sep 7, 2026
Merged

fix(compliance): group the Rapport view by report headline, tags as a caption (#1188)#1203
renemadsen merged 1 commit into
stablefrom
feat/1188-rapport-by-report-headline

Conversation

@renemadsen

Copy link
Copy Markdown
Member

Closes #1188. Part of #1183 (customer bug list, PDF pages 4–5 "Tabel_Rapport").

Decisions (final)

D1 server-side union of columns per headline · D2 caption = the section's tags (excluding the headline) alphabetical, joined - · D3 (a) rows without a headline form a last Uden rapportoverskrift section · D4 = no Rapportoverskrift CSV column (product sign-off: follow the mock-up) · D5 sections ordered by caption, then headline name, then id · D6 tag-filter semantics unchanged · D7 #1185 took B1.

What

BackendEformColumns groups by AreaRulePlanning.ItemPlanningTagId (the wizard's "report table header tag"): new ComplianceReportHeadlineGroupModel (headlineTagId, headlineName — null when no PlanningTags row, rendered #{id}; tagsCaption; checkListIds; schemaUnavailableCheckListIds; a fresh union of the templates' columns keyed f{fieldId}; cases once each). Cases carry tags (headline excluded — required, the legacy area-rule path also stores the headline as an ARP tag) and their own checkListId. ComplianceReportTagGroupModel / ComplianceReportTemplateGroupModel deleted; headline ids ride the single existing PlanningTags lookup; no DB calls in the loop. Export: ComplianceExportTable.Caption; Rapport = one table per headline with a plain caption line above the bold headline, Delrapport = the row's own tags, no headline column, appendix labelled by caption; Oversigt/Detaljer untouched. localization.json: WithoutReportHeadline, ReportHeadline (26 locales).

Frontend — model/service/helper/view on the new shape: .compliance-report__tag = caption, .compliance-report__heading = headline (#{id} / fallback), union columns with under foreign-template fields, per-template "Kolonner utilgængelige for eForm #{{id}}" notice (whole-section notice only when all templates lack a schema), Rediger routes with the row's own checkListId. i18n: Without tag retired (no consumer left); Without report headline + the notice key added in 26 locales, the fallback label aligned with localization.json so screen and export agree.

Tests — NUnit grouping tests rewritten (two headlines; one headline over two templates → union with in-place dash; no leak into another group sharing the template; caption A - B; legacy headline-as-tag excluded; tag filter shows full membership; fallback last; orphan headline id keeps its group with null name; order; cloned templates), builder/writer tests updated (Caption, Delrapport, appendix, partial-schema suffix); Jest helper + component specs rewritten; Playwright s/compliance-report-view.spec.ts replaces the substring-matched text=Rapportoverskrift assertion with structural section assertions.

Reversed documented decisions

#1160 decision 5 (tag → template grouping), #1166 ("mirror this shape; do not reuse the type"), #1167 (heading = template name; grouping divergence), PR #1178 / ComplianceExportDocumentBuilder.cs composite {tag} – {template} Delrapport. The "Excel sheet name" wording in the issue is moot (#1189 removed xlsx).

Verified against the running dev stack (gate 2)

Live eform-columns: 11 groups, Σ cases = 438 = index rows with an answered checkListId; every case in exactly one group; captions sorted; fallback last; tags never contain the headline (0 mismatches over 438 rows); legacy headline-as-tag plannings de-duplicated in the caption; a 7-template group renders the union with in place; Rediger/case/5552/13/874 (the row's template). Exports: PDF caption above bold headline per section, Delrapport = row tags, no headline column, fallback section last; CSV Delrapport first, blanks for empties, no headline column; Detaljer/Oversigt exports unchanged.

Handoff notes for #1192 (Rapport export restyle)

🤖 Generated with Claude Code

https://claude.ai/code/session_018qJL2WhHwhZ5CGZehZF2ro

… caption (#1188)

"Rapportoverskrift" is a real field (AreaRulePlanning.ItemPlanningTagId,
the wizard's "report table header tag"), not a prototype placeholder.
#1167 read it as one and grouped Rapport by tag x eForm template with
the template name as heading, so a headline spanning several tags
rendered as several tables, a multi-tag task was duplicated, and the
export followed suit.

Backend
- EformColumns groups by row.Arp?.ItemPlanningTagId: one
  ComplianceReportHeadlineGroupModel per headline (HeadlineTagId,
  HeadlineName (null when unresolvable -> "#id" on the client),
  TagsCaption, CheckListIds, SchemaUnavailableCheckListIds, a FRESH
  union of the templates' columns, Cases once each). Cases carry Tags
  (excluding the headline, which the legacy area-rule path also stores
  as an ARP tag) and their own CheckListId. Rows without a headline form
  a last fallback group (WithoutReportHeadline). Order: caption, headline
  name, id. Tag-group/template-group DTOs deleted.
- Export: ComplianceExportTable.Caption; BuildReport emits one table per
  headline (caption line above the bold headline, Delrapport = the row's
  own tags joined " - ", no headline column per product decision 4,
  appendix labelled by caption); Oversigt/Detaljer untouched.
- localization.json: WithoutReportHeadline, ReportHeadline (26 locales).
- Tests: EformColumns grouping tests rewritten (two headlines, union
  columns with in-place dash, no cache leak, caption A - B, legacy
  headline-as-tag excluded, fallback last, orphan headline id, order,
  clones); builder/writer tests updated for Caption and Delrapport.

Frontend
- Model/service/helper/view follow the new shape: caption
  (.compliance-report__tag) + headline (.compliance-report__heading),
  "#id" for unresolvable headlines, "Uden rapportoverskrift" fallback,
  per-template "columns unavailable" notice, Rediger uses the row's own
  checkListId. i18n: "Without tag" retired; "Without report headline"
  and the per-template notice key added in 26 locales, fallback label
  aligned with localization.json.
- Jest specs rewritten; Playwright replaces the substring-matched
  "Rapportoverskrift" assertion with structural section assertions.

Reverses #1160 decision 5, #1166 "mirror this shape", #1167 heading and
grouping, and PR #1178's composite Delrapport column.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018qJL2WhHwhZ5CGZehZF2ro
Copilot AI lite review requested due to automatic review settings September 7, 2026 07:42

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Backend grouping should normalize/trim headline and tag names at the source to avoid inconsistent ordering/output between UI and exports when tag names contain surrounding whitespace.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR updates the Compliance “Rapport” read model and UI to group results by report headline (AreaRulePlanning.ItemPlanningTagId) instead of the previous tag × template grouping, aligning the screen and exports with the customer PDF (“Tabel_Rapport”) requirements.

Changes:

  • Backend: replace tag/template grouping DTOs with ComplianceReportHeadlineGroupModel and build per-headline union columns + per-case tags (headline excluded).
  • Export: add ComplianceExportTable.Caption (tags caption) rendered above the headline in Word/PDF; adjust Rapport export shaping to the new grouping and Delrapport semantics.
  • Frontend/tests: map the new DTO shape into sections (caption + headline), add per-template schema-unavailable notices, update i18n and Playwright/Jest/NUnit fixtures.
File summaries
File Description
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationComplianceReportService/IBackendConfigurationComplianceReportService.cs Updates service contract to headline-grouped DTO
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationComplianceReportService/ComplianceReportEformProjector.cs Updates schema-unavailable docs to new DTO shape
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationComplianceReportService/BackendConfigurationComplianceReportService.cs Implements headline grouping + union columns + per-row tags
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationComplianceExportService/ComplianceExportWordWriter.cs Renders Rapport caption line above headline
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationComplianceExportService/ComplianceExportDocumentBuilder.cs Builds Rapport tables from headline groups + caption/title semantics
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Resources/localization.json Adds WithoutReportHeadline + ReportHeadline keys (26 locales)
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Models/ComplianceReport/ComplianceReportTemplateGroupModel.cs Removes obsolete template-group DTO
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Models/ComplianceReport/ComplianceReportTagGroupModel.cs Removes obsolete tag-group DTO
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Models/ComplianceReport/ComplianceReportHeadlineGroupModel.cs Adds new headline-group DTO
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Models/ComplianceReport/ComplianceReportCaseModel.cs Adds per-case CheckListId + Tags for new grouping/export
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Infrastructure/Models/ComplianceReport/ComplianceExportDocument.cs Adds ComplianceExportTable.Caption + updates Rapport grouping docs
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Controllers/ComplianceReportController.cs Updates endpoint return type to headline groups
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/ComplianceExportWriterTests.cs Updates writer tests for caption/title and CSV caption omission
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/ComplianceExportServiceTests.cs Updates stubbed service return types
eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn.Integration.Test/ComplianceExportDocumentBuilderTests.cs Rewrites Rapport export builder tests for new grouping
eform-client/src/app/plugins/modules/backend-configuration-pn/services/backend-configuration-pn-compliance-report.service.ts Updates frontend service return type to headline groups
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/compliance-report/helpers/compliance-report-sections.ts Maps headline groups to sections + schema notice logic
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/compliance-report/helpers/compliance-report-sections.spec.ts Rewrites pure helper tests for headline grouping rules
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/compliance-report/components/compliance-report-view/compliance-report-view.component.ts Updates Rapport view to render headline sections + per-row template id
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/compliance-report/components/compliance-report-view/compliance-report-view.component.spec.ts Updates component tests for new section shape + routing
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/compliance-report/components/compliance-report-view/compliance-report-view.component.scss Updates caption/heading styling semantics
eform-client/src/app/plugins/modules/backend-configuration-pn/modules/compliance-report/components/compliance-report-view/compliance-report-view.component.html Updates markup for caption + headline + per-template notices
eform-client/src/app/plugins/modules/backend-configuration-pn/models/compliance-report/compliance-report.model.ts Replaces tag/template DTOs with headline-group model
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ukUA.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/svSE.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/slSL.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/skSK.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/roRO.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ptPT.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ptBR.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/plPL.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/noNO.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/nlNL.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/lvLV.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/ltLT.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/itIT.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/isIS.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/huHU.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/hrHR.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/frFR.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/fiFI.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/etET.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/esES.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/enUS.ts Updates keys/comments for headline grouping + template notice
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/elGR.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/deDE.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/da.ts Replaces “Without tag” with Danish headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/csCZ.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/src/app/plugins/modules/backend-configuration-pn/i18n/bgBG.ts Replaces “Without tag” with new headline + template-notice keys
eform-client/playwright/e2e/plugins/backend-configuration-pn/s/compliance-report-view.spec.ts Updates Playwright assertions to structural section checks
Review details

Suppressed comments (1)

eFormAPI/Plugins/BackendConfiguration.Pn/BackendConfiguration.Pn/Services/BackendConfigurationComplianceReportService/BackendConfigurationComplianceReportService.cs:1184

  • TagLabel returns raw PlanningTags.Name, so names with surrounding whitespace can produce duplicate-looking tags, affect TagsCaption ordering, and make screen/export output diverge (the frontend trims). Trimming here keeps captions deterministic and consistent with the UI/export formatting rules.
    private static string TagLabel(int tagId, Dictionary<int, string> planningTagNames)
    {
        var name = planningTagNames.GetValueOrDefault(tagId);
        return string.IsNullOrWhiteSpace(name) ? $"#{tagId}" : name;
    }
  • Files reviewed: 51/51 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1125 to +1127
group = new HeadlineGroupBuilder(
headlineTagId, planningTagNames.GetValueOrDefault(headlineTagId.Value));
groupsByHeadlineId[headlineTagId.Value] = group;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants