@hmcts/ccd-case-ui-toolkit 6.0.2-migration-dynamic-list-rc1 → 6.0.2-migration-dynamic-list-rc2

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.
Files changed (33) hide show
  1. package/bundles/hmcts-ccd-case-ui-toolkit.umd.js +483 -255
  2. package/bundles/hmcts-ccd-case-ui-toolkit.umd.js.map +1 -1
  3. package/bundles/hmcts-ccd-case-ui-toolkit.umd.min.js +1 -1
  4. package/bundles/hmcts-ccd-case-ui-toolkit.umd.min.js.map +1 -1
  5. package/esm2015/lib/shared/components/case-viewer/case-full-access-view/case-full-access-view.component.js +20 -3
  6. package/esm2015/lib/shared/components/palette/case-flag/components/select-flag-type/select-flag-type.component.js +30 -19
  7. package/esm2015/lib/shared/components/palette/case-flag/write-case-flag-field.component.js +35 -24
  8. package/esm2015/lib/shared/components/palette/datetime-picker/datetime-picker.component.js +10 -3
  9. package/esm2015/lib/shared/components/search-result/search-result.component.js +10 -14
  10. package/esm2015/lib/shared/directives/conditional-show/domain/conditional-show.model.js +103 -200
  11. package/esm2015/lib/shared/directives/conditional-show/services/condition-parser.service.js +201 -0
  12. package/esm2015/lib/shared/directives/conditional-show/services/condition.peg.js +103 -0
  13. package/esm2015/lib/shared/domain/case-flag/hmcts-service-detail.model.js +1 -1
  14. package/esm2015/lib/shared/services/case-flag/case-flag-refdata.service.js +25 -4
  15. package/fesm2015/hmcts-ccd-case-ui-toolkit.js +499 -235
  16. package/fesm2015/hmcts-ccd-case-ui-toolkit.js.map +1 -1
  17. package/lib/shared/components/case-viewer/case-full-access-view/case-full-access-view.component.d.ts +1 -0
  18. package/lib/shared/components/case-viewer/case-full-access-view/case-full-access-view.component.d.ts.map +1 -1
  19. package/lib/shared/components/palette/case-flag/components/select-flag-type/select-flag-type.component.d.ts +3 -1
  20. package/lib/shared/components/palette/case-flag/components/select-flag-type/select-flag-type.component.d.ts.map +1 -1
  21. package/lib/shared/components/palette/case-flag/write-case-flag-field.component.d.ts +2 -0
  22. package/lib/shared/components/palette/case-flag/write-case-flag-field.component.d.ts.map +1 -1
  23. package/lib/shared/components/palette/datetime-picker/datetime-picker.component.d.ts.map +1 -1
  24. package/lib/shared/directives/conditional-show/domain/conditional-show.model.d.ts +13 -30
  25. package/lib/shared/directives/conditional-show/domain/conditional-show.model.d.ts.map +1 -1
  26. package/lib/shared/directives/conditional-show/services/condition-parser.service.d.ts +30 -0
  27. package/lib/shared/directives/conditional-show/services/condition-parser.service.d.ts.map +1 -0
  28. package/lib/shared/directives/conditional-show/services/condition.peg.d.ts +3 -0
  29. package/lib/shared/directives/conditional-show/services/condition.peg.d.ts.map +1 -0
  30. package/lib/shared/domain/case-flag/hmcts-service-detail.model.d.ts.map +1 -1
  31. package/lib/shared/services/case-flag/case-flag-refdata.service.d.ts +14 -3
  32. package/lib/shared/services/case-flag/case-flag-refdata.service.d.ts.map +1 -1
  33. package/package.json +1 -1
@@ -12,9 +12,10 @@ import * as i1$2 from '@angular/common/http';
12
12
  import { HttpErrorResponse, HttpHeaders, HttpParams } from '@angular/common/http';
13
13
  import { catchError, map, publish, refCount, debounceTime, delay, distinctUntilChanged, finalize, publishReplay, take, tap, first, switchMap, takeUntil, filter } from 'rxjs/operators';
14
14
  import { Type, Expose, plainToClassFromExist, plainToClass } from 'class-transformer';
15
- import * as _ from 'underscore';
16
15
  import * as moment from 'moment';
17
16
  import { __decorate, __metadata } from 'tslib';
17
+ import * as _ from 'underscore';
18
+ import { generate } from 'pegjs';
18
19
  import { isUndefined } from 'util';
19
20
  import { StateMachine } from '@edium/fsm';
20
21
  import * as i1$3 from '@angular/material/dialog';
@@ -3802,168 +3803,165 @@ FieldsUtils.ɵprov = i0.ɵɵdefineInjectable({ token: FieldsUtils, factory: Fiel
3802
3803
  type: Injectable
3803
3804
  }], null, null); })();
3804
3805
 
3805
- class ShowCondition {
3806
- // Expects a show condition of the form: <fieldName>="string"
3807
- constructor(condition) {
3808
- this.condition = condition;
3809
- this.orConditions = null;
3810
- this.andConditions = null;
3811
- if (!!condition) {
3812
- if (condition.search(ShowCondition.OR_CONDITION_REGEXP) !== -1) {
3813
- this.orConditions = condition.split(ShowCondition.OR_CONDITION_REGEXP);
3814
- }
3815
- else {
3816
- this.andConditions = condition.split(ShowCondition.AND_CONDITION_REGEXP);
3817
- }
3818
- }
3819
- }
3820
- static addPathPrefixToCondition(showCondition, pathPrefix) {
3821
- if (!pathPrefix || pathPrefix === '') {
3822
- return showCondition;
3823
- }
3824
- if (showCondition.search(ShowCondition.OR_CONDITION_REGEXP) !== -1) {
3825
- let orConditions = showCondition.split(ShowCondition.OR_CONDITION_REGEXP);
3826
- orConditions = this.extractConditions(orConditions, pathPrefix);
3827
- return orConditions.join(' OR ');
3828
- }
3829
- else {
3830
- let andConditions = showCondition.split(ShowCondition.AND_CONDITION_REGEXP);
3831
- andConditions = this.extractConditions(andConditions, pathPrefix);
3832
- return andConditions.join(' AND ');
3833
- }
3806
+ const conditionSource = `{
3807
+ function flat(arr, depth = 1) {
3808
+ var flatten = function (arr, depth = 1) {
3809
+ if (depth) return arr;
3810
+
3811
+ // Otherwise, concatenate into the parent array
3812
+ return arr.reduce(function (acc, val) {
3813
+ return acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val);
3814
+ }, []);
3815
+
3816
+ };
3817
+
3818
+ return flatten(arr, depth - 1);
3834
3819
  }
3835
- // Cache instances so that we can cache results more effectively
3836
- static getInstance(condition) {
3837
- let instance = this.instanceCache.get(condition);
3838
- if (!instance) {
3839
- instance = new ShowCondition(condition);
3840
- this.instanceCache.set(condition, instance);
3820
+ }
3821
+
3822
+ Start
3823
+ = Formula
3824
+
3825
+ Formula
3826
+ = EnclosedFormula
3827
+ / OpenFormula
3828
+
3829
+ EnclosedFormula
3830
+ = bracket formula:OpenFormula bracket join:(JoinComparator)*
3831
+ { return flat([ [formula], join[0] ], 1) }
3832
+
3833
+ OpenFormula
3834
+ = eq:OpenEqualityCheck joins:(JoinComparator)*
3835
+ { return flat([ eq, flat(joins) ]) }
3836
+
3837
+ JoinComparator
3838
+ = comp:Comparator eq:OpenEqualityCheck
3839
+ { return [comp, eq]; }
3840
+ / CompoundJoinComparator
3841
+
3842
+ CompoundJoinComparator
3843
+ = comp:Comparator bracket f:OpenFormula bracket
3844
+ { return [comp, f ] }
3845
+
3846
+ OpenEqualityCheck
3847
+ = fr:FieldRef _? op:operator _? val:Value
3848
+ { return { fieldReference: fr, comparator: op, value: val } }
3849
+
3850
+ Comparator
3851
+ = _? c:'AND' _?
3852
+ { return c; }
3853
+ / _? c:'OR' _?
3854
+ { return c; }
3855
+
3856
+ Word
3857
+ = l:Letter+
3858
+ { return l.join(""); }
3859
+
3860
+ Letter
3861
+ = [a-zA-Z]
3862
+
3863
+ Value
3864
+ = v:quotedValue / v:Word
3865
+ { return v.join("") }
3866
+ / v:number
3867
+ { return parseInt(v.join("")) }
3868
+
3869
+ FieldRef
3870
+ = FieldReference / MetadataFieldReference
3871
+
3872
+ MetadataFieldReference
3873
+ = s1:openSquare fr:FieldReference s2:closeSquare
3874
+ { return s1 + fr + s2 }
3875
+
3876
+ FieldReference
3877
+ = characters:[A-Za-z0-9._-]+ { return characters.join(""); }
3878
+
3879
+ openSquare
3880
+ = "["
3881
+
3882
+ closeSquare
3883
+ = "]"
3884
+
3885
+ number
3886
+ = [0-9]+
3887
+
3888
+ quotedValue
3889
+ = '"'val:[A-Za-z0-9.,* _&()/-]*'"'
3890
+ { return val.join(""); }
3891
+
3892
+ bracket
3893
+ = (_? "("+ _? / _? ")"+ _? )
3894
+
3895
+ operator
3896
+ = "=" / "!=" / "CONTAINS"
3897
+
3898
+ ws "Whitespace"
3899
+ = [ \t]
3900
+
3901
+ _ "One or more whitespaces"
3902
+ = ws+
3903
+
3904
+ nl "New line"
3905
+ = "\\n"`;
3906
+ var peg = generate(conditionSource);
3907
+
3908
+ class ConditionParser {
3909
+ /**
3910
+ * Parse the raw formula and output structured condition data
3911
+ * that can be used in evaluating show/hide logic
3912
+ * @param condition raw formula e.g. TextField = "Hello"
3913
+ */
3914
+ static parse(condition) {
3915
+ if (!condition) {
3916
+ return null;
3841
3917
  }
3842
- return instance;
3918
+ ;
3919
+ condition = condition.replace(/CONTAINS/g, ' CONTAINS');
3920
+ return peg.parse(condition.trim(), {});
3843
3921
  }
3844
3922
  /**
3845
- * Determine whether a ShowCondition model is affected by fields that have
3846
- * a display_context of HIDDEN or READONLY, which means they aren't able to
3847
- * be changed by the user's actions.
3848
- *
3849
- * @param showCondition The ShowCondition model to evaluate.
3850
- * @param caseFields Inspected to see appropriate display_contexts.
3923
+ * Evaluate the current fields against the conditions
3924
+ * @param fields the current page fields and their value
3925
+ * @param conditions The PegJS formula output
3851
3926
  */
3852
- static hiddenCannotChange(showCondition, caseFields) {
3853
- if (showCondition && caseFields) {
3854
- const conditions = showCondition.andConditions || showCondition.orConditions;
3855
- if (conditions && conditions.length > 0) {
3856
- let allUnchangeable = true;
3857
- for (const condition of conditions) {
3858
- const [field] = ShowCondition.getField(condition);
3859
- const path = field.split('.');
3860
- let head = path.shift();
3861
- let caseField = caseFields.find(cf => cf.id === head);
3862
- while (path.length > 0) {
3863
- head = path.shift();
3864
- if (caseField) {
3865
- // Jump out if this is HIDDEN or READONLY, regardless of whether or not it's
3866
- // complex or a collection - nested fields will "inherit" the display_context.
3867
- if (['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1) {
3868
- break;
3869
- }
3870
- // Consider what type of field this is.
3871
- const ft = caseField.field_type;
3872
- switch (ft.type) {
3873
- case 'Collection':
3874
- if (ft.collection_field_type.type === 'Complex' && ft.collection_field_type.complex_fields) {
3875
- caseField = ft.collection_field_type.complex_fields.find(cf => cf.id === head);
3876
- }
3877
- break;
3878
- case 'Complex':
3879
- if (ft.complex_fields) {
3880
- caseField = ft.complex_fields.find(cf => cf.id === head);
3881
- }
3882
- break;
3883
- }
3884
- }
3885
- }
3886
- if (caseField) {
3887
- allUnchangeable = allUnchangeable && ['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1;
3888
- }
3927
+ static evaluate(fields, conditions, path) {
3928
+ if (!conditions || conditions.length === 0) {
3929
+ return true;
3930
+ }
3931
+ ;
3932
+ const validJoinComparators = ['AND', 'OR'];
3933
+ const result = conditions.reduce((accumulator, condition, index) => {
3934
+ const isJoinComparator = (comparator) => (typeof comparator === 'string' && validJoinComparators.indexOf(comparator) !== -1);
3935
+ if (isJoinComparator(condition)) {
3936
+ return accumulator;
3937
+ }
3938
+ ;
3939
+ let currentConditionResult = true;
3940
+ if (Array.isArray(condition)) {
3941
+ currentConditionResult = this.evaluate(fields, condition);
3942
+ if (isJoinComparator(conditions[index - 1])) {
3943
+ return this.evaluateJoin(accumulator, conditions[index - 1], currentConditionResult);
3889
3944
  }
3890
- return allUnchangeable;
3891
3945
  }
3892
- }
3893
- return false;
3894
- }
3895
- static extractConditions(conditionsArray, pathPrefix) {
3896
- const extracted = conditionsArray.map(condition => {
3897
- if (condition.startsWith(pathPrefix)) {
3898
- return condition;
3946
+ if (condition.comparator) {
3947
+ const formula = condition.fieldReference + condition.comparator + condition.value;
3948
+ currentConditionResult = this.matchEqualityCondition(fields, formula, path);
3899
3949
  }
3900
- return `${pathPrefix}.${condition}`;
3901
- });
3902
- return extracted;
3903
- }
3904
- static getField(condition) {
3905
- let separator = ShowCondition.CONTAINS;
3906
- if (condition.indexOf(ShowCondition.CONTAINS) < 0) {
3907
- separator = ShowCondition.CONDITION_EQUALS;
3908
- if (condition.indexOf(ShowCondition.CONDITION_NOT_EQUALS) > -1) {
3909
- separator = ShowCondition.CONDITION_NOT_EQUALS;
3950
+ if (isJoinComparator(conditions[index - 1])) {
3951
+ return this.evaluateJoin(accumulator, conditions[index - 1], currentConditionResult);
3910
3952
  }
3911
- }
3912
- return [condition.split(separator)[0], separator];
3913
- }
3914
- match(fields, path) {
3915
- if (!this.condition) {
3916
- return true;
3917
- }
3918
- return this.matchAndConditions(fields, this.updatePathName(path));
3919
- }
3920
- matchByContextFields(contextFields) {
3921
- return this.match(FieldsUtils.toValuesMap(contextFields));
3922
- }
3923
- /**
3924
- * Determine whether this is affected by fields that have a display_context
3925
- * of HIDDEN or READONLY, which means they aren't able to be changed by the
3926
- * user's actions.
3927
- *
3928
- * @param caseFields Inspected to see appropriate display_contexts.
3929
- */
3930
- hiddenCannotChange(caseFields) {
3931
- return ShowCondition.hiddenCannotChange(this, caseFields);
3932
- }
3933
- /**
3934
- * Path Name gets updated for complex sub fields
3935
- * @param path Path name.
3936
- */
3937
- updatePathName(path) {
3938
- if (path && path.split(/[_]+/g).length > 0) {
3939
- const [pathName, ...pathTail] = path.split(/[_]+/g);
3940
- const pathFinalIndex = pathTail.pop();
3941
- const pathTailString = pathTail.toString();
3942
- let mappedPathTail;
3943
- mappedPathTail = pathTail.map((value) => {
3944
- return Number(pathFinalIndex) === Number(value) ? pathName : value;
3945
- });
3946
- return pathTailString !== mappedPathTail.toString()
3947
- ? `${pathName}_${mappedPathTail.join('_')}_${pathFinalIndex}`
3948
- : path;
3949
- }
3950
- else {
3951
- return path;
3952
- }
3953
+ return currentConditionResult;
3954
+ }, true);
3955
+ return result;
3953
3956
  }
3954
- matchAndConditions(fields, path) {
3955
- if (!!this.orConditions) {
3956
- return this.orConditions.some(orCondition => this.matchEqualityCondition(fields, orCondition, path));
3957
- }
3958
- else if (!!this.andConditions) {
3959
- return this.andConditions.every(andCondition => this.matchEqualityCondition(fields, andCondition, path));
3960
- }
3961
- else {
3962
- return false;
3957
+ static evaluateJoin(leftResult, comparator, rightResult) {
3958
+ switch (comparator) {
3959
+ case 'OR': return leftResult || rightResult;
3960
+ case 'AND': return leftResult && rightResult;
3963
3961
  }
3964
3962
  }
3965
- matchEqualityCondition(fields, condition, path) {
3966
- const [field, conditionSeparator] = ShowCondition.getField(condition);
3963
+ static matchEqualityCondition(fields, condition, path) {
3964
+ const [field, conditionSeparator] = this.getField(condition);
3967
3965
  const [head, ...tail] = field.split('.');
3968
3966
  const currentValue = this.findValueForComplexCondition(fields, head, tail, path);
3969
3967
  const expectedValue = this.unquoted(condition.split(conditionSeparator)[1]);
@@ -3974,7 +3972,29 @@ class ShowCondition {
3974
3972
  return this.checkValueEquals(expectedValue, currentValue, conditionSeparator);
3975
3973
  }
3976
3974
  }
3977
- checkValueEquals(expectedValue, currentValue, conditionSeparaor) {
3975
+ static getValue(fields, head) {
3976
+ if (this.isDynamicList(fields[head])) {
3977
+ return fields[head].value.code;
3978
+ }
3979
+ else {
3980
+ return fields[head];
3981
+ }
3982
+ }
3983
+ static isDynamicList(dynamiclist) {
3984
+ return !_.isEmpty(dynamiclist) &&
3985
+ (_.has(dynamiclist, 'value') && _.has(dynamiclist, 'list_items'));
3986
+ }
3987
+ static getField(condition) {
3988
+ let separator = ShowCondition.CONTAINS;
3989
+ if (condition.indexOf(ShowCondition.CONTAINS) < 0) {
3990
+ separator = ShowCondition.CONDITION_EQUALS;
3991
+ if (condition.indexOf(ShowCondition.CONDITION_NOT_EQUALS) > -1) {
3992
+ separator = ShowCondition.CONDITION_NOT_EQUALS;
3993
+ }
3994
+ }
3995
+ return [condition.split(separator)[0], separator];
3996
+ }
3997
+ static checkValueEquals(expectedValue, currentValue, conditionSeparaor) {
3978
3998
  if (expectedValue.search('[,]') > -1) { // for multi-select list
3979
3999
  return this.checkMultiSelectListEquals(expectedValue, currentValue, conditionSeparaor);
3980
4000
  }
@@ -3994,7 +4014,7 @@ class ShowCondition {
3994
4014
  }
3995
4015
  }
3996
4016
  }
3997
- checkValueNotEquals(expectedValue, currentValue) {
4017
+ static checkValueNotEquals(expectedValue, currentValue) {
3998
4018
  const formatCurrentValue = currentValue ? currentValue.toString().trim() : '';
3999
4019
  if ('*' === expectedValue && formatCurrentValue !== '') {
4000
4020
  return false;
@@ -4002,7 +4022,7 @@ class ShowCondition {
4002
4022
  const formatExpectedValue = expectedValue ? expectedValue.toString().trim() : '';
4003
4023
  return formatCurrentValue != formatExpectedValue; // tslint:disable-line
4004
4024
  }
4005
- checkMultiSelectListEquals(expectedValue, currentValue, conditionSeparator) {
4025
+ static checkMultiSelectListEquals(expectedValue, currentValue, conditionSeparator) {
4006
4026
  const expectedValues = expectedValue.split(',').sort().toString();
4007
4027
  const values = currentValue ? currentValue.sort().toString() : '';
4008
4028
  if (conditionSeparator === ShowCondition.CONDITION_NOT_EQUALS) {
@@ -4012,7 +4032,7 @@ class ShowCondition {
4012
4032
  return expectedValues === values;
4013
4033
  }
4014
4034
  }
4015
- checkValueContains(expectedValue, currentValue) {
4035
+ static checkValueContains(expectedValue, currentValue) {
4016
4036
  if (expectedValue.search(',') > -1) {
4017
4037
  const expectedValues = expectedValue.split(',').sort();
4018
4038
  const values = currentValue ? currentValue.sort().toString() : '';
@@ -4023,7 +4043,11 @@ class ShowCondition {
4023
4043
  return values.search(expectedValue) >= 0;
4024
4044
  }
4025
4045
  }
4026
- findValueForComplexCondition(fields, head, tail, path) {
4046
+ static unquoted(str) {
4047
+ const res = str.replace(/^"|"$/g, '');
4048
+ return res;
4049
+ }
4050
+ static findValueForComplexCondition(fields, head, tail, path) {
4027
4051
  if (!fields) {
4028
4052
  return undefined;
4029
4053
  }
@@ -4039,7 +4063,7 @@ class ShowCondition {
4039
4063
  }
4040
4064
  }
4041
4065
  }
4042
- findValueForComplexConditionForPathIfAny(fields, head, tail, path) {
4066
+ static findValueForComplexConditionForPathIfAny(fields, head, tail, path) {
4043
4067
  if (path) {
4044
4068
  const [_, ...pathTail] = path.split(/[_]+/g);
4045
4069
  return this.findValueForComplexCondition(fields[head], tail[0], tail.slice(1), pathTail.join('_'));
@@ -4048,9 +4072,9 @@ class ShowCondition {
4048
4072
  return this.findValueForComplexCondition(fields[head], tail[0], tail.slice(1), path);
4049
4073
  }
4050
4074
  }
4051
- findValueForComplexConditionInArray(fields, head, tail, path) {
4075
+ static findValueForComplexConditionInArray(fields, head, tail, path) {
4052
4076
  // use the path to resolve which array element we refer to
4053
- if (path && path.startsWith(head)) {
4077
+ if (path.startsWith(head)) {
4054
4078
  const [_, ...pathTail] = path.split(/[_]+/g);
4055
4079
  if (pathTail.length > 0) {
4056
4080
  try {
@@ -4059,42 +4083,221 @@ class ShowCondition {
4059
4083
  return (fields[head][arrayIndex] !== undefined) ? this.findValueForComplexCondition(fields[head][arrayIndex]['value'], tail[0], tail.slice(1), dropNumberPath.join('_')) : null;
4060
4084
  }
4061
4085
  catch (e) {
4062
- console.log('Error while parsing number', pathTail[0], e);
4086
+ console.error('Error while parsing number', pathTail[0], e);
4063
4087
  }
4064
4088
  }
4065
4089
  }
4066
4090
  else {
4067
- console.log('Path in formArray should start with ', head, ', full path: ', path);
4091
+ console.error('Path in formArray should start with ', head, ', full path: ', path);
4068
4092
  }
4069
4093
  }
4070
- getValue(fields, head) {
4071
- if (this.isDynamicList(fields[head])) {
4072
- return fields[head].value.code;
4094
+ static removeStarChar(str) {
4095
+ if (str && str.indexOf('*') > -1) {
4096
+ return str.substring(0, str.indexOf('*'));
4097
+ }
4098
+ return str;
4099
+ }
4100
+ static okIfBothEmpty(right, value) {
4101
+ return value === null && (right === '');
4102
+ }
4103
+ }
4104
+
4105
+ class ShowCondition {
4106
+ // Expects a show condition of the form: <fieldName>="string"
4107
+ constructor(condition) {
4108
+ this.condition = condition;
4109
+ this.conditions = [];
4110
+ if (!!condition) {
4111
+ this.conditions = ConditionParser.parse(condition);
4112
+ }
4113
+ }
4114
+ static addPathPrefixToCondition(showCondition, pathPrefix) {
4115
+ if (!pathPrefix || pathPrefix === '') {
4116
+ return showCondition;
4117
+ }
4118
+ if (!showCondition) {
4119
+ return '';
4120
+ }
4121
+ const formula = ConditionParser.parse(showCondition);
4122
+ if (!formula) {
4123
+ return showCondition;
4124
+ }
4125
+ this.processedList = [];
4126
+ showCondition = showCondition.replace(/CONTAINS/g, ' CONTAINS');
4127
+ const processedCondition = this.processAddPathPrefixToCondition(formula, pathPrefix, showCondition);
4128
+ return processedCondition.replace(/ CONTAINS/g, 'CONTAINS');
4129
+ }
4130
+ static processAddPathPrefixToCondition(formula, pathPrefix, originalCondition) {
4131
+ let finalCondition = originalCondition;
4132
+ if (Array.isArray(formula)) {
4133
+ formula.forEach(condition => {
4134
+ if (typeof condition === 'string' && this.validJoinComparators.indexOf(condition) !== -1) {
4135
+ // do nothing
4136
+ }
4137
+ else {
4138
+ if (Array.isArray(condition)) {
4139
+ finalCondition = this.processAddPathPrefixToCondition(condition, pathPrefix, finalCondition);
4140
+ }
4141
+ else {
4142
+ finalCondition = this.extractConditions(condition, pathPrefix, finalCondition);
4143
+ }
4144
+ }
4145
+ });
4073
4146
  }
4074
4147
  else {
4075
- return fields[head];
4148
+ finalCondition = this.extractConditions(formula, pathPrefix, finalCondition);
4076
4149
  }
4150
+ return finalCondition;
4077
4151
  }
4078
- isDynamicList(dynamiclist) {
4079
- return !_.isEmpty(dynamiclist) &&
4080
- (_.has(dynamiclist, 'value') && _.has(dynamiclist, 'list_items'));
4152
+ static extractConditions(condition, pathPrefix, originalCondition) {
4153
+ if (condition.fieldReference.startsWith(pathPrefix)) {
4154
+ return originalCondition;
4155
+ }
4156
+ else {
4157
+ if (originalCondition.indexOf(condition.fieldReference) > -1) {
4158
+ if (this.processedList && this.processedList.indexOf(condition.fieldReference) === -1) {
4159
+ this.processedList.push(condition.fieldReference);
4160
+ const regularExp = new RegExp('(\\b)' + condition.fieldReference + '(?=[^"]*(?:"[^"]*"[^"]*)*$)(\\b)', 'g');
4161
+ return originalCondition.replace(regularExp, pathPrefix + '.' + condition.fieldReference);
4162
+ }
4163
+ else {
4164
+ return originalCondition;
4165
+ }
4166
+ }
4167
+ }
4081
4168
  }
4082
- unquoted(str) {
4083
- return str.replace(/(?:^")|(?:"$)/g, '');
4169
+ // Cache instances so that we can cache results more effectively
4170
+ static getInstance(condition) {
4171
+ let instance = this.instanceCache.get(condition);
4172
+ if (!instance) {
4173
+ instance = new ShowCondition(condition);
4174
+ this.instanceCache.set(condition, instance);
4175
+ }
4176
+ return instance;
4084
4177
  }
4085
- removeStarChar(str) {
4086
- return str.substring(0, str.length - 1);
4178
+ static getField(condition) {
4179
+ let separator = ShowCondition.CONTAINS;
4180
+ if (condition.indexOf(ShowCondition.CONTAINS) < 0) {
4181
+ separator = ShowCondition.CONDITION_EQUALS;
4182
+ if (condition.indexOf(ShowCondition.CONDITION_NOT_EQUALS) > -1) {
4183
+ separator = ShowCondition.CONDITION_NOT_EQUALS;
4184
+ }
4185
+ }
4186
+ return [condition.split(separator)[0], separator];
4087
4187
  }
4088
- okIfBothEmpty(right, value) {
4089
- return value === null && (right === '');
4188
+ static getConditions(formula) {
4189
+ const conditionList = [];
4190
+ if (!!formula) {
4191
+ const newFormula = typeof formula === 'string' ? JSON.parse(formula) : formula;
4192
+ if (Array.isArray(newFormula)) {
4193
+ newFormula.forEach(condition => {
4194
+ if (!(typeof condition === 'string' && this.validJoinComparators.indexOf(condition) !== -1)) {
4195
+ if (Array.isArray(condition)) {
4196
+ conditionList.push(ShowCondition.getConditions(condition).toString());
4197
+ }
4198
+ else {
4199
+ conditionList.push(condition.fieldReference + condition.comparator + condition.value);
4200
+ }
4201
+ }
4202
+ });
4203
+ }
4204
+ else {
4205
+ conditionList.push(newFormula.fieldReference + newFormula.comparator + newFormula.value);
4206
+ }
4207
+ }
4208
+ return conditionList.toString();
4209
+ }
4210
+ /**
4211
+ * Determine whether a ShowCondition model is affected by fields that have
4212
+ * a display_context of HIDDEN or READONLY, which means they aren't able to
4213
+ * be changed by the user's actions.
4214
+ *
4215
+ * @param showCondition The ShowCondition model to evaluate.
4216
+ * @param caseFields Inspected to see appropriate display_contexts.
4217
+ */
4218
+ static hiddenCannotChange(showCondition, caseFields) {
4219
+ if (showCondition && showCondition.conditions.length && caseFields) {
4220
+ const conditions = this.getConditions(showCondition.conditions).split(',');
4221
+ if (conditions && conditions.length > 0) {
4222
+ let allUnchangeable = true;
4223
+ for (const condition of conditions) {
4224
+ const [field] = ShowCondition.getField(condition);
4225
+ const path = field.split('.');
4226
+ let head = path.shift();
4227
+ let caseField = caseFields.find(cf => cf.id === head);
4228
+ while (path.length > 0) {
4229
+ head = path.shift();
4230
+ if (caseField) {
4231
+ // Jump out if this is HIDDEN or READONLY, regardless of whether or not it's
4232
+ // complex or a collection - nested fields will "inherit" the display_context.
4233
+ if (['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1) {
4234
+ break;
4235
+ }
4236
+ // Consider what type of field this is.
4237
+ const ft = caseField.field_type;
4238
+ switch (ft.type) {
4239
+ case 'Collection':
4240
+ if (ft.collection_field_type.type === 'Complex' && ft.collection_field_type.complex_fields) {
4241
+ caseField = ft.collection_field_type.complex_fields.find(cf => cf.id === head);
4242
+ }
4243
+ break;
4244
+ case 'Complex':
4245
+ if (ft.complex_fields) {
4246
+ caseField = ft.complex_fields.find(cf => cf.id === head);
4247
+ }
4248
+ break;
4249
+ }
4250
+ }
4251
+ }
4252
+ if (caseField) {
4253
+ allUnchangeable = allUnchangeable && ['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1;
4254
+ }
4255
+ }
4256
+ return allUnchangeable;
4257
+ }
4258
+ }
4259
+ return false;
4260
+ }
4261
+ match(fields, path) {
4262
+ return ConditionParser.evaluate(fields, this.conditions, this.updatePathName(path));
4263
+ }
4264
+ updatePathName(path) {
4265
+ if (path && path.split(/[_]+/g).length > 0) {
4266
+ /* tslint:disable-next-line */
4267
+ let [pathName, ...pathTail] = path.split(/[_]+/g);
4268
+ const pathFinalIndex = pathTail.pop();
4269
+ const pathTailString = pathTail.toString();
4270
+ pathTail = pathTail.map((value) => {
4271
+ return Number(pathFinalIndex) === Number(value) ? pathName : value;
4272
+ });
4273
+ return pathTailString !== pathTail.toString()
4274
+ ? `${pathName}_${pathTail.join('_')}_${pathFinalIndex}`
4275
+ : path;
4276
+ }
4277
+ else {
4278
+ return path;
4279
+ }
4280
+ }
4281
+ matchByContextFields(contextFields) {
4282
+ return this.match(FieldsUtils.toValuesMap(contextFields));
4283
+ }
4284
+ /**
4285
+ * Determine whether this is affected by fields that have a display_context
4286
+ * of HIDDEN or READONLY, which means they aren't able to be changed by the
4287
+ * user's actions.
4288
+ *
4289
+ * @param caseFields Inspected to see appropriate display_contexts.
4290
+ */
4291
+ hiddenCannotChange(caseFields) {
4292
+ return ShowCondition.hiddenCannotChange(this, caseFields);
4090
4293
  }
4091
4294
  }
4092
- ShowCondition.AND_CONDITION_REGEXP = new RegExp('\\sAND\\s(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)', 'g');
4093
- ShowCondition.OR_CONDITION_REGEXP = new RegExp('\\sOR\\s(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)', 'g');
4094
4295
  ShowCondition.CONDITION_NOT_EQUALS = '!=';
4095
4296
  ShowCondition.CONDITION_EQUALS = '=';
4096
4297
  ShowCondition.CONTAINS = 'CONTAINS';
4097
4298
  ShowCondition.instanceCache = new Map();
4299
+ ShowCondition.validJoinComparators = ['AND', 'OR'];
4300
+ ShowCondition.processedList = [];
4098
4301
 
4099
4302
  class Constants {
4100
4303
  }
@@ -5904,13 +6107,14 @@ class CaseFlagRefdataService {
5904
6107
  return of(null);
5905
6108
  }
5906
6109
  /**
5907
- * Retrieves the HMCTS service details for a jurisdiction or service, including service code. (For example, the "SSCS"
5908
- * service has a corresponding service code of "BBA3".)
6110
+ * Retrieves the HMCTS service details for a jurisdiction or service, including service codes. More than one
6111
+ * service code may be present. For example, the Divorce jurisdiction/service has corresponding service codes of
6112
+ * "ABA1" and "ABA2".
5909
6113
  *
5910
6114
  * @param serviceNames The service name(s) to look up, comma-separated if more than one
5911
6115
  * @returns An `Observable` of an array of service details
5912
6116
  */
5913
- getHmctsServiceDetails(serviceNames) {
6117
+ getHmctsServiceDetailsByServiceName(serviceNames) {
5914
6118
  let url = this.appConfig.getLocationRefApiUrl();
5915
6119
  if (url) {
5916
6120
  url += '/orgServices';
@@ -5921,6 +6125,26 @@ class CaseFlagRefdataService {
5921
6125
  }
5922
6126
  return of(null);
5923
6127
  }
6128
+ /**
6129
+ * Retrieves the HMCTS service details for a case type, including service code. For example, the
6130
+ * "FinancialRemedyContested" case type is associated with the Divorce jurisdiction/service and service code "ABA2".
6131
+ *
6132
+ * Note that a case type might not be associated with any service codes of a jurisdiction or service.
6133
+ *
6134
+ * @param caseTypeId The case type ID to look up
6135
+ * @returns An `Observable` of an array of service details
6136
+ */
6137
+ getHmctsServiceDetailsByCaseType(caseTypeId) {
6138
+ let url = this.appConfig.getLocationRefApiUrl();
6139
+ if (url) {
6140
+ url += '/orgServices';
6141
+ if (caseTypeId) {
6142
+ url += `?ccdCaseType=${caseTypeId}`;
6143
+ }
6144
+ return this.http.get(url, { observe: 'body' });
6145
+ }
6146
+ return of(null);
6147
+ }
5924
6148
  }
5925
6149
  CaseFlagRefdataService.ɵfac = function CaseFlagRefdataService_Factory(t) { return new (t || CaseFlagRefdataService)(i0.ɵɵinject(HttpService), i0.ɵɵinject(AbstractAppConfig)); };
5926
6150
  CaseFlagRefdataService.ɵprov = i0.ɵɵdefineInjectable({ token: CaseFlagRefdataService, factory: CaseFlagRefdataService.ɵfac });
@@ -10802,7 +11026,7 @@ function WriteCaseFlagFieldComponent_div_1_ng_container_5_Template(rf, ctx) { if
10802
11026
  } if (rf & 2) {
10803
11027
  const ctx_r8 = i0.ɵɵnextContext(2);
10804
11028
  i0.ɵɵadvance(1);
10805
- i0.ɵɵproperty("formGroup", ctx_r8.caseFlagParentFormGroup)("jurisdiction", ctx_r8.jurisdiction);
11029
+ i0.ɵɵproperty("formGroup", ctx_r8.caseFlagParentFormGroup)("jurisdiction", ctx_r8.jurisdiction)("caseTypeId", ctx_r8.caseTypeId)("hmctsServiceId", ctx_r8.hmctsServiceId);
10806
11030
  } }
10807
11031
  function WriteCaseFlagFieldComponent_div_1_ng_container_6_Template(rf, ctx) { if (rf & 1) {
10808
11032
  const _r17 = i0.ɵɵgetCurrentView();
@@ -10836,7 +11060,7 @@ function WriteCaseFlagFieldComponent_div_1_Template(rf, ctx) { if (rf & 1) {
10836
11060
  i0.ɵɵtext(3);
10837
11061
  i0.ɵɵelementEnd();
10838
11062
  i0.ɵɵtemplate(4, WriteCaseFlagFieldComponent_div_1_ng_container_4_Template, 2, 2, "ng-container", 11);
10839
- i0.ɵɵtemplate(5, WriteCaseFlagFieldComponent_div_1_ng_container_5_Template, 2, 2, "ng-container", 11);
11063
+ i0.ɵɵtemplate(5, WriteCaseFlagFieldComponent_div_1_ng_container_5_Template, 2, 4, "ng-container", 11);
10840
11064
  i0.ɵɵtemplate(6, WriteCaseFlagFieldComponent_div_1_ng_container_6_Template, 2, 3, "ng-container", 11);
10841
11065
  i0.ɵɵtemplate(7, WriteCaseFlagFieldComponent_div_1_ng_container_7_Template, 2, 2, "ng-container", 11);
10842
11066
  i0.ɵɵelementEnd();
@@ -10935,29 +11159,40 @@ class WriteCaseFlagFieldComponent extends AbstractFieldWriteComponent {
10935
11159
  }
10936
11160
  }), true);
10937
11161
  this.createFlagCaption = CaseFlagText.CAPTION;
10938
- // Get the jurisdiction from the CaseView object in the snapshot data (required for retrieving the available flag
11162
+ // Get the case type ID from the CaseView object in the snapshot data (required for retrieving the available flag
10939
11163
  // types for a case)
10940
- if (this.route.snapshot.data.case && this.route.snapshot.data.case.case_type &&
10941
- this.route.snapshot.data.case.case_type.jurisdiction) {
10942
- this.jurisdiction = this.route.snapshot.data.case.case_type.jurisdiction.id;
11164
+ if (this.route.snapshot.data.case && this.route.snapshot.data.case.case_type) {
11165
+ this.caseTypeId = this.route.snapshot.data.case.case_type.id;
11166
+ // Get the jurisdiction (required for retrieving the available flag types if unable to determine using case type ID)
11167
+ if (this.route.snapshot.data.case.case_type.jurisdiction) {
11168
+ this.jurisdiction = this.route.snapshot.data.case.case_type.jurisdiction.id;
11169
+ }
10943
11170
  }
10944
11171
  // Extract all flags-related data from the CaseEventTrigger object in the snapshot data
10945
- if (this.route.snapshot.data.eventTrigger && this.route.snapshot.data.eventTrigger.case_fields) {
10946
- this.flagsData = (this.route.snapshot.data.eventTrigger.case_fields)
10947
- .reduce((flags, caseField) => {
10948
- return FieldsUtils.extractFlagsDataFromCaseField(flags, caseField, caseField.id, caseField);
10949
- }, []);
10950
- // Set boolean indicating the display_context_parameter is "update"
10951
- this.isDisplayContextParameterUpdate =
10952
- this.setDisplayContextParameterUpdate((this.route.snapshot.data.eventTrigger.case_fields));
10953
- // Set starting field state
10954
- this.fieldState = this.isDisplayContextParameterUpdate ? CaseFlagFieldState.FLAG_MANAGE_CASE_FLAGS : CaseFlagFieldState.FLAG_LOCATION;
10955
- // Get case title, to be used by child components
10956
- this.caseEditDataService.caseTitle$.subscribe({
10957
- next: title => {
10958
- this.caseTitle = title.length > 0 ? title : this.caseNameMissing;
10959
- }
10960
- });
11172
+ if (this.route.snapshot.data.eventTrigger) {
11173
+ // Get the HMCTSServiceId from supplementary data, if it exists (required for retrieving the available flag types in
11174
+ // the first instance, only falling back on case type ID or jurisidiction if it's not present)
11175
+ if (this.route.snapshot.data.eventTrigger.supplementary_data
11176
+ && this.route.snapshot.data.eventTrigger.supplementary_data.HMCTSServiceId) {
11177
+ this.hmctsServiceId = this.route.snapshot.data.eventTrigger.supplementary_data.HMCTSServiceId;
11178
+ }
11179
+ if (this.route.snapshot.data.eventTrigger.case_fields) {
11180
+ this.flagsData = (this.route.snapshot.data.eventTrigger.case_fields)
11181
+ .reduce((flags, caseField) => {
11182
+ return FieldsUtils.extractFlagsDataFromCaseField(flags, caseField, caseField.id, caseField);
11183
+ }, []);
11184
+ // Set boolean indicating the display_context_parameter is "update"
11185
+ this.isDisplayContextParameterUpdate =
11186
+ this.setDisplayContextParameterUpdate((this.route.snapshot.data.eventTrigger.case_fields));
11187
+ // Set starting field state
11188
+ this.fieldState = this.isDisplayContextParameterUpdate ? CaseFlagFieldState.FLAG_MANAGE_CASE_FLAGS : CaseFlagFieldState.FLAG_LOCATION;
11189
+ // Get case title, to be used by child components
11190
+ this.caseEditDataService.caseTitle$.subscribe({
11191
+ next: title => {
11192
+ this.caseTitle = title.length > 0 ? title : this.caseNameMissing;
11193
+ }
11194
+ });
11195
+ }
10961
11196
  }
10962
11197
  }
10963
11198
  setDisplayContextParameterUpdate(caseFields) {
@@ -11190,7 +11425,7 @@ class WriteCaseFlagFieldComponent extends AbstractFieldWriteComponent {
11190
11425
  }
11191
11426
  }
11192
11427
  WriteCaseFlagFieldComponent.ɵfac = function WriteCaseFlagFieldComponent_Factory(t) { return new (t || WriteCaseFlagFieldComponent)(i0.ɵɵdirectiveInject(i1$1.ActivatedRoute), i0.ɵɵdirectiveInject(CaseEditDataService)); };
11193
- WriteCaseFlagFieldComponent.ɵcmp = i0.ɵɵdefineComponent({ type: WriteCaseFlagFieldComponent, selectors: [["ccd-write-case-flag-field"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 3, consts: [["class", "govuk-error-summary", "aria-labelledby", "error-summary-title", "role", "alert", "tabindex", "-1", "data-module", "govuk-error-summary", 4, "ngIf"], ["class", "form-group", 3, "formGroup", 4, "ngIf"], ["aria-labelledby", "error-summary-title", "role", "alert", "tabindex", "-1", "data-module", "govuk-error-summary", 1, "govuk-error-summary"], ["id", "error-summary-title", 1, "govuk-error-summary__title"], ["class", "govuk-error-summary__body", 4, "ngFor", "ngForOf"], [1, "govuk-error-summary__body"], [1, "govuk-list", "govuk-error-summary__list"], [1, "validation-error", 3, "click"], [1, "form-group", 3, "formGroup"], [1, "govuk-form-group", 3, "ngSwitch"], ["id", "create-flag-caption", 1, "govuk-caption-l", 3, "ngClass"], [4, "ngSwitchCase"], [3, "formGroup", "flagsData", "caseFlagStateEmitter"], [3, "formGroup", "jurisdiction", "caseFlagStateEmitter", "flagCommentsOptionalEmitter"], [3, "formGroup", "languages", "flagCode", "caseFlagStateEmitter"], [3, "formGroup", "optional", "caseFlagStateEmitter"], [3, "formGroup", "flagsData", "caseTitle", "caseFlagStateEmitter"], [3, "formGroup", "selectedFlag", "caseFlagStateEmitter"]], template: function WriteCaseFlagFieldComponent_Template(rf, ctx) { if (rf & 1) {
11428
+ WriteCaseFlagFieldComponent.ɵcmp = i0.ɵɵdefineComponent({ type: WriteCaseFlagFieldComponent, selectors: [["ccd-write-case-flag-field"]], features: [i0.ɵɵInheritDefinitionFeature], decls: 3, vars: 3, consts: [["class", "govuk-error-summary", "aria-labelledby", "error-summary-title", "role", "alert", "tabindex", "-1", "data-module", "govuk-error-summary", 4, "ngIf"], ["class", "form-group", 3, "formGroup", 4, "ngIf"], ["aria-labelledby", "error-summary-title", "role", "alert", "tabindex", "-1", "data-module", "govuk-error-summary", 1, "govuk-error-summary"], ["id", "error-summary-title", 1, "govuk-error-summary__title"], ["class", "govuk-error-summary__body", 4, "ngFor", "ngForOf"], [1, "govuk-error-summary__body"], [1, "govuk-list", "govuk-error-summary__list"], [1, "validation-error", 3, "click"], [1, "form-group", 3, "formGroup"], [1, "govuk-form-group", 3, "ngSwitch"], ["id", "create-flag-caption", 1, "govuk-caption-l", 3, "ngClass"], [4, "ngSwitchCase"], [3, "formGroup", "flagsData", "caseFlagStateEmitter"], [3, "formGroup", "jurisdiction", "caseTypeId", "hmctsServiceId", "caseFlagStateEmitter", "flagCommentsOptionalEmitter"], [3, "formGroup", "languages", "flagCode", "caseFlagStateEmitter"], [3, "formGroup", "optional", "caseFlagStateEmitter"], [3, "formGroup", "flagsData", "caseTitle", "caseFlagStateEmitter"], [3, "formGroup", "selectedFlag", "caseFlagStateEmitter"]], template: function WriteCaseFlagFieldComponent_Template(rf, ctx) { if (rf & 1) {
11194
11429
  i0.ɵɵtemplate(0, WriteCaseFlagFieldComponent_div_0_Template, 4, 1, "div", 0);
11195
11430
  i0.ɵɵtemplate(1, WriteCaseFlagFieldComponent_div_1_Template, 8, 10, "div", 1);
11196
11431
  i0.ɵɵtemplate(2, WriteCaseFlagFieldComponent_div_2_Template, 4, 4, "div", 1);
@@ -16588,23 +16823,30 @@ class SelectFlagTypeComponent {
16588
16823
  && this.formGroup['caseField'].id === this.caseLevelCaseFlagsFieldId
16589
16824
  ? RefdataCaseFlagType.CASE
16590
16825
  : RefdataCaseFlagType.PARTY;
16591
- // HMCTS service code for a given jurisdiction is required to retrieve the relevant list of flag types
16592
- this.flagRefdata$ = this.caseFlagRefdataService.getHmctsServiceDetails(this.jurisdiction)
16593
- .pipe(
16594
- // Use switchMap to return an inner Observable of the flag types data, having received the service details
16595
- // including service_code. This avoids having nested `subscribe`s, which is an anti-pattern!
16596
- switchMap(serviceDetails => {
16597
- return this.caseFlagRefdataService.getCaseFlagsRefdata(serviceDetails[0].service_code, flagType);
16598
- }))
16599
- .subscribe({
16600
- next: flagTypes => {
16826
+ // If hmctsServiceId is present, use this to retrieve the relevant list of flag types
16827
+ if (this.hmctsServiceId) {
16828
+ this.flagRefdata$ = this.caseFlagRefdataService.getCaseFlagsRefdata(this.hmctsServiceId, flagType)
16829
+ .subscribe({
16601
16830
  // First (and only) object in the returned array should be the top-level "Party" flag type
16602
- this.flagTypes = flagTypes[0].childFlags;
16603
- },
16604
- error: error => {
16605
- this.onRefdataError(error);
16606
- }
16607
- });
16831
+ next: flagTypes => this.flagTypes = flagTypes[0].childFlags,
16832
+ error: error => this.onRefdataError(error)
16833
+ });
16834
+ }
16835
+ else {
16836
+ // Else, HMCTS service code is required to retrieve the relevant list of flag types; attempt to obtain it by case type ID first
16837
+ this.flagRefdata$ = this.caseFlagRefdataService.getHmctsServiceDetailsByCaseType(this.caseTypeId)
16838
+ .pipe(
16839
+ // If an error occurs retrieving HMCTS service details by case type ID, try by service name instead
16840
+ catchError(_ => this.caseFlagRefdataService.getHmctsServiceDetailsByServiceName(this.jurisdiction)),
16841
+ // Use switchMap to return an inner Observable of the flag types data, having received the service details
16842
+ // including service_code. This avoids having nested `subscribe`s, which is an anti-pattern!
16843
+ switchMap(serviceDetails => this.caseFlagRefdataService.getCaseFlagsRefdata(serviceDetails[0].service_code, flagType)))
16844
+ .subscribe({
16845
+ // First (and only) object in the returned array should be the top-level "Party" flag type
16846
+ next: flagTypes => this.flagTypes = flagTypes[0].childFlags,
16847
+ error: error => this.onRefdataError(error)
16848
+ });
16849
+ }
16608
16850
  }
16609
16851
  ngOnDestroy() {
16610
16852
  if (this.flagRefdata$) {
@@ -16675,7 +16917,7 @@ class SelectFlagTypeComponent {
16675
16917
  }
16676
16918
  }
16677
16919
  SelectFlagTypeComponent.ɵfac = function SelectFlagTypeComponent_Factory(t) { return new (t || SelectFlagTypeComponent)(i0.ɵɵdirectiveInject(CaseFlagRefdataService)); };
16678
- SelectFlagTypeComponent.ɵcmp = i0.ɵɵdefineComponent({ type: SelectFlagTypeComponent, selectors: [["ccd-select-flag-type"]], inputs: { formGroup: "formGroup", jurisdiction: "jurisdiction" }, outputs: { caseFlagStateEmitter: "caseFlagStateEmitter", flagCommentsOptionalEmitter: "flagCommentsOptionalEmitter" }, decls: 11, vars: 9, consts: [[1, "form-group", 3, "formGroup"], [1, "govuk-form-group", 3, "ngClass"], ["aria-describedby", "flag-type-heading", 1, "govuk-fieldset"], [1, "govuk-fieldset__legend", "govuk-fieldset__legend--l"], ["id", "flag-type-heading", 1, "govuk-fieldset__heading"], ["id", "flag-type-not-selected-error-message", "class", "govuk-error-message", 4, "ngIf"], ["data-module", "govuk-radios", "id", "conditional-radios-list", 1, "govuk-radios", "govuk-radios--conditional"], ["class", "govuk-radios__item", 4, "ngFor", "ngForOf"], ["class", "govuk-radios__conditional", "id", "conditional-flagType", 4, "ngIf"], ["class", "govuk-button-group", 4, "ngIf"], ["id", "flag-type-not-selected-error-message", 1, "govuk-error-message"], [1, "govuk-visually-hidden"], [1, "govuk-radios__item"], ["type", "radio", 1, "govuk-radios__input", 3, "id", "name", "value", "formControlName", "change"], [1, "govuk-label", "govuk-radios__label", 3, "for"], ["id", "conditional-flagType", 1, "govuk-radios__conditional"], ["for", "other-flag-type-description", 1, "govuk-label"], ["id", "flag-type-error-message", "class", "govuk-error-message", 4, "ngIf"], ["id", "other-flag-type-description", "type", "text", 1, "govuk-input", "govuk-!-width-one-half", 3, "ngClass", "name", "formControlName"], ["id", "flag-type-error-message", 1, "govuk-error-message"], [1, "govuk-button-group"], ["type", "button", 1, "button", "button-primary", 3, "click"]], template: function SelectFlagTypeComponent_Template(rf, ctx) { if (rf & 1) {
16920
+ SelectFlagTypeComponent.ɵcmp = i0.ɵɵdefineComponent({ type: SelectFlagTypeComponent, selectors: [["ccd-select-flag-type"]], inputs: { formGroup: "formGroup", jurisdiction: "jurisdiction", caseTypeId: "caseTypeId", hmctsServiceId: "hmctsServiceId" }, outputs: { caseFlagStateEmitter: "caseFlagStateEmitter", flagCommentsOptionalEmitter: "flagCommentsOptionalEmitter" }, decls: 11, vars: 9, consts: [[1, "form-group", 3, "formGroup"], [1, "govuk-form-group", 3, "ngClass"], ["aria-describedby", "flag-type-heading", 1, "govuk-fieldset"], [1, "govuk-fieldset__legend", "govuk-fieldset__legend--l"], ["id", "flag-type-heading", 1, "govuk-fieldset__heading"], ["id", "flag-type-not-selected-error-message", "class", "govuk-error-message", 4, "ngIf"], ["data-module", "govuk-radios", "id", "conditional-radios-list", 1, "govuk-radios", "govuk-radios--conditional"], ["class", "govuk-radios__item", 4, "ngFor", "ngForOf"], ["class", "govuk-radios__conditional", "id", "conditional-flagType", 4, "ngIf"], ["class", "govuk-button-group", 4, "ngIf"], ["id", "flag-type-not-selected-error-message", 1, "govuk-error-message"], [1, "govuk-visually-hidden"], [1, "govuk-radios__item"], ["type", "radio", 1, "govuk-radios__input", 3, "id", "name", "value", "formControlName", "change"], [1, "govuk-label", "govuk-radios__label", 3, "for"], ["id", "conditional-flagType", 1, "govuk-radios__conditional"], ["for", "other-flag-type-description", 1, "govuk-label"], ["id", "flag-type-error-message", "class", "govuk-error-message", 4, "ngIf"], ["id", "other-flag-type-description", "type", "text", 1, "govuk-input", "govuk-!-width-one-half", 3, "ngClass", "name", "formControlName"], ["id", "flag-type-error-message", 1, "govuk-error-message"], [1, "govuk-button-group"], ["type", "button", 1, "button", "button-primary", 3, "click"]], template: function SelectFlagTypeComponent_Template(rf, ctx) { if (rf & 1) {
16679
16921
  i0.ɵɵelementStart(0, "div", 0);
16680
16922
  i0.ɵɵelementStart(1, "div", 1);
16681
16923
  i0.ɵɵelementStart(2, "fieldset", 2);
@@ -16719,6 +16961,10 @@ SelectFlagTypeComponent.ɵcmp = i0.ɵɵdefineComponent({ type: SelectFlagTypeCom
16719
16961
  type: Input
16720
16962
  }], jurisdiction: [{
16721
16963
  type: Input
16964
+ }], caseTypeId: [{
16965
+ type: Input
16966
+ }], hmctsServiceId: [{
16967
+ type: Input
16722
16968
  }], caseFlagStateEmitter: [{
16723
16969
  type: Output
16724
16970
  }], flagCommentsOptionalEmitter: [{
@@ -18730,7 +18976,10 @@ DatetimePickerComponent.ɵcmp = i0.ɵɵdefineComponent({ type: DatetimePickerCom
18730
18976
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputElement = _t.first);
18731
18977
  } }, inputs: { dateControl: "dateControl" }, features: [i0.ɵɵProvidersFeature([
18732
18978
  { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_MOMENT_FORMATS },
18733
- { provide: NgxMatDateAdapter, useClass: NgxMatMomentAdapter },
18979
+ { provide: NgxMatDateAdapter,
18980
+ useClass: NgxMatMomentAdapter,
18981
+ deps: [MAT_DATE_LOCALE, NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS]
18982
+ },
18734
18983
  { provide: NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
18735
18984
  ]), i0.ɵɵInheritDefinitionFeature], decls: 14, vars: 26, consts: [[1, "govuk-form-group", "bottom-30", 3, "id", "ngClass"], ["class", "form-label", 4, "ngIf"], ["class", "form-hint", 4, "ngIf"], ["class", "error-message", 4, "ngIf"], [1, "datepicker-container"], ["ng-model-options", "{timezone:'utc'}", 1, "govuk-input", 3, "min", "max", "formControl", "ngxMatDatetimePicker", "focusin", "focusout", "dateChange"], ["input", ""], ["matSuffix", "", "id", "pickerOpener", 3, "for"], [3, "color", "touchUi", "hideTime", "startView", "stepHour", "stepSecond", "stepMinute", "showSeconds", "showSpinners", "disableMinute", "enableMeridian", "yearSelected", "monthSelected", "opened"], ["picker", ""], [1, "form-label"], [1, "form-hint"], [1, "error-message"]], template: function DatetimePickerComponent_Template(rf, ctx) { if (rf & 1) {
18736
18985
  i0.ɵɵelementStart(0, "div", 0);
@@ -18783,7 +19032,10 @@ DatetimePickerComponent.ɵcmp = i0.ɵɵdefineComponent({ type: DatetimePickerCom
18783
19032
  encapsulation: ViewEncapsulation.None,
18784
19033
  providers: [
18785
19034
  { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_MOMENT_FORMATS },
18786
- { provide: NgxMatDateAdapter, useClass: NgxMatMomentAdapter },
19035
+ { provide: NgxMatDateAdapter,
19036
+ useClass: NgxMatMomentAdapter,
19037
+ deps: [MAT_DATE_LOCALE, NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS]
19038
+ },
18787
19039
  { provide: NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
18788
19040
  ]
18789
19041
  }]
@@ -24186,11 +24438,12 @@ class CaseFullAccessViewComponent {
24186
24438
  this.activitySubscription = this.postViewActivity().subscribe();
24187
24439
  });
24188
24440
  }
24441
+ this.checkRouteAndSetCaseViewTab();
24189
24442
  // Check for active Case Flags
24190
24443
  this.activeCaseFlags = this.hasActiveCaseFlags();
24191
24444
  }
24192
24445
  ngOnChanges(changes) {
24193
- if (!changes.prependedTabs.firstChange) {
24446
+ if (changes && changes.prependedTabs && !changes.prependedTabs.firstChange) {
24194
24447
  this.init();
24195
24448
  this.crf.detectChanges();
24196
24449
  this.organiseTabPosition();
@@ -24215,6 +24468,21 @@ class CaseFullAccessViewComponent {
24215
24468
  subscription.unsubscribe();
24216
24469
  }
24217
24470
  }
24471
+ checkRouteAndSetCaseViewTab() {
24472
+ this.router.events
24473
+ .pipe(filter((event) => event instanceof NavigationEnd))
24474
+ .subscribe((event) => {
24475
+ const url = event && event.url;
24476
+ if (url) {
24477
+ const tabUrl = url ? url.split('#') : null;
24478
+ const tab = tabUrl && tabUrl.length > 1 ? tabUrl[tabUrl.length - 1].replaceAll('%20', ' ') : '';
24479
+ const matTab = this.tabGroup._tabs.find((x) => x.textLabel.toLowerCase() === tab.toLowerCase());
24480
+ if (matTab && matTab.position) {
24481
+ this.tabGroup.selectedIndex = matTab.position;
24482
+ }
24483
+ }
24484
+ });
24485
+ }
24218
24486
  postViewActivity() {
24219
24487
  return this.activityPollingService.postViewActivity(this.caseDetails.case_id);
24220
24488
  }
@@ -27671,11 +27939,11 @@ function SearchResultComponent_table_0_th_9_Template(rf, ctx) { if (rf & 1) {
27671
27939
  i0.ɵɵadvance(2);
27672
27940
  i0.ɵɵproperty("checked", ctx_r6.allOnPageSelected())("disabled", !ctx_r6.canAnyBeShared());
27673
27941
  } }
27674
- function SearchResultComponent_table_0_th_10_div_6_Template(rf, ctx) { if (rf & 1) {
27942
+ function SearchResultComponent_table_0_th_10_div_4_Template(rf, ctx) { if (rf & 1) {
27675
27943
  const _r19 = i0.ɵɵgetCurrentView();
27676
27944
  i0.ɵɵelementStart(0, "div", 27);
27677
27945
  i0.ɵɵelementStart(1, "a", 28);
27678
- i0.ɵɵlistener("click", function SearchResultComponent_table_0_th_10_div_6_Template_a_click_1_listener() { i0.ɵɵrestoreView(_r19); const col_r15 = i0.ɵɵnextContext().$implicit; const ctx_r17 = i0.ɵɵnextContext(2); return ctx_r17.sort(col_r15); });
27946
+ i0.ɵɵlistener("click", function SearchResultComponent_table_0_th_10_div_4_Template_a_click_1_listener() { i0.ɵɵrestoreView(_r19); const col_r15 = i0.ɵɵnextContext().$implicit; const ctx_r17 = i0.ɵɵnextContext(2); return ctx_r17.sort(col_r15); });
27679
27947
  i0.ɵɵelementEnd();
27680
27948
  i0.ɵɵelementEnd();
27681
27949
  } if (rf & 2) {
@@ -27687,16 +27955,12 @@ function SearchResultComponent_table_0_th_10_div_6_Template(rf, ctx) { if (rf &
27687
27955
  function SearchResultComponent_table_0_th_10_Template(rf, ctx) { if (rf & 1) {
27688
27956
  const _r22 = i0.ɵɵgetCurrentView();
27689
27957
  i0.ɵɵelementStart(0, "th");
27690
- i0.ɵɵelementStart(1, "table", 24);
27691
- i0.ɵɵelementStart(2, "tr");
27692
- i0.ɵɵelementStart(3, "th");
27693
- i0.ɵɵelementStart(4, "div", 25);
27694
- i0.ɵɵlistener("click", function SearchResultComponent_table_0_th_10_Template_div_click_4_listener() { i0.ɵɵrestoreView(_r22); const col_r15 = ctx.$implicit; const ctx_r21 = i0.ɵɵnextContext(2); return ctx_r21.sort(col_r15); });
27695
- i0.ɵɵtext(5);
27696
- i0.ɵɵelementEnd();
27697
- i0.ɵɵtemplate(6, SearchResultComponent_table_0_th_10_div_6_Template, 2, 1, "div", 26);
27698
- i0.ɵɵelementEnd();
27958
+ i0.ɵɵelementStart(1, "div", 24);
27959
+ i0.ɵɵelementStart(2, "div", 25);
27960
+ i0.ɵɵlistener("click", function SearchResultComponent_table_0_th_10_Template_div_click_2_listener() { i0.ɵɵrestoreView(_r22); const col_r15 = ctx.$implicit; const ctx_r21 = i0.ɵɵnextContext(2); return ctx_r21.sort(col_r15); });
27961
+ i0.ɵɵtext(3);
27699
27962
  i0.ɵɵelementEnd();
27963
+ i0.ɵɵtemplate(4, SearchResultComponent_table_0_th_10_div_4_Template, 2, 1, "div", 26);
27700
27964
  i0.ɵɵelementEnd();
27701
27965
  i0.ɵɵelementEnd();
27702
27966
  } if (rf & 2) {
@@ -27704,7 +27968,7 @@ function SearchResultComponent_table_0_th_10_Template(rf, ctx) { if (rf & 1) {
27704
27968
  const ctx_r7 = i0.ɵɵnextContext(2);
27705
27969
  i0.ɵɵadvance(1);
27706
27970
  i0.ɵɵattribute("aria-label", "Sort by " + col_r15.label + " " + ctx_r7.isSortAscending(col_r15) ? "ascending" : "descending");
27707
- i0.ɵɵadvance(4);
27971
+ i0.ɵɵadvance(2);
27708
27972
  i0.ɵɵtextInterpolate(col_r15.label);
27709
27973
  i0.ɵɵadvance(1);
27710
27974
  i0.ɵɵproperty("ngIf", ctx_r7.comparator(col_r15));
@@ -27976,7 +28240,7 @@ function SearchResultComponent_table_0_Template(rf, ctx) { if (rf & 1) {
27976
28240
  i0.ɵɵelementStart(7, "thead");
27977
28241
  i0.ɵɵelementStart(8, "tr", 7);
27978
28242
  i0.ɵɵtemplate(9, SearchResultComponent_table_0_th_9_Template, 4, 2, "th", 8);
27979
- i0.ɵɵtemplate(10, SearchResultComponent_table_0_th_10_Template, 7, 3, "th", 9);
28243
+ i0.ɵɵtemplate(10, SearchResultComponent_table_0_th_10_Template, 5, 3, "th", 9);
27980
28244
  i0.ɵɵtemplate(11, SearchResultComponent_table_0_th_11_Template, 1, 0, "th", 10);
27981
28245
  i0.ɵɵelementEnd();
27982
28246
  i0.ɵɵelementEnd();