@hmcts/ccd-case-ui-toolkit 7.4.3-redact → 7.4.4-default-focus
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3960,6 +3960,7 @@ class CaseTab {
|
|
|
3960
3960
|
order;
|
|
3961
3961
|
fields;
|
|
3962
3962
|
show_condition;
|
|
3963
|
+
defaultFocus;
|
|
3963
3964
|
}
|
|
3964
3965
|
__decorate([
|
|
3965
3966
|
Type(() => CaseField),
|
|
@@ -14766,6 +14767,9 @@ class CaseFileViewFieldComponent {
|
|
|
14766
14767
|
ngAfterViewInit() {
|
|
14767
14768
|
const slider = this.elementRef.nativeElement.querySelector('.slider');
|
|
14768
14769
|
const documentTreeContainer = this.elementRef.nativeElement.querySelector('.document-tree-container');
|
|
14770
|
+
if (!slider || !documentTreeContainer) {
|
|
14771
|
+
return;
|
|
14772
|
+
}
|
|
14769
14773
|
const mousedown$ = fromEvent(slider, 'mousedown');
|
|
14770
14774
|
const mousemove$ = fromEvent(document, 'mousemove');
|
|
14771
14775
|
const mouseup$ = fromEvent(document, 'mouseup');
|
|
@@ -27404,8 +27408,12 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
|
|
|
27404
27408
|
this.removeUnsupportedMarkup(documentElement);
|
|
27405
27409
|
this.normaliseDateRangeSpacing(documentElement);
|
|
27406
27410
|
this.removeUnsupportedAttributes(documentElement);
|
|
27411
|
+
const hasMeaningfulContent = this.hasMeaningfulRichTextContent(documentElement);
|
|
27412
|
+
if (hasMeaningfulContent) {
|
|
27413
|
+
this.preserveDocmosisBlankParagraphs(documentElement);
|
|
27414
|
+
}
|
|
27407
27415
|
const sanitisedValue = sanitiseRichTextDocument(documentElement);
|
|
27408
|
-
return
|
|
27416
|
+
return hasMeaningfulContent
|
|
27409
27417
|
? this.normalisePlainTextValue(sanitisedValue)
|
|
27410
27418
|
: '';
|
|
27411
27419
|
}
|
|
@@ -27425,11 +27433,22 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
|
|
|
27425
27433
|
this.removeUnsupportedMarkup(documentElement);
|
|
27426
27434
|
this.normaliseDateRangeSpacing(documentElement);
|
|
27427
27435
|
this.removeUnsupportedAttributes(documentElement);
|
|
27436
|
+
const hasMeaningfulContent = this.hasMeaningfulRichTextContent(documentElement);
|
|
27437
|
+
if (hasMeaningfulContent) {
|
|
27438
|
+
this.preserveDocmosisBlankParagraphs(documentElement);
|
|
27439
|
+
}
|
|
27428
27440
|
const sanitisedValue = sanitiseRichTextDocument(documentElement);
|
|
27429
|
-
return
|
|
27441
|
+
return hasMeaningfulContent
|
|
27430
27442
|
? this.normalisePlainTextValue(sanitisedValue)
|
|
27431
27443
|
: '';
|
|
27432
27444
|
}
|
|
27445
|
+
/**
|
|
27446
|
+
* Gives intentionally blank paragraphs content so Docmosis preserves them as blank lines.
|
|
27447
|
+
* This runs only when the document has meaningful content, so a completely empty field remains empty.
|
|
27448
|
+
*/
|
|
27449
|
+
preserveDocmosisBlankParagraphs(documentElement) {
|
|
27450
|
+
this.replaceBlankParagraphContent(documentElement, '\u00a0');
|
|
27451
|
+
}
|
|
27433
27452
|
hasMeaningfulRichTextContent(documentElement) {
|
|
27434
27453
|
const visibleText = (documentElement.body.textContent || '')
|
|
27435
27454
|
.replace(/[\s\u00a0\u200b-\u200d\ufeff]/g, '');
|
|
@@ -27550,7 +27569,8 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
|
|
|
27550
27569
|
emitEvent: false,
|
|
27551
27570
|
emitModelToViewChange: false
|
|
27552
27571
|
});
|
|
27553
|
-
if (normalisedValue || this.editorHasMeaningfulRichTextContent())
|
|
27572
|
+
if ((normalisedValue || this.editorHasMeaningfulRichTextContent())
|
|
27573
|
+
&& !this.differsOnlyByDocmosisBlankParagraphs(value, normalisedValue)) {
|
|
27554
27574
|
this.editor.setContent(normalisedValue || '');
|
|
27555
27575
|
}
|
|
27556
27576
|
}
|
|
@@ -27558,6 +27578,34 @@ class WriteRichTextAreaFieldComponent extends AbstractFieldWriteComponent {
|
|
|
27558
27578
|
this.isNormalisingValue = false;
|
|
27559
27579
|
}
|
|
27560
27580
|
}
|
|
27581
|
+
differsOnlyByDocmosisBlankParagraphs(value, normalisedValue) {
|
|
27582
|
+
if (!value || !normalisedValue) {
|
|
27583
|
+
return false;
|
|
27584
|
+
}
|
|
27585
|
+
const originalDocument = new DOMParser().parseFromString(value, 'text/html');
|
|
27586
|
+
const normalisedDocument = new DOMParser().parseFromString(normalisedValue, 'text/html');
|
|
27587
|
+
this.clearBlankParagraphs(originalDocument);
|
|
27588
|
+
this.clearBlankParagraphs(normalisedDocument);
|
|
27589
|
+
return originalDocument.body.innerHTML === normalisedDocument.body.innerHTML;
|
|
27590
|
+
}
|
|
27591
|
+
/**
|
|
27592
|
+
* Canonicalises visually blank paragraphs to <p></p> before comparing two HTML values.
|
|
27593
|
+
* This lets the editor avoid reloading when only the Docmosis blank-line representation changed.
|
|
27594
|
+
*/
|
|
27595
|
+
clearBlankParagraphs(documentElement) {
|
|
27596
|
+
this.replaceBlankParagraphContent(documentElement, '');
|
|
27597
|
+
}
|
|
27598
|
+
replaceBlankParagraphContent(documentElement, replacement) {
|
|
27599
|
+
const paragraphs = Array.prototype.slice.call(documentElement.body.querySelectorAll('p'));
|
|
27600
|
+
paragraphs.forEach((paragraph) => {
|
|
27601
|
+
// Ignore standard whitespace (\s), non-breaking spaces (U+00A0), zero-width characters
|
|
27602
|
+
// (U+200B–U+200D), and the byte-order mark (U+FEFF) when checking for visible text.
|
|
27603
|
+
const visibleText = (paragraph.textContent || '').replace(/[\s\u00a0\u200b-\u200d\ufeff]/g, '');
|
|
27604
|
+
if (!visibleText && !paragraph.querySelector('hr')) {
|
|
27605
|
+
paragraph.textContent = replacement;
|
|
27606
|
+
}
|
|
27607
|
+
});
|
|
27608
|
+
}
|
|
27561
27609
|
editorHasMeaningfulRichTextContent() {
|
|
27562
27610
|
const documentNode = this.editor.view.state.doc;
|
|
27563
27611
|
const visibleText = documentNode.textContent.replace(/[\s\u00a0\u200b-\u200d\ufeff]/g, '');
|
|
@@ -41457,7 +41505,12 @@ class CaseFullAccessViewComponent {
|
|
|
41457
41505
|
let hashValue = url.substring(url.indexOf('#') + 1);
|
|
41458
41506
|
const hasHash = url.includes('#');
|
|
41459
41507
|
const isSpecialTabPath = url.includes('roles-and-access') || url.includes('tasks') || url.includes('hearings');
|
|
41460
|
-
|
|
41508
|
+
// TODO: Remove defaultFocusDemo once QA'd
|
|
41509
|
+
const defaultFocusDemo = url.includes('default-focus-demo');
|
|
41510
|
+
if (defaultFocusDemo) {
|
|
41511
|
+
this.caseDetails.tabs[Number(url.substring(url.indexOf('default-focus-demo-') + 19))].defaultFocus = true;
|
|
41512
|
+
}
|
|
41513
|
+
if (defaultFocusDemo || (!hasHash && !isSpecialTabPath)) {
|
|
41461
41514
|
const paths = url.split('/');
|
|
41462
41515
|
const lastPath = decodeURIComponent(paths[paths.length - 1]);
|
|
41463
41516
|
let foundTab = null;
|
|
@@ -41481,10 +41534,13 @@ class CaseFullAccessViewComponent {
|
|
|
41481
41534
|
});
|
|
41482
41535
|
}
|
|
41483
41536
|
else {
|
|
41484
|
-
this.caseDetails.tabs
|
|
41537
|
+
this.caseDetails.tabs = this.orderService.sort(this.caseDetails.tabs);
|
|
41538
|
+
// Presuming default focus only set for one tab here - multiple tabs with default focus are not handled as is a contradiction
|
|
41539
|
+
let preSelectTab = this.caseDetails.tabs.find((tab) => tab.defaultFocus === true) ?? null;
|
|
41540
|
+
// Attempt to pre-select the tab based on the preferred label for the current case type
|
|
41485
41541
|
const preferredLabel = FieldsUtils.defaultTabList?.[this.caseDetails?.case_type?.id];
|
|
41486
|
-
|
|
41487
|
-
if (preferredLabel) {
|
|
41542
|
+
// If no tab has default focus, attempt to use the preferred label for the current case type
|
|
41543
|
+
if (!preSelectTab && preferredLabel) {
|
|
41488
41544
|
preSelectTab = this.caseDetails.tabs.find((tab) => (tab.label === preferredLabel) || (tab.id === preferredLabel)) ?? null;
|
|
41489
41545
|
}
|
|
41490
41546
|
if (!preSelectTab) {
|