@hmcts/ccd-case-ui-toolkit 6.13.0-test1 → 6.13.9-rc1

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 (34) hide show
  1. package/bundles/hmcts-ccd-case-ui-toolkit.umd.js +484 -256
  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-file-view/components/case-file-view-folder-selector/case-file-view-folder-selector.component.js +1 -1
  7. package/esm2015/lib/shared/components/palette/case-flag/components/select-flag-type/select-flag-type.component.js +30 -19
  8. package/esm2015/lib/shared/components/palette/case-flag/write-case-flag-field.component.js +35 -24
  9. package/esm2015/lib/shared/components/palette/datetime-picker/datetime-picker.component.js +10 -3
  10. package/esm2015/lib/shared/components/search-result/search-result.component.js +10 -14
  11. package/esm2015/lib/shared/directives/conditional-show/domain/conditional-show.model.js +103 -200
  12. package/esm2015/lib/shared/directives/conditional-show/services/condition-parser.service.js +201 -0
  13. package/esm2015/lib/shared/directives/conditional-show/services/condition.peg.js +103 -0
  14. package/esm2015/lib/shared/domain/case-flag/hmcts-service-detail.model.js +1 -1
  15. package/esm2015/lib/shared/services/case-flag/case-flag-refdata.service.js +25 -4
  16. package/fesm2015/hmcts-ccd-case-ui-toolkit.js +500 -236
  17. package/fesm2015/hmcts-ccd-case-ui-toolkit.js.map +1 -1
  18. package/lib/shared/components/case-viewer/case-full-access-view/case-full-access-view.component.d.ts +1 -0
  19. package/lib/shared/components/case-viewer/case-full-access-view/case-full-access-view.component.d.ts.map +1 -1
  20. package/lib/shared/components/palette/case-flag/components/select-flag-type/select-flag-type.component.d.ts +3 -1
  21. package/lib/shared/components/palette/case-flag/components/select-flag-type/select-flag-type.component.d.ts.map +1 -1
  22. package/lib/shared/components/palette/case-flag/write-case-flag-field.component.d.ts +2 -0
  23. package/lib/shared/components/palette/case-flag/write-case-flag-field.component.d.ts.map +1 -1
  24. package/lib/shared/components/palette/datetime-picker/datetime-picker.component.d.ts.map +1 -1
  25. package/lib/shared/directives/conditional-show/domain/conditional-show.model.d.ts +13 -30
  26. package/lib/shared/directives/conditional-show/domain/conditional-show.model.d.ts.map +1 -1
  27. package/lib/shared/directives/conditional-show/services/condition-parser.service.d.ts +30 -0
  28. package/lib/shared/directives/conditional-show/services/condition-parser.service.d.ts.map +1 -0
  29. package/lib/shared/directives/conditional-show/services/condition.peg.d.ts +3 -0
  30. package/lib/shared/directives/conditional-show/services/condition.peg.d.ts.map +1 -0
  31. package/lib/shared/domain/case-flag/hmcts-service-detail.model.d.ts.map +1 -1
  32. package/lib/shared/services/case-flag/case-flag-refdata.service.d.ts +14 -3
  33. package/lib/shared/services/case-flag/case-flag-refdata.service.d.ts.map +1 -1
  34. 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';
@@ -3799,168 +3800,165 @@ FieldsUtils.ɵprov = i0.ɵɵdefineInjectable({ token: FieldsUtils, factory: Fiel
3799
3800
  type: Injectable
3800
3801
  }], null, null); })();
3801
3802
 
3802
- class ShowCondition {
3803
- // Expects a show condition of the form: <fieldName>="string"
3804
- constructor(condition) {
3805
- this.condition = condition;
3806
- this.orConditions = null;
3807
- this.andConditions = null;
3808
- if (!!condition) {
3809
- if (condition.search(ShowCondition.OR_CONDITION_REGEXP) !== -1) {
3810
- this.orConditions = condition.split(ShowCondition.OR_CONDITION_REGEXP);
3811
- }
3812
- else {
3813
- this.andConditions = condition.split(ShowCondition.AND_CONDITION_REGEXP);
3814
- }
3815
- }
3816
- }
3817
- static addPathPrefixToCondition(showCondition, pathPrefix) {
3818
- if (!pathPrefix || pathPrefix === '') {
3819
- return showCondition;
3820
- }
3821
- if (showCondition.search(ShowCondition.OR_CONDITION_REGEXP) !== -1) {
3822
- let orConditions = showCondition.split(ShowCondition.OR_CONDITION_REGEXP);
3823
- orConditions = this.extractConditions(orConditions, pathPrefix);
3824
- return orConditions.join(' OR ');
3825
- }
3826
- else {
3827
- let andConditions = showCondition.split(ShowCondition.AND_CONDITION_REGEXP);
3828
- andConditions = this.extractConditions(andConditions, pathPrefix);
3829
- return andConditions.join(' AND ');
3830
- }
3803
+ const conditionSource = `{
3804
+ function flat(arr, depth = 1) {
3805
+ var flatten = function (arr, depth = 1) {
3806
+ if (depth) return arr;
3807
+
3808
+ // Otherwise, concatenate into the parent array
3809
+ return arr.reduce(function (acc, val) {
3810
+ return acc.concat(Array.isArray(val) ? flatten(val, depth - 1) : val);
3811
+ }, []);
3812
+
3813
+ };
3814
+
3815
+ return flatten(arr, depth - 1);
3831
3816
  }
3832
- // Cache instances so that we can cache results more effectively
3833
- static getInstance(condition) {
3834
- let instance = this.instanceCache.get(condition);
3835
- if (!instance) {
3836
- instance = new ShowCondition(condition);
3837
- this.instanceCache.set(condition, instance);
3817
+ }
3818
+
3819
+ Start
3820
+ = Formula
3821
+
3822
+ Formula
3823
+ = EnclosedFormula
3824
+ / OpenFormula
3825
+
3826
+ EnclosedFormula
3827
+ = bracket formula:OpenFormula bracket join:(JoinComparator)*
3828
+ { return flat([ [formula], join[0] ], 1) }
3829
+
3830
+ OpenFormula
3831
+ = eq:OpenEqualityCheck joins:(JoinComparator)*
3832
+ { return flat([ eq, flat(joins) ]) }
3833
+
3834
+ JoinComparator
3835
+ = comp:Comparator eq:OpenEqualityCheck
3836
+ { return [comp, eq]; }
3837
+ / CompoundJoinComparator
3838
+
3839
+ CompoundJoinComparator
3840
+ = comp:Comparator bracket f:OpenFormula bracket
3841
+ { return [comp, f ] }
3842
+
3843
+ OpenEqualityCheck
3844
+ = fr:FieldRef _? op:operator _? val:Value
3845
+ { return { fieldReference: fr, comparator: op, value: val } }
3846
+
3847
+ Comparator
3848
+ = _? c:'AND' _?
3849
+ { return c; }
3850
+ / _? c:'OR' _?
3851
+ { return c; }
3852
+
3853
+ Word
3854
+ = l:Letter+
3855
+ { return l.join(""); }
3856
+
3857
+ Letter
3858
+ = [a-zA-Z]
3859
+
3860
+ Value
3861
+ = v:quotedValue / v:Word
3862
+ { return v.join("") }
3863
+ / v:number
3864
+ { return parseInt(v.join("")) }
3865
+
3866
+ FieldRef
3867
+ = FieldReference / MetadataFieldReference
3868
+
3869
+ MetadataFieldReference
3870
+ = s1:openSquare fr:FieldReference s2:closeSquare
3871
+ { return s1 + fr + s2 }
3872
+
3873
+ FieldReference
3874
+ = characters:[A-Za-z0-9._-]+ { return characters.join(""); }
3875
+
3876
+ openSquare
3877
+ = "["
3878
+
3879
+ closeSquare
3880
+ = "]"
3881
+
3882
+ number
3883
+ = [0-9]+
3884
+
3885
+ quotedValue
3886
+ = '"'val:[A-Za-z0-9.,* _&()/-]*'"'
3887
+ { return val.join(""); }
3888
+
3889
+ bracket
3890
+ = (_? "("+ _? / _? ")"+ _? )
3891
+
3892
+ operator
3893
+ = "=" / "!=" / "CONTAINS"
3894
+
3895
+ ws "Whitespace"
3896
+ = [ \t]
3897
+
3898
+ _ "One or more whitespaces"
3899
+ = ws+
3900
+
3901
+ nl "New line"
3902
+ = "\\n"`;
3903
+ var peg = generate(conditionSource);
3904
+
3905
+ class ConditionParser {
3906
+ /**
3907
+ * Parse the raw formula and output structured condition data
3908
+ * that can be used in evaluating show/hide logic
3909
+ * @param condition raw formula e.g. TextField = "Hello"
3910
+ */
3911
+ static parse(condition) {
3912
+ if (!condition) {
3913
+ return null;
3838
3914
  }
3839
- return instance;
3915
+ ;
3916
+ condition = condition.replace(/CONTAINS/g, ' CONTAINS');
3917
+ return peg.parse(condition.trim(), {});
3840
3918
  }
3841
3919
  /**
3842
- * Determine whether a ShowCondition model is affected by fields that have
3843
- * a display_context of HIDDEN or READONLY, which means they aren't able to
3844
- * be changed by the user's actions.
3845
- *
3846
- * @param showCondition The ShowCondition model to evaluate.
3847
- * @param caseFields Inspected to see appropriate display_contexts.
3920
+ * Evaluate the current fields against the conditions
3921
+ * @param fields the current page fields and their value
3922
+ * @param conditions The PegJS formula output
3848
3923
  */
3849
- static hiddenCannotChange(showCondition, caseFields) {
3850
- if (showCondition && caseFields) {
3851
- const conditions = showCondition.andConditions || showCondition.orConditions;
3852
- if (conditions && conditions.length > 0) {
3853
- let allUnchangeable = true;
3854
- for (const condition of conditions) {
3855
- const [field] = ShowCondition.getField(condition);
3856
- const path = field.split('.');
3857
- let head = path.shift();
3858
- let caseField = caseFields.find(cf => cf.id === head);
3859
- while (path.length > 0) {
3860
- head = path.shift();
3861
- if (caseField) {
3862
- // Jump out if this is HIDDEN or READONLY, regardless of whether or not it's
3863
- // complex or a collection - nested fields will "inherit" the display_context.
3864
- if (['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1) {
3865
- break;
3866
- }
3867
- // Consider what type of field this is.
3868
- const ft = caseField.field_type;
3869
- switch (ft.type) {
3870
- case 'Collection':
3871
- if (ft.collection_field_type.type === 'Complex' && ft.collection_field_type.complex_fields) {
3872
- caseField = ft.collection_field_type.complex_fields.find(cf => cf.id === head);
3873
- }
3874
- break;
3875
- case 'Complex':
3876
- if (ft.complex_fields) {
3877
- caseField = ft.complex_fields.find(cf => cf.id === head);
3878
- }
3879
- break;
3880
- }
3881
- }
3882
- }
3883
- if (caseField) {
3884
- allUnchangeable = allUnchangeable && ['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1;
3885
- }
3924
+ static evaluate(fields, conditions, path) {
3925
+ if (!conditions || conditions.length === 0) {
3926
+ return true;
3927
+ }
3928
+ ;
3929
+ const validJoinComparators = ['AND', 'OR'];
3930
+ const result = conditions.reduce((accumulator, condition, index) => {
3931
+ const isJoinComparator = (comparator) => (typeof comparator === 'string' && validJoinComparators.indexOf(comparator) !== -1);
3932
+ if (isJoinComparator(condition)) {
3933
+ return accumulator;
3934
+ }
3935
+ ;
3936
+ let currentConditionResult = true;
3937
+ if (Array.isArray(condition)) {
3938
+ currentConditionResult = this.evaluate(fields, condition);
3939
+ if (isJoinComparator(conditions[index - 1])) {
3940
+ return this.evaluateJoin(accumulator, conditions[index - 1], currentConditionResult);
3886
3941
  }
3887
- return allUnchangeable;
3888
3942
  }
3889
- }
3890
- return false;
3891
- }
3892
- static extractConditions(conditionsArray, pathPrefix) {
3893
- const extracted = conditionsArray.map(condition => {
3894
- if (condition.startsWith(pathPrefix)) {
3895
- return condition;
3943
+ if (condition.comparator) {
3944
+ const formula = condition.fieldReference + condition.comparator + condition.value;
3945
+ currentConditionResult = this.matchEqualityCondition(fields, formula, path);
3896
3946
  }
3897
- return `${pathPrefix}.${condition}`;
3898
- });
3899
- return extracted;
3900
- }
3901
- static getField(condition) {
3902
- let separator = ShowCondition.CONTAINS;
3903
- if (condition.indexOf(ShowCondition.CONTAINS) < 0) {
3904
- separator = ShowCondition.CONDITION_EQUALS;
3905
- if (condition.indexOf(ShowCondition.CONDITION_NOT_EQUALS) > -1) {
3906
- separator = ShowCondition.CONDITION_NOT_EQUALS;
3947
+ if (isJoinComparator(conditions[index - 1])) {
3948
+ return this.evaluateJoin(accumulator, conditions[index - 1], currentConditionResult);
3907
3949
  }
3908
- }
3909
- return [condition.split(separator)[0], separator];
3910
- }
3911
- match(fields, path) {
3912
- if (!this.condition) {
3913
- return true;
3914
- }
3915
- return this.matchAndConditions(fields, this.updatePathName(path));
3916
- }
3917
- matchByContextFields(contextFields) {
3918
- return this.match(FieldsUtils.toValuesMap(contextFields));
3919
- }
3920
- /**
3921
- * Determine whether this is affected by fields that have a display_context
3922
- * of HIDDEN or READONLY, which means they aren't able to be changed by the
3923
- * user's actions.
3924
- *
3925
- * @param caseFields Inspected to see appropriate display_contexts.
3926
- */
3927
- hiddenCannotChange(caseFields) {
3928
- return ShowCondition.hiddenCannotChange(this, caseFields);
3929
- }
3930
- /**
3931
- * Path Name gets updated for complex sub fields
3932
- * @param path Path name.
3933
- */
3934
- updatePathName(path) {
3935
- if (path && path.split(/[_]+/g).length > 0) {
3936
- const [pathName, ...pathTail] = path.split(/[_]+/g);
3937
- const pathFinalIndex = pathTail.pop();
3938
- const pathTailString = pathTail.toString();
3939
- let mappedPathTail;
3940
- mappedPathTail = pathTail.map((value) => {
3941
- return Number(pathFinalIndex) === Number(value) ? pathName : value;
3942
- });
3943
- return pathTailString !== mappedPathTail.toString()
3944
- ? `${pathName}_${mappedPathTail.join('_')}_${pathFinalIndex}`
3945
- : path;
3946
- }
3947
- else {
3948
- return path;
3949
- }
3950
+ return currentConditionResult;
3951
+ }, true);
3952
+ return result;
3950
3953
  }
3951
- matchAndConditions(fields, path) {
3952
- if (!!this.orConditions) {
3953
- return this.orConditions.some(orCondition => this.matchEqualityCondition(fields, orCondition, path));
3954
- }
3955
- else if (!!this.andConditions) {
3956
- return this.andConditions.every(andCondition => this.matchEqualityCondition(fields, andCondition, path));
3957
- }
3958
- else {
3959
- return false;
3954
+ static evaluateJoin(leftResult, comparator, rightResult) {
3955
+ switch (comparator) {
3956
+ case 'OR': return leftResult || rightResult;
3957
+ case 'AND': return leftResult && rightResult;
3960
3958
  }
3961
3959
  }
3962
- matchEqualityCondition(fields, condition, path) {
3963
- const [field, conditionSeparator] = ShowCondition.getField(condition);
3960
+ static matchEqualityCondition(fields, condition, path) {
3961
+ const [field, conditionSeparator] = this.getField(condition);
3964
3962
  const [head, ...tail] = field.split('.');
3965
3963
  const currentValue = this.findValueForComplexCondition(fields, head, tail, path);
3966
3964
  const expectedValue = this.unquoted(condition.split(conditionSeparator)[1]);
@@ -3971,7 +3969,29 @@ class ShowCondition {
3971
3969
  return this.checkValueEquals(expectedValue, currentValue, conditionSeparator);
3972
3970
  }
3973
3971
  }
3974
- checkValueEquals(expectedValue, currentValue, conditionSeparaor) {
3972
+ static getValue(fields, head) {
3973
+ if (this.isDynamicList(fields[head])) {
3974
+ return fields[head].value.code;
3975
+ }
3976
+ else {
3977
+ return fields[head];
3978
+ }
3979
+ }
3980
+ static isDynamicList(dynamiclist) {
3981
+ return !_.isEmpty(dynamiclist) &&
3982
+ (_.has(dynamiclist, 'value') && _.has(dynamiclist, 'list_items'));
3983
+ }
3984
+ static getField(condition) {
3985
+ let separator = ShowCondition.CONTAINS;
3986
+ if (condition.indexOf(ShowCondition.CONTAINS) < 0) {
3987
+ separator = ShowCondition.CONDITION_EQUALS;
3988
+ if (condition.indexOf(ShowCondition.CONDITION_NOT_EQUALS) > -1) {
3989
+ separator = ShowCondition.CONDITION_NOT_EQUALS;
3990
+ }
3991
+ }
3992
+ return [condition.split(separator)[0], separator];
3993
+ }
3994
+ static checkValueEquals(expectedValue, currentValue, conditionSeparaor) {
3975
3995
  if (expectedValue.search('[,]') > -1) { // for multi-select list
3976
3996
  return this.checkMultiSelectListEquals(expectedValue, currentValue, conditionSeparaor);
3977
3997
  }
@@ -3991,7 +4011,7 @@ class ShowCondition {
3991
4011
  }
3992
4012
  }
3993
4013
  }
3994
- checkValueNotEquals(expectedValue, currentValue) {
4014
+ static checkValueNotEquals(expectedValue, currentValue) {
3995
4015
  const formatCurrentValue = currentValue ? currentValue.toString().trim() : '';
3996
4016
  if ('*' === expectedValue && formatCurrentValue !== '') {
3997
4017
  return false;
@@ -3999,7 +4019,7 @@ class ShowCondition {
3999
4019
  const formatExpectedValue = expectedValue ? expectedValue.toString().trim() : '';
4000
4020
  return formatCurrentValue != formatExpectedValue; // tslint:disable-line
4001
4021
  }
4002
- checkMultiSelectListEquals(expectedValue, currentValue, conditionSeparator) {
4022
+ static checkMultiSelectListEquals(expectedValue, currentValue, conditionSeparator) {
4003
4023
  const expectedValues = expectedValue.split(',').sort().toString();
4004
4024
  const values = currentValue ? currentValue.sort().toString() : '';
4005
4025
  if (conditionSeparator === ShowCondition.CONDITION_NOT_EQUALS) {
@@ -4009,7 +4029,7 @@ class ShowCondition {
4009
4029
  return expectedValues === values;
4010
4030
  }
4011
4031
  }
4012
- checkValueContains(expectedValue, currentValue) {
4032
+ static checkValueContains(expectedValue, currentValue) {
4013
4033
  if (expectedValue.search(',') > -1) {
4014
4034
  const expectedValues = expectedValue.split(',').sort();
4015
4035
  const values = currentValue ? currentValue.sort().toString() : '';
@@ -4020,7 +4040,11 @@ class ShowCondition {
4020
4040
  return values.search(expectedValue) >= 0;
4021
4041
  }
4022
4042
  }
4023
- findValueForComplexCondition(fields, head, tail, path) {
4043
+ static unquoted(str) {
4044
+ const res = str.replace(/^"|"$/g, '');
4045
+ return res;
4046
+ }
4047
+ static findValueForComplexCondition(fields, head, tail, path) {
4024
4048
  if (!fields) {
4025
4049
  return undefined;
4026
4050
  }
@@ -4036,7 +4060,7 @@ class ShowCondition {
4036
4060
  }
4037
4061
  }
4038
4062
  }
4039
- findValueForComplexConditionForPathIfAny(fields, head, tail, path) {
4063
+ static findValueForComplexConditionForPathIfAny(fields, head, tail, path) {
4040
4064
  if (path) {
4041
4065
  const [_, ...pathTail] = path.split(/[_]+/g);
4042
4066
  return this.findValueForComplexCondition(fields[head], tail[0], tail.slice(1), pathTail.join('_'));
@@ -4045,9 +4069,9 @@ class ShowCondition {
4045
4069
  return this.findValueForComplexCondition(fields[head], tail[0], tail.slice(1), path);
4046
4070
  }
4047
4071
  }
4048
- findValueForComplexConditionInArray(fields, head, tail, path) {
4072
+ static findValueForComplexConditionInArray(fields, head, tail, path) {
4049
4073
  // use the path to resolve which array element we refer to
4050
- if (path && path.startsWith(head)) {
4074
+ if (path.startsWith(head)) {
4051
4075
  const [_, ...pathTail] = path.split(/[_]+/g);
4052
4076
  if (pathTail.length > 0) {
4053
4077
  try {
@@ -4056,42 +4080,221 @@ class ShowCondition {
4056
4080
  return (fields[head][arrayIndex] !== undefined) ? this.findValueForComplexCondition(fields[head][arrayIndex]['value'], tail[0], tail.slice(1), dropNumberPath.join('_')) : null;
4057
4081
  }
4058
4082
  catch (e) {
4059
- console.log('Error while parsing number', pathTail[0], e);
4083
+ console.error('Error while parsing number', pathTail[0], e);
4060
4084
  }
4061
4085
  }
4062
4086
  }
4063
4087
  else {
4064
- console.log('Path in formArray should start with ', head, ', full path: ', path);
4088
+ console.error('Path in formArray should start with ', head, ', full path: ', path);
4065
4089
  }
4066
4090
  }
4067
- getValue(fields, head) {
4068
- if (this.isDynamicList(fields[head])) {
4069
- return fields[head].value.code;
4091
+ static removeStarChar(str) {
4092
+ if (str && str.indexOf('*') > -1) {
4093
+ return str.substring(0, str.indexOf('*'));
4094
+ }
4095
+ return str;
4096
+ }
4097
+ static okIfBothEmpty(right, value) {
4098
+ return value === null && (right === '');
4099
+ }
4100
+ }
4101
+
4102
+ class ShowCondition {
4103
+ // Expects a show condition of the form: <fieldName>="string"
4104
+ constructor(condition) {
4105
+ this.condition = condition;
4106
+ this.conditions = [];
4107
+ if (!!condition) {
4108
+ this.conditions = ConditionParser.parse(condition);
4109
+ }
4110
+ }
4111
+ static addPathPrefixToCondition(showCondition, pathPrefix) {
4112
+ if (!pathPrefix || pathPrefix === '') {
4113
+ return showCondition;
4114
+ }
4115
+ if (!showCondition) {
4116
+ return '';
4117
+ }
4118
+ const formula = ConditionParser.parse(showCondition);
4119
+ if (!formula) {
4120
+ return showCondition;
4121
+ }
4122
+ this.processedList = [];
4123
+ showCondition = showCondition.replace(/CONTAINS/g, ' CONTAINS');
4124
+ const processedCondition = this.processAddPathPrefixToCondition(formula, pathPrefix, showCondition);
4125
+ return processedCondition.replace(/ CONTAINS/g, 'CONTAINS');
4126
+ }
4127
+ static processAddPathPrefixToCondition(formula, pathPrefix, originalCondition) {
4128
+ let finalCondition = originalCondition;
4129
+ if (Array.isArray(formula)) {
4130
+ formula.forEach(condition => {
4131
+ if (typeof condition === 'string' && this.validJoinComparators.indexOf(condition) !== -1) {
4132
+ // do nothing
4133
+ }
4134
+ else {
4135
+ if (Array.isArray(condition)) {
4136
+ finalCondition = this.processAddPathPrefixToCondition(condition, pathPrefix, finalCondition);
4137
+ }
4138
+ else {
4139
+ finalCondition = this.extractConditions(condition, pathPrefix, finalCondition);
4140
+ }
4141
+ }
4142
+ });
4070
4143
  }
4071
4144
  else {
4072
- return fields[head];
4145
+ finalCondition = this.extractConditions(formula, pathPrefix, finalCondition);
4073
4146
  }
4147
+ return finalCondition;
4074
4148
  }
4075
- isDynamicList(dynamiclist) {
4076
- return !_.isEmpty(dynamiclist) &&
4077
- (_.has(dynamiclist, 'value') && _.has(dynamiclist, 'list_items'));
4149
+ static extractConditions(condition, pathPrefix, originalCondition) {
4150
+ if (condition.fieldReference.startsWith(pathPrefix)) {
4151
+ return originalCondition;
4152
+ }
4153
+ else {
4154
+ if (originalCondition.indexOf(condition.fieldReference) > -1) {
4155
+ if (this.processedList && this.processedList.indexOf(condition.fieldReference) === -1) {
4156
+ this.processedList.push(condition.fieldReference);
4157
+ const regularExp = new RegExp('(\\b)' + condition.fieldReference + '(?=[^"]*(?:"[^"]*"[^"]*)*$)(\\b)', 'g');
4158
+ return originalCondition.replace(regularExp, pathPrefix + '.' + condition.fieldReference);
4159
+ }
4160
+ else {
4161
+ return originalCondition;
4162
+ }
4163
+ }
4164
+ }
4078
4165
  }
4079
- unquoted(str) {
4080
- return str.replace(/(?:^")|(?:"$)/g, '');
4166
+ // Cache instances so that we can cache results more effectively
4167
+ static getInstance(condition) {
4168
+ let instance = this.instanceCache.get(condition);
4169
+ if (!instance) {
4170
+ instance = new ShowCondition(condition);
4171
+ this.instanceCache.set(condition, instance);
4172
+ }
4173
+ return instance;
4081
4174
  }
4082
- removeStarChar(str) {
4083
- return str.substring(0, str.length - 1);
4175
+ static getField(condition) {
4176
+ let separator = ShowCondition.CONTAINS;
4177
+ if (condition.indexOf(ShowCondition.CONTAINS) < 0) {
4178
+ separator = ShowCondition.CONDITION_EQUALS;
4179
+ if (condition.indexOf(ShowCondition.CONDITION_NOT_EQUALS) > -1) {
4180
+ separator = ShowCondition.CONDITION_NOT_EQUALS;
4181
+ }
4182
+ }
4183
+ return [condition.split(separator)[0], separator];
4084
4184
  }
4085
- okIfBothEmpty(right, value) {
4086
- return value === null && (right === '');
4185
+ static getConditions(formula) {
4186
+ const conditionList = [];
4187
+ if (!!formula) {
4188
+ const newFormula = typeof formula === 'string' ? JSON.parse(formula) : formula;
4189
+ if (Array.isArray(newFormula)) {
4190
+ newFormula.forEach(condition => {
4191
+ if (!(typeof condition === 'string' && this.validJoinComparators.indexOf(condition) !== -1)) {
4192
+ if (Array.isArray(condition)) {
4193
+ conditionList.push(ShowCondition.getConditions(condition).toString());
4194
+ }
4195
+ else {
4196
+ conditionList.push(condition.fieldReference + condition.comparator + condition.value);
4197
+ }
4198
+ }
4199
+ });
4200
+ }
4201
+ else {
4202
+ conditionList.push(newFormula.fieldReference + newFormula.comparator + newFormula.value);
4203
+ }
4204
+ }
4205
+ return conditionList.toString();
4206
+ }
4207
+ /**
4208
+ * Determine whether a ShowCondition model is affected by fields that have
4209
+ * a display_context of HIDDEN or READONLY, which means they aren't able to
4210
+ * be changed by the user's actions.
4211
+ *
4212
+ * @param showCondition The ShowCondition model to evaluate.
4213
+ * @param caseFields Inspected to see appropriate display_contexts.
4214
+ */
4215
+ static hiddenCannotChange(showCondition, caseFields) {
4216
+ if (showCondition && showCondition.conditions.length && caseFields) {
4217
+ const conditions = this.getConditions(showCondition.conditions).split(',');
4218
+ if (conditions && conditions.length > 0) {
4219
+ let allUnchangeable = true;
4220
+ for (const condition of conditions) {
4221
+ const [field] = ShowCondition.getField(condition);
4222
+ const path = field.split('.');
4223
+ let head = path.shift();
4224
+ let caseField = caseFields.find(cf => cf.id === head);
4225
+ while (path.length > 0) {
4226
+ head = path.shift();
4227
+ if (caseField) {
4228
+ // Jump out if this is HIDDEN or READONLY, regardless of whether or not it's
4229
+ // complex or a collection - nested fields will "inherit" the display_context.
4230
+ if (['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1) {
4231
+ break;
4232
+ }
4233
+ // Consider what type of field this is.
4234
+ const ft = caseField.field_type;
4235
+ switch (ft.type) {
4236
+ case 'Collection':
4237
+ if (ft.collection_field_type.type === 'Complex' && ft.collection_field_type.complex_fields) {
4238
+ caseField = ft.collection_field_type.complex_fields.find(cf => cf.id === head);
4239
+ }
4240
+ break;
4241
+ case 'Complex':
4242
+ if (ft.complex_fields) {
4243
+ caseField = ft.complex_fields.find(cf => cf.id === head);
4244
+ }
4245
+ break;
4246
+ }
4247
+ }
4248
+ }
4249
+ if (caseField) {
4250
+ allUnchangeable = allUnchangeable && ['HIDDEN', 'READONLY'].indexOf(caseField.display_context) > -1;
4251
+ }
4252
+ }
4253
+ return allUnchangeable;
4254
+ }
4255
+ }
4256
+ return false;
4257
+ }
4258
+ match(fields, path) {
4259
+ return ConditionParser.evaluate(fields, this.conditions, this.updatePathName(path));
4260
+ }
4261
+ updatePathName(path) {
4262
+ if (path && path.split(/[_]+/g).length > 0) {
4263
+ /* tslint:disable-next-line */
4264
+ let [pathName, ...pathTail] = path.split(/[_]+/g);
4265
+ const pathFinalIndex = pathTail.pop();
4266
+ const pathTailString = pathTail.toString();
4267
+ pathTail = pathTail.map((value) => {
4268
+ return Number(pathFinalIndex) === Number(value) ? pathName : value;
4269
+ });
4270
+ return pathTailString !== pathTail.toString()
4271
+ ? `${pathName}_${pathTail.join('_')}_${pathFinalIndex}`
4272
+ : path;
4273
+ }
4274
+ else {
4275
+ return path;
4276
+ }
4277
+ }
4278
+ matchByContextFields(contextFields) {
4279
+ return this.match(FieldsUtils.toValuesMap(contextFields));
4280
+ }
4281
+ /**
4282
+ * Determine whether this is affected by fields that have a display_context
4283
+ * of HIDDEN or READONLY, which means they aren't able to be changed by the
4284
+ * user's actions.
4285
+ *
4286
+ * @param caseFields Inspected to see appropriate display_contexts.
4287
+ */
4288
+ hiddenCannotChange(caseFields) {
4289
+ return ShowCondition.hiddenCannotChange(this, caseFields);
4087
4290
  }
4088
4291
  }
4089
- ShowCondition.AND_CONDITION_REGEXP = new RegExp('\\sAND\\s(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)', 'g');
4090
- ShowCondition.OR_CONDITION_REGEXP = new RegExp('\\sOR\\s(?![^"]*"(?:(?:[^"]*"){2})*[^"]*$)', 'g');
4091
4292
  ShowCondition.CONDITION_NOT_EQUALS = '!=';
4092
4293
  ShowCondition.CONDITION_EQUALS = '=';
4093
4294
  ShowCondition.CONTAINS = 'CONTAINS';
4094
4295
  ShowCondition.instanceCache = new Map();
4296
+ ShowCondition.validJoinComparators = ['AND', 'OR'];
4297
+ ShowCondition.processedList = [];
4095
4298
 
4096
4299
  class Constants {
4097
4300
  }
@@ -5886,13 +6089,14 @@ class CaseFlagRefdataService {
5886
6089
  return of(null);
5887
6090
  }
5888
6091
  /**
5889
- * Retrieves the HMCTS service details for a jurisdiction or service, including service code. (For example, the "SSCS"
5890
- * service has a corresponding service code of "BBA3".)
6092
+ * Retrieves the HMCTS service details for a jurisdiction or service, including service codes. More than one
6093
+ * service code may be present. For example, the Divorce jurisdiction/service has corresponding service codes of
6094
+ * "ABA1" and "ABA2".
5891
6095
  *
5892
6096
  * @param serviceNames The service name(s) to look up, comma-separated if more than one
5893
6097
  * @returns An `Observable` of an array of service details
5894
6098
  */
5895
- getHmctsServiceDetails(serviceNames) {
6099
+ getHmctsServiceDetailsByServiceName(serviceNames) {
5896
6100
  let url = this.appConfig.getLocationRefApiUrl();
5897
6101
  if (url) {
5898
6102
  url += '/orgServices';
@@ -5903,6 +6107,26 @@ class CaseFlagRefdataService {
5903
6107
  }
5904
6108
  return of(null);
5905
6109
  }
6110
+ /**
6111
+ * Retrieves the HMCTS service details for a case type, including service code. For example, the
6112
+ * "FinancialRemedyContested" case type is associated with the Divorce jurisdiction/service and service code "ABA2".
6113
+ *
6114
+ * Note that a case type might not be associated with any service codes of a jurisdiction or service.
6115
+ *
6116
+ * @param caseTypeId The case type ID to look up
6117
+ * @returns An `Observable` of an array of service details
6118
+ */
6119
+ getHmctsServiceDetailsByCaseType(caseTypeId) {
6120
+ let url = this.appConfig.getLocationRefApiUrl();
6121
+ if (url) {
6122
+ url += '/orgServices';
6123
+ if (caseTypeId) {
6124
+ url += `?ccdCaseType=${caseTypeId}`;
6125
+ }
6126
+ return this.http.get(url, { observe: 'body' });
6127
+ }
6128
+ return of(null);
6129
+ }
5906
6130
  }
5907
6131
  CaseFlagRefdataService.ɵfac = function CaseFlagRefdataService_Factory(t) { return new (t || CaseFlagRefdataService)(i0.ɵɵinject(HttpService), i0.ɵɵinject(AbstractAppConfig)); };
5908
6132
  CaseFlagRefdataService.ɵprov = i0.ɵɵdefineInjectable({ token: CaseFlagRefdataService, factory: CaseFlagRefdataService.ɵfac });
@@ -10784,7 +11008,7 @@ function WriteCaseFlagFieldComponent_div_1_ng_container_5_Template(rf, ctx) { if
10784
11008
  } if (rf & 2) {
10785
11009
  const ctx_r8 = i0.ɵɵnextContext(2);
10786
11010
  i0.ɵɵadvance(1);
10787
- i0.ɵɵproperty("formGroup", ctx_r8.caseFlagParentFormGroup)("jurisdiction", ctx_r8.jurisdiction);
11011
+ i0.ɵɵproperty("formGroup", ctx_r8.caseFlagParentFormGroup)("jurisdiction", ctx_r8.jurisdiction)("caseTypeId", ctx_r8.caseTypeId)("hmctsServiceId", ctx_r8.hmctsServiceId);
10788
11012
  } }
10789
11013
  function WriteCaseFlagFieldComponent_div_1_ng_container_6_Template(rf, ctx) { if (rf & 1) {
10790
11014
  const _r17 = i0.ɵɵgetCurrentView();
@@ -10818,7 +11042,7 @@ function WriteCaseFlagFieldComponent_div_1_Template(rf, ctx) { if (rf & 1) {
10818
11042
  i0.ɵɵtext(3);
10819
11043
  i0.ɵɵelementEnd();
10820
11044
  i0.ɵɵtemplate(4, WriteCaseFlagFieldComponent_div_1_ng_container_4_Template, 2, 2, "ng-container", 11);
10821
- i0.ɵɵtemplate(5, WriteCaseFlagFieldComponent_div_1_ng_container_5_Template, 2, 2, "ng-container", 11);
11045
+ i0.ɵɵtemplate(5, WriteCaseFlagFieldComponent_div_1_ng_container_5_Template, 2, 4, "ng-container", 11);
10822
11046
  i0.ɵɵtemplate(6, WriteCaseFlagFieldComponent_div_1_ng_container_6_Template, 2, 3, "ng-container", 11);
10823
11047
  i0.ɵɵtemplate(7, WriteCaseFlagFieldComponent_div_1_ng_container_7_Template, 2, 2, "ng-container", 11);
10824
11048
  i0.ɵɵelementEnd();
@@ -10917,29 +11141,40 @@ class WriteCaseFlagFieldComponent extends AbstractFieldWriteComponent {
10917
11141
  }
10918
11142
  }), true);
10919
11143
  this.createFlagCaption = CaseFlagText.CAPTION;
10920
- // Get the jurisdiction from the CaseView object in the snapshot data (required for retrieving the available flag
11144
+ // Get the case type ID from the CaseView object in the snapshot data (required for retrieving the available flag
10921
11145
  // types for a case)
10922
- if (this.route.snapshot.data.case && this.route.snapshot.data.case.case_type &&
10923
- this.route.snapshot.data.case.case_type.jurisdiction) {
10924
- this.jurisdiction = this.route.snapshot.data.case.case_type.jurisdiction.id;
11146
+ if (this.route.snapshot.data.case && this.route.snapshot.data.case.case_type) {
11147
+ this.caseTypeId = this.route.snapshot.data.case.case_type.id;
11148
+ // Get the jurisdiction (required for retrieving the available flag types if unable to determine using case type ID)
11149
+ if (this.route.snapshot.data.case.case_type.jurisdiction) {
11150
+ this.jurisdiction = this.route.snapshot.data.case.case_type.jurisdiction.id;
11151
+ }
10925
11152
  }
10926
11153
  // Extract all flags-related data from the CaseEventTrigger object in the snapshot data
10927
- if (this.route.snapshot.data.eventTrigger && this.route.snapshot.data.eventTrigger.case_fields) {
10928
- this.flagsData = (this.route.snapshot.data.eventTrigger.case_fields)
10929
- .reduce((flags, caseField) => {
10930
- return FieldsUtils.extractFlagsDataFromCaseField(flags, caseField, caseField.id, caseField);
10931
- }, []);
10932
- // Set boolean indicating the display_context_parameter is "update"
10933
- this.isDisplayContextParameterUpdate =
10934
- this.setDisplayContextParameterUpdate((this.route.snapshot.data.eventTrigger.case_fields));
10935
- // Set starting field state
10936
- this.fieldState = this.isDisplayContextParameterUpdate ? CaseFlagFieldState.FLAG_MANAGE_CASE_FLAGS : CaseFlagFieldState.FLAG_LOCATION;
10937
- // Get case title, to be used by child components
10938
- this.caseEditDataService.caseTitle$.subscribe({
10939
- next: title => {
10940
- this.caseTitle = title.length > 0 ? title : this.caseNameMissing;
10941
- }
10942
- });
11154
+ if (this.route.snapshot.data.eventTrigger) {
11155
+ // Get the HMCTSServiceId from supplementary data, if it exists (required for retrieving the available flag types in
11156
+ // the first instance, only falling back on case type ID or jurisidiction if it's not present)
11157
+ if (this.route.snapshot.data.eventTrigger.supplementary_data
11158
+ && this.route.snapshot.data.eventTrigger.supplementary_data.HMCTSServiceId) {
11159
+ this.hmctsServiceId = this.route.snapshot.data.eventTrigger.supplementary_data.HMCTSServiceId;
11160
+ }
11161
+ if (this.route.snapshot.data.eventTrigger.case_fields) {
11162
+ this.flagsData = (this.route.snapshot.data.eventTrigger.case_fields)
11163
+ .reduce((flags, caseField) => {
11164
+ return FieldsUtils.extractFlagsDataFromCaseField(flags, caseField, caseField.id, caseField);
11165
+ }, []);
11166
+ // Set boolean indicating the display_context_parameter is "update"
11167
+ this.isDisplayContextParameterUpdate =
11168
+ this.setDisplayContextParameterUpdate((this.route.snapshot.data.eventTrigger.case_fields));
11169
+ // Set starting field state
11170
+ this.fieldState = this.isDisplayContextParameterUpdate ? CaseFlagFieldState.FLAG_MANAGE_CASE_FLAGS : CaseFlagFieldState.FLAG_LOCATION;
11171
+ // Get case title, to be used by child components
11172
+ this.caseEditDataService.caseTitle$.subscribe({
11173
+ next: title => {
11174
+ this.caseTitle = title.length > 0 ? title : this.caseNameMissing;
11175
+ }
11176
+ });
11177
+ }
10943
11178
  }
10944
11179
  }
10945
11180
  setDisplayContextParameterUpdate(caseFields) {
@@ -11172,7 +11407,7 @@ class WriteCaseFlagFieldComponent extends AbstractFieldWriteComponent {
11172
11407
  }
11173
11408
  }
11174
11409
  WriteCaseFlagFieldComponent.ɵfac = function WriteCaseFlagFieldComponent_Factory(t) { return new (t || WriteCaseFlagFieldComponent)(i0.ɵɵdirectiveInject(i1$1.ActivatedRoute), i0.ɵɵdirectiveInject(CaseEditDataService)); };
11175
- 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) {
11410
+ 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) {
11176
11411
  i0.ɵɵtemplate(0, WriteCaseFlagFieldComponent_div_0_Template, 4, 1, "div", 0);
11177
11412
  i0.ɵɵtemplate(1, WriteCaseFlagFieldComponent_div_1_Template, 8, 10, "div", 1);
11178
11413
  i0.ɵɵtemplate(2, WriteCaseFlagFieldComponent_div_2_Template, 4, 4, "div", 1);
@@ -15486,7 +15721,7 @@ CaseFileViewFolderSelectorComponent.ɵcmp = i0.ɵɵdefineComponent({ type: CaseF
15486
15721
  i0.ɵɵtextInterpolate1("Where do you want to move \"", ctx.data.document.document_filename, "\" file?");
15487
15722
  i0.ɵɵadvance(2);
15488
15723
  i0.ɵɵproperty("ngForOf", ctx.currentCategories);
15489
- } }, directives: [i1.NgForOf, i1.NgTemplateOutlet], styles: [":host{position:relative;display:block}.folders{margin-bottom:20px}.folder{display:none;border-top:1px solid #ccc;margin:0 0 -1px}.folder:last-child{border-bottom:1px solid #ccc}.folders>.folder,input:checked~.folder{display:block}.iconImg{position:relative;display:inline-block;height:28px}.folder>.folder{margin-left:20px}.folder label:before{top:3px}.folder label:after{top:13px}p{font-weight:700}button{margin-right:20px}.close{float:right;width:30px;height:30px;background:url(/assets/img/x.PNG) no-repeat 50%}.cancel,.close{cursor:pointer}.cdk-overlay-pane{overflow:auto}.cdk-overlay-pane::-webkit-scrollbar{width:7px}.cdk-overlay-pane::-webkit-scrollbar-thumb{border:4px solid transparent;background-clip:padding-box;border-radius:9999px;background-color:#aaa}.cdk-overlay-pane::-webkit-scrollbar-button{display:none}.cdk-overlay-pane::-webkit-scrollbar-track-piece{background:#eee}.cdk-overlay-pane::-webkit-scrollbar-thumb{background:#ccc}"], encapsulation: 2 });
15724
+ } }, directives: [i1.NgForOf, i1.NgTemplateOutlet], styles: [":host{position:relative;display:block}.folders{margin-bottom:20px}.folder{display:none;border-top:1px solid #ccc;margin:0 0 -1px}.folder,.folder:last-child{border-bottom:1px solid #ccc}.folders>.folder,input:checked~.folder{display:block}.iconImg{position:relative;display:inline-block;height:28px}.folder>.folder{margin-left:20px}.folder label:before{top:3px}.folder label:after{top:13px}p{font-weight:700}button{margin-right:20px}.close{float:right;width:30px;height:30px;background:url(/assets/img/x.PNG) no-repeat 50%}.cancel,.close{cursor:pointer}.cdk-overlay-pane{overflow:auto}.cdk-overlay-pane::-webkit-scrollbar{width:7px}.cdk-overlay-pane::-webkit-scrollbar-thumb{border:4px solid transparent;background-clip:padding-box;border-radius:9999px;background-color:#aaa}.cdk-overlay-pane::-webkit-scrollbar-button{display:none}.cdk-overlay-pane::-webkit-scrollbar-track-piece{background:#eee}.cdk-overlay-pane::-webkit-scrollbar-thumb{background:#ccc}"], encapsulation: 2 });
15490
15725
  (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CaseFileViewFolderSelectorComponent, [{
15491
15726
  type: Component,
15492
15727
  args: [{
@@ -16370,23 +16605,30 @@ class SelectFlagTypeComponent {
16370
16605
  && this.formGroup['caseField'].id === this.caseLevelCaseFlagsFieldId
16371
16606
  ? RefdataCaseFlagType.CASE
16372
16607
  : RefdataCaseFlagType.PARTY;
16373
- // HMCTS service code for a given jurisdiction is required to retrieve the relevant list of flag types
16374
- this.flagRefdata$ = this.caseFlagRefdataService.getHmctsServiceDetails(this.jurisdiction)
16375
- .pipe(
16376
- // Use switchMap to return an inner Observable of the flag types data, having received the service details
16377
- // including service_code. This avoids having nested `subscribe`s, which is an anti-pattern!
16378
- switchMap(serviceDetails => {
16379
- return this.caseFlagRefdataService.getCaseFlagsRefdata(serviceDetails[0].service_code, flagType);
16380
- }))
16381
- .subscribe({
16382
- next: flagTypes => {
16608
+ // If hmctsServiceId is present, use this to retrieve the relevant list of flag types
16609
+ if (this.hmctsServiceId) {
16610
+ this.flagRefdata$ = this.caseFlagRefdataService.getCaseFlagsRefdata(this.hmctsServiceId, flagType)
16611
+ .subscribe({
16383
16612
  // First (and only) object in the returned array should be the top-level "Party" flag type
16384
- this.flagTypes = flagTypes[0].childFlags;
16385
- },
16386
- error: error => {
16387
- this.onRefdataError(error);
16388
- }
16389
- });
16613
+ next: flagTypes => this.flagTypes = flagTypes[0].childFlags,
16614
+ error: error => this.onRefdataError(error)
16615
+ });
16616
+ }
16617
+ else {
16618
+ // Else, HMCTS service code is required to retrieve the relevant list of flag types; attempt to obtain it by case type ID first
16619
+ this.flagRefdata$ = this.caseFlagRefdataService.getHmctsServiceDetailsByCaseType(this.caseTypeId)
16620
+ .pipe(
16621
+ // If an error occurs retrieving HMCTS service details by case type ID, try by service name instead
16622
+ catchError(_ => this.caseFlagRefdataService.getHmctsServiceDetailsByServiceName(this.jurisdiction)),
16623
+ // Use switchMap to return an inner Observable of the flag types data, having received the service details
16624
+ // including service_code. This avoids having nested `subscribe`s, which is an anti-pattern!
16625
+ switchMap(serviceDetails => this.caseFlagRefdataService.getCaseFlagsRefdata(serviceDetails[0].service_code, flagType)))
16626
+ .subscribe({
16627
+ // First (and only) object in the returned array should be the top-level "Party" flag type
16628
+ next: flagTypes => this.flagTypes = flagTypes[0].childFlags,
16629
+ error: error => this.onRefdataError(error)
16630
+ });
16631
+ }
16390
16632
  }
16391
16633
  ngOnDestroy() {
16392
16634
  if (this.flagRefdata$) {
@@ -16457,7 +16699,7 @@ class SelectFlagTypeComponent {
16457
16699
  }
16458
16700
  }
16459
16701
  SelectFlagTypeComponent.ɵfac = function SelectFlagTypeComponent_Factory(t) { return new (t || SelectFlagTypeComponent)(i0.ɵɵdirectiveInject(CaseFlagRefdataService)); };
16460
- 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) {
16702
+ 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) {
16461
16703
  i0.ɵɵelementStart(0, "div", 0);
16462
16704
  i0.ɵɵelementStart(1, "div", 1);
16463
16705
  i0.ɵɵelementStart(2, "fieldset", 2);
@@ -16501,6 +16743,10 @@ SelectFlagTypeComponent.ɵcmp = i0.ɵɵdefineComponent({ type: SelectFlagTypeCom
16501
16743
  type: Input
16502
16744
  }], jurisdiction: [{
16503
16745
  type: Input
16746
+ }], caseTypeId: [{
16747
+ type: Input
16748
+ }], hmctsServiceId: [{
16749
+ type: Input
16504
16750
  }], caseFlagStateEmitter: [{
16505
16751
  type: Output
16506
16752
  }], flagCommentsOptionalEmitter: [{
@@ -18512,7 +18758,10 @@ DatetimePickerComponent.ɵcmp = i0.ɵɵdefineComponent({ type: DatetimePickerCom
18512
18758
  i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.inputElement = _t.first);
18513
18759
  } }, inputs: { dateControl: "dateControl" }, features: [i0.ɵɵProvidersFeature([
18514
18760
  { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_MOMENT_FORMATS },
18515
- { provide: NgxMatDateAdapter, useClass: NgxMatMomentAdapter },
18761
+ { provide: NgxMatDateAdapter,
18762
+ useClass: NgxMatMomentAdapter,
18763
+ deps: [MAT_DATE_LOCALE, NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS]
18764
+ },
18516
18765
  { provide: NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
18517
18766
  ]), 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) {
18518
18767
  i0.ɵɵelementStart(0, "div", 0);
@@ -18565,7 +18814,10 @@ DatetimePickerComponent.ɵcmp = i0.ɵɵdefineComponent({ type: DatetimePickerCom
18565
18814
  encapsulation: ViewEncapsulation.None,
18566
18815
  providers: [
18567
18816
  { provide: NGX_MAT_DATE_FORMATS, useValue: CUSTOM_MOMENT_FORMATS },
18568
- { provide: NgxMatDateAdapter, useClass: NgxMatMomentAdapter },
18817
+ { provide: NgxMatDateAdapter,
18818
+ useClass: NgxMatMomentAdapter,
18819
+ deps: [MAT_DATE_LOCALE, NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS]
18820
+ },
18569
18821
  { provide: NGX_MAT_MOMENT_DATE_ADAPTER_OPTIONS, useValue: { useUtc: true } }
18570
18822
  ]
18571
18823
  }]
@@ -23938,11 +24190,12 @@ class CaseFullAccessViewComponent {
23938
24190
  this.activitySubscription = this.postViewActivity().subscribe();
23939
24191
  });
23940
24192
  }
24193
+ this.checkRouteAndSetCaseViewTab();
23941
24194
  // Check for active Case Flags
23942
24195
  this.activeCaseFlags = this.hasActiveCaseFlags();
23943
24196
  }
23944
24197
  ngOnChanges(changes) {
23945
- if (!changes.prependedTabs.firstChange) {
24198
+ if (changes && changes.prependedTabs && !changes.prependedTabs.firstChange) {
23946
24199
  this.init();
23947
24200
  this.crf.detectChanges();
23948
24201
  this.organiseTabPosition();
@@ -23967,6 +24220,21 @@ class CaseFullAccessViewComponent {
23967
24220
  subscription.unsubscribe();
23968
24221
  }
23969
24222
  }
24223
+ checkRouteAndSetCaseViewTab() {
24224
+ this.router.events
24225
+ .pipe(filter((event) => event instanceof NavigationEnd))
24226
+ .subscribe((event) => {
24227
+ const url = event && event.url;
24228
+ if (url) {
24229
+ const tabUrl = url ? url.split('#') : null;
24230
+ const tab = tabUrl && tabUrl.length > 1 ? tabUrl[tabUrl.length - 1].replaceAll('%20', ' ') : '';
24231
+ const matTab = this.tabGroup._tabs.find((x) => x.textLabel.toLowerCase() === tab.toLowerCase());
24232
+ if (matTab && matTab.position) {
24233
+ this.tabGroup.selectedIndex = matTab.position;
24234
+ }
24235
+ }
24236
+ });
24237
+ }
23970
24238
  postViewActivity() {
23971
24239
  return this.activityPollingService.postViewActivity(this.caseDetails.case_id);
23972
24240
  }
@@ -27423,11 +27691,11 @@ function SearchResultComponent_table_0_th_9_Template(rf, ctx) { if (rf & 1) {
27423
27691
  i0.ɵɵadvance(2);
27424
27692
  i0.ɵɵproperty("checked", ctx_r6.allOnPageSelected())("disabled", !ctx_r6.canAnyBeShared());
27425
27693
  } }
27426
- function SearchResultComponent_table_0_th_10_div_6_Template(rf, ctx) { if (rf & 1) {
27694
+ function SearchResultComponent_table_0_th_10_div_4_Template(rf, ctx) { if (rf & 1) {
27427
27695
  const _r19 = i0.ɵɵgetCurrentView();
27428
27696
  i0.ɵɵelementStart(0, "div", 27);
27429
27697
  i0.ɵɵelementStart(1, "a", 28);
27430
- 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); });
27698
+ 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); });
27431
27699
  i0.ɵɵelementEnd();
27432
27700
  i0.ɵɵelementEnd();
27433
27701
  } if (rf & 2) {
@@ -27439,16 +27707,12 @@ function SearchResultComponent_table_0_th_10_div_6_Template(rf, ctx) { if (rf &
27439
27707
  function SearchResultComponent_table_0_th_10_Template(rf, ctx) { if (rf & 1) {
27440
27708
  const _r22 = i0.ɵɵgetCurrentView();
27441
27709
  i0.ɵɵelementStart(0, "th");
27442
- i0.ɵɵelementStart(1, "table", 24);
27443
- i0.ɵɵelementStart(2, "tr");
27444
- i0.ɵɵelementStart(3, "th");
27445
- i0.ɵɵelementStart(4, "div", 25);
27446
- 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); });
27447
- i0.ɵɵtext(5);
27448
- i0.ɵɵelementEnd();
27449
- i0.ɵɵtemplate(6, SearchResultComponent_table_0_th_10_div_6_Template, 2, 1, "div", 26);
27450
- i0.ɵɵelementEnd();
27710
+ i0.ɵɵelementStart(1, "div", 24);
27711
+ i0.ɵɵelementStart(2, "div", 25);
27712
+ 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); });
27713
+ i0.ɵɵtext(3);
27451
27714
  i0.ɵɵelementEnd();
27715
+ i0.ɵɵtemplate(4, SearchResultComponent_table_0_th_10_div_4_Template, 2, 1, "div", 26);
27452
27716
  i0.ɵɵelementEnd();
27453
27717
  i0.ɵɵelementEnd();
27454
27718
  } if (rf & 2) {
@@ -27456,7 +27720,7 @@ function SearchResultComponent_table_0_th_10_Template(rf, ctx) { if (rf & 1) {
27456
27720
  const ctx_r7 = i0.ɵɵnextContext(2);
27457
27721
  i0.ɵɵadvance(1);
27458
27722
  i0.ɵɵattribute("aria-label", "Sort by " + col_r15.label + " " + ctx_r7.isSortAscending(col_r15) ? "ascending" : "descending");
27459
- i0.ɵɵadvance(4);
27723
+ i0.ɵɵadvance(2);
27460
27724
  i0.ɵɵtextInterpolate(col_r15.label);
27461
27725
  i0.ɵɵadvance(1);
27462
27726
  i0.ɵɵproperty("ngIf", ctx_r7.comparator(col_r15));
@@ -27728,7 +27992,7 @@ function SearchResultComponent_table_0_Template(rf, ctx) { if (rf & 1) {
27728
27992
  i0.ɵɵelementStart(7, "thead");
27729
27993
  i0.ɵɵelementStart(8, "tr", 7);
27730
27994
  i0.ɵɵtemplate(9, SearchResultComponent_table_0_th_9_Template, 4, 2, "th", 8);
27731
- i0.ɵɵtemplate(10, SearchResultComponent_table_0_th_10_Template, 7, 3, "th", 9);
27995
+ i0.ɵɵtemplate(10, SearchResultComponent_table_0_th_10_Template, 5, 3, "th", 9);
27732
27996
  i0.ɵɵtemplate(11, SearchResultComponent_table_0_th_11_Template, 1, 0, "th", 10);
27733
27997
  i0.ɵɵelementEnd();
27734
27998
  i0.ɵɵelementEnd();