@hmcts/ccd-case-ui-toolkit 7.3.43-exui-3229 → 7.3.43-exui-4368-2916

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.
@@ -6624,6 +6624,7 @@ class LabelSubstitutorDirective {
6624
6624
  contextFields = [];
6625
6625
  formGroup;
6626
6626
  elementsToSubstitute = ['label', 'hint_text'];
6627
+ initialLabel;
6627
6628
  initialHintText;
6628
6629
  languageSubscription;
6629
6630
  constructor(fieldsUtils, placeholderService, rpxTranslationPipe, rpxTranslationService) {
@@ -6633,9 +6634,10 @@ class LabelSubstitutorDirective {
6633
6634
  this.rpxTranslationService = rpxTranslationService;
6634
6635
  }
6635
6636
  ngOnInit() {
6637
+ this.initialLabel = this.caseField.label;
6636
6638
  this.initialHintText = this.caseField.hint_text;
6637
- this.caseField.originalLabel = this.caseField.label;
6638
6639
  this.noCacheProcessing();
6640
+ this.caseField.originalLabel = this.caseField.originalLabel || this.caseField.label;
6639
6641
  this.formGroup = this.formGroup || new FormGroup({});
6640
6642
  this.languageSubscription = this.rpxTranslationService.language$.pipe(skip(1)).subscribe(() => {
6641
6643
  this.onLanguageChange();
@@ -6658,22 +6660,56 @@ class LabelSubstitutorDirective {
6658
6660
  }
6659
6661
  }
6660
6662
  }
6661
- applySubstitutions() {
6663
+ applySubstitutions(isLanguageChange = false) {
6662
6664
  const fields = this.getReadOnlyAndFormFields();
6663
6665
  if (this.shouldSubstitute('label')) {
6664
- const oldLabel = this.caseField.label;
6665
- const substitutedLabel = this.resolvePlaceholders(fields, this.caseField.label);
6666
- if (oldLabel && oldLabel !== substitutedLabel) {
6667
- // we need to translate the uninterpolated data then substitute the values in translated string
6668
- this.caseField.originalLabel = substitutedLabel;
6669
- const translated = this.rpxTranslationPipe.transform(oldLabel);
6670
- const transSubstitutedLabel = this.resolvePlaceholders(fields, translated);
6671
- this.caseField.label = transSubstitutedLabel;
6672
- this.caseField.isTranslated = this.rpxTranslationService.language === 'cy' && translated !== oldLabel;
6666
+ const currentLabel = this.caseField.label;
6667
+ // `originalLabel` stores the label exactly as it came from the server, before any
6668
+ // placeholder values were inserted. That gives us a clean starting point when the user
6669
+ // changes language or returns to the page later.
6670
+ const originalLabel = this.caseField.originalLabel || currentLabel;
6671
+ const substitutedCurrentLabel = this.resolvePlaceholders(fields, currentLabel);
6672
+ const substitutedOriginalLabel = originalLabel === currentLabel
6673
+ ? substitutedCurrentLabel
6674
+ : this.resolvePlaceholders(fields, originalLabel);
6675
+ const substitutedLabel = substitutedCurrentLabel || substitutedOriginalLabel;
6676
+ const languageIsWelsh = this.rpxTranslationService.language === 'cy';
6677
+ const hasAnyLabelSubstitution = (currentLabel && currentLabel !== substitutedCurrentLabel)
6678
+ || (originalLabel && originalLabel !== substitutedOriginalLabel);
6679
+ if (hasAnyLabelSubstitution) {
6680
+ // Preserve the original template the first time we successfully interpolate it.
6681
+ this.caseField.originalLabel = this.caseField.originalLabel || originalLabel;
6682
+ // Some labels only translate correctly if we translate the template first and then
6683
+ // substitute the helper values into the translated sentence.
6684
+ const translatedTemplateLabel = this.resolvePlaceholders(fields, this.translateLabel(originalLabel, isLanguageChange));
6685
+ // Other labels only translate correctly if we first resolve the English phrase and let
6686
+ // the render layer translate that final resolved string.
6687
+ const translatedResolvedLabel = this.translateLabel(substitutedLabel, isLanguageChange);
6688
+ const hasResolvedWelshTranslation = languageIsWelsh
6689
+ && translatedResolvedLabel
6690
+ && translatedResolvedLabel !== substitutedLabel;
6691
+ const hasTemplateWelshTranslation = languageIsWelsh
6692
+ && translatedTemplateLabel
6693
+ && translatedTemplateLabel !== substitutedLabel;
6694
+ if (hasResolvedWelshTranslation) {
6695
+ // Keep the resolved English label and mark it as not yet translated so the field
6696
+ // template can run `rpxTranslate` on the full phrase at render time.
6697
+ this.setLabelState(substitutedLabel);
6698
+ }
6699
+ else if (hasTemplateWelshTranslation) {
6700
+ // Use the template-translated result when translating the fully resolved label does
6701
+ // not improve the Welsh output.
6702
+ this.setLabelState(translatedTemplateLabel, true);
6703
+ }
6704
+ else {
6705
+ // English, untranslated Welsh, or labels whose translation is handled elsewhere.
6706
+ this.setLabelState(substitutedLabel);
6707
+ }
6673
6708
  }
6674
6709
  else {
6675
- this.caseField.label = substitutedLabel;
6676
- this.caseField.isTranslated = false;
6710
+ // No placeholders were resolved, so keep the current label and allow the render layer
6711
+ // to translate it normally if needed.
6712
+ this.setLabelState(substitutedLabel);
6677
6713
  }
6678
6714
  }
6679
6715
  if (this.shouldSubstitute('hint_text')) {
@@ -6683,14 +6719,26 @@ class LabelSubstitutorDirective {
6683
6719
  this.caseField.value = this.resolvePlaceholders(fields, this.caseField.value);
6684
6720
  }
6685
6721
  }
6722
+ translateLabel(label, isLanguageChange) {
6723
+ return isLanguageChange && this.rpxTranslationService.language === 'en'
6724
+ ? label
6725
+ : this.rpxTranslationPipe.transform(label);
6726
+ }
6727
+ setLabelState(label, isTranslated = false) {
6728
+ this.caseField.label = label;
6729
+ this.caseField.isTranslated = isTranslated;
6730
+ }
6686
6731
  onLanguageChange() {
6687
- this.resetToInitialValues();
6688
- this.applySubstitutions();
6732
+ this.resetToInitialValues(true);
6733
+ this.applySubstitutions(true);
6689
6734
  }
6690
- resetToInitialValues() {
6691
- if (this.caseField?.originalLabel) {
6735
+ resetToInitialValues(isLanguageChange = false) {
6736
+ if (isLanguageChange && this.caseField?.originalLabel) {
6692
6737
  this.caseField.label = this.caseField.originalLabel;
6693
6738
  }
6739
+ if (!isLanguageChange && this.initialLabel) {
6740
+ this.caseField.label = this.initialLabel;
6741
+ }
6694
6742
  if (this.initialHintText) {
6695
6743
  this.caseField.hint_text = this.initialHintText;
6696
6744
  }
@@ -8748,14 +8796,9 @@ class CaseEditWizardGuard {
8748
8796
  }
8749
8797
  goToFirst(wizard, canShowPredicate, route) {
8750
8798
  const firstPage = wizard.firstPage(canShowPredicate);
8751
- // This route transition is an internal wizard redirect used to append the first page id to the URL.
8752
- // Mark it in navigation state so EventStartGuard can skip duplicate work allocation checks.
8753
- return this.router.navigate([...this.parentUrlSegments(route), firstPage ? firstPage.id : 'submit'], {
8754
- queryParams: route.queryParams,
8755
- state: {
8756
- [EVENT_START_FIRST_PAGE_REDIRECT]: true
8757
- }
8758
- });
8799
+ // If there’s no specific wizard page called, it makes another navigation to either the first page available or to the submit page
8800
+ // TODO should find a way to navigate to target page without going through the whole loop (and make a second call to BE) again
8801
+ return this.router.navigate([...this.parentUrlSegments(route), firstPage ? firstPage.id : 'submit'], { queryParams: route.queryParams });
8759
8802
  }
8760
8803
  goToSubmit(route) {
8761
8804
  return this.router.navigate([...this.parentUrlSegments(route), 'submit'], { queryParams: route.queryParams });
@@ -9977,7 +10020,6 @@ class CaseEditComponent {
9977
10020
  }] }); })();
9978
10021
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CaseEditComponent, { className: "CaseEditComponent", filePath: "lib/shared/components/case-editor/case-edit/case-edit.component.ts", lineNumber: 38 }); })();
9979
10022
 
9980
- const EVENT_START_FIRST_PAGE_REDIRECT = 'eventStartFirstPageRedirect';
9981
10023
  function convertNonASCIICharacter(character) {
9982
10024
  if (character === '£') {
9983
10025
  // pound sign will be frequently used and works for btoa despite being non-ASCII
@@ -37464,10 +37506,6 @@ class EventStartGuard {
37464
37506
  }
37465
37507
  }
37466
37508
  return caseDataObservable.pipe(switchMap(() => {
37467
- if (this.shouldSkipDuplicateWorkAllocationCall()) {
37468
- this.abstractConfig.logMessage(`EventStartGuard: skipping duplicate work allocation call for caseId ${caseId} and eventId ${eventId}`);
37469
- return of(true);
37470
- }
37471
37509
  if (this.jurisdiction && this.caseType) {
37472
37510
  if (this.caseId === caseId) {
37473
37511
  return this.workAllocationService.getTasksByCaseIdAndEventId(eventId, caseId, this.caseType, this.jurisdiction)
@@ -37481,9 +37519,6 @@ class EventStartGuard {
37481
37519
  return of(false);
37482
37520
  }));
37483
37521
  }
37484
- shouldSkipDuplicateWorkAllocationCall() {
37485
- return this.router.getCurrentNavigation()?.extras?.state?.[EVENT_START_FIRST_PAGE_REDIRECT] === true;
37486
- }
37487
37522
  checkTaskInEventNotRequired(payload, caseId, taskId, eventId, userId) {
37488
37523
  if (!payload || !payload.tasks) {
37489
37524
  return true;