@hmcts/media-viewer 2.7.7 → 2.7.11

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 (40) hide show
  1. package/assets/sass/comment-set-header.scss +11 -0
  2. package/assets/sass/toolbar/main-toolbar.scss +3 -3
  3. package/assets/sass/toolbar/redaction-toolbar.scss +7 -0
  4. package/assets/sass/toolbar/search-bar.scss +8 -0
  5. package/bundles/hmcts-media-viewer.umd.js +75 -31
  6. package/bundles/hmcts-media-viewer.umd.js.map +1 -1
  7. package/bundles/hmcts-media-viewer.umd.min.js +1 -1
  8. package/bundles/hmcts-media-viewer.umd.min.js.map +1 -1
  9. package/esm2015/lib/annotations/comment-set/comment/comment.component.js +12 -12
  10. package/esm2015/lib/annotations/comment-set/comment-set-header/comment-set-header.component.js +9 -3
  11. package/esm2015/lib/annotations/comment-set/comment-set-render.service.js +2 -2
  12. package/esm2015/lib/annotations/comment-set/comment-set.component.js +28 -3
  13. package/esm2015/lib/toolbar/main-toolbar/main-toolbar.component.js +2 -2
  14. package/esm2015/lib/toolbar/redaction-toolbar/redaction-toolbar.component.js +8 -2
  15. package/esm2015/lib/toolbar/search-bar/search-bar.component.js +8 -2
  16. package/esm2015/lib/viewers/convertible-content-viewer/convertible-content-viewer.component.js +7 -2
  17. package/esm2015/lib/viewers/pdf-viewer/pdf-viewer.component.js +2 -20
  18. package/esm5/lib/annotations/comment-set/comment/comment.component.js +12 -12
  19. package/esm5/lib/annotations/comment-set/comment-set-header/comment-set-header.component.js +12 -3
  20. package/esm5/lib/annotations/comment-set/comment-set-render.service.js +2 -2
  21. package/esm5/lib/annotations/comment-set/comment-set.component.js +32 -3
  22. package/esm5/lib/toolbar/main-toolbar/main-toolbar.component.js +2 -2
  23. package/esm5/lib/toolbar/redaction-toolbar/redaction-toolbar.component.js +11 -2
  24. package/esm5/lib/toolbar/search-bar/search-bar.component.js +11 -2
  25. package/esm5/lib/viewers/convertible-content-viewer/convertible-content-viewer.component.js +7 -2
  26. package/esm5/lib/viewers/pdf-viewer/pdf-viewer.component.js +2 -20
  27. package/fesm2015/hmcts-media-viewer.js +1316 -1285
  28. package/fesm2015/hmcts-media-viewer.js.map +1 -1
  29. package/fesm5/hmcts-media-viewer.js +3355 -3311
  30. package/fesm5/hmcts-media-viewer.js.map +1 -1
  31. package/hmcts-media-viewer-v2.7.11.tgz +0 -0
  32. package/hmcts-media-viewer.metadata.json +1 -1
  33. package/lib/annotations/comment-set/comment/comment.component.d.ts +2 -2
  34. package/lib/annotations/comment-set/comment-set-header/comment-set-header.component.d.ts +1 -0
  35. package/lib/annotations/comment-set/comment-set.component.d.ts +4 -1
  36. package/lib/toolbar/redaction-toolbar/redaction-toolbar.component.d.ts +1 -0
  37. package/lib/toolbar/search-bar/search-bar.component.d.ts +1 -0
  38. package/lib/viewers/pdf-viewer/pdf-viewer.component.d.ts +0 -3
  39. package/package.json +1 -1
  40. package/hmcts-media-viewer-v2.7.7.tgz +0 -0
@@ -842,357 +842,166 @@ const defaultUnsupportedOptions = {
842
842
  * @fileoverview added by tsickle
843
843
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
844
844
  */
845
- // TODO: replace by NgRx
846
- class CommentService {
847
- constructor() {
848
- this.unsavedChanges = new Subject();
849
- }
850
- /**
851
- * @param {?} commentSetComponent
852
- * @return {?}
853
- */
854
- setCommentSet(commentSetComponent) {
855
- this.commentSetComponent = commentSetComponent;
856
- }
857
- /**
858
- * @param {?} changes
859
- * @return {?}
860
- */
861
- onCommentChange(changes) {
862
- this.unsavedChanges.next(changes);
863
- }
864
- /**
865
- * @return {?}
866
- */
867
- getUnsavedChanges() {
868
- return this.unsavedChanges.asObservable();
869
- }
870
- /**
871
- * @param {?} annotation
872
- * @return {?}
873
- */
874
- hasUnsavedComments(annotation) {
875
- if (annotation.comments.length > 0) {
876
- /** @type {?} */
877
- const comment = this.getComment(annotation);
878
- return comment.hasUnsavedChanges;
879
- }
880
- return false;
881
- }
882
- /**
883
- * @param {?} annotation
884
- * @param {?} hasUnsavedChanges
885
- * @return {?}
886
- */
887
- updateUnsavedCommentsStatus(annotation, hasUnsavedChanges) {
888
- /** @type {?} */
889
- const comment = this.getComment(annotation);
890
- comment.hasUnsavedChanges = hasUnsavedChanges;
891
- this.allCommentsSaved();
892
- }
893
- /**
894
- * @param {?} annotation
895
- * @return {?}
896
- */
897
- getComment(annotation) {
898
- return this.commentSetComponent.commentComponents
899
- .find((/**
900
- * @param {?} c
901
- * @return {?}
902
- */
903
- c => c.comment.annotationId === annotation.comments[0].annotationId));
904
- }
905
- /**
906
- * @return {?}
907
- */
908
- resetCommentSet() {
909
- this.commentSetComponent = null;
910
- }
911
- /**
912
- * @return {?}
913
- */
914
- allCommentsSaved() {
915
- this.onCommentChange(this.commentSetComponent.commentComponents.some((/**
916
- * @param {?} comment
917
- * @return {?}
918
- */
919
- comment => comment.hasUnsavedChanges === true)));
920
- }
921
- }
922
- CommentService.decorators = [
923
- { type: Injectable }
924
- ];
925
-
926
- /**
927
- * @fileoverview added by tsickle
928
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
929
- */
930
- class CommentSetRenderService {
931
- /**
932
- * @param {?} commentComponents
933
- * @param {?} pageHeights
934
- * @param {?} rotate
935
- * @param {?} zoom
936
- * @return {?}
937
- */
938
- redrawComponents(commentComponents, pageHeights, rotate, zoom) {
939
- /** @type {?} */
940
- let prevComment;
941
- this.sortComponents(commentComponents, pageHeights, rotate, zoom).forEach((/**
942
- * @param {?} comment
943
- * @return {?}
944
- */
945
- (comment) => {
946
- this.adjustIfOverlapping(comment, prevComment, zoom);
947
- prevComment = comment;
948
- }));
949
- }
950
- /**
951
- * @param {?} commentComponents
952
- * @param {?} pageHeights
953
- * @param {?} rotate
954
- * @param {?} zoom
955
- * @return {?}
956
- */
957
- sortComponents(commentComponents, pageHeights, rotate, zoom) {
958
- return commentComponents.sort((/**
959
- * @param {?} a
960
- * @param {?} b
961
- * @return {?}
962
- */
963
- (a, b) => {
964
- a.rectTop = this.top(a._rectangle, pageHeights[a.page - 1], rotate, zoom);
965
- b.rectTop = this.top(b._rectangle, pageHeights[b.page - 1], rotate, zoom);
966
- return this.processSort(a, b);
967
- }));
968
- }
969
- /**
970
- * @private
971
- * @param {?} comment
972
- * @param {?} prevComment
973
- * @param {?} zoom
974
- * @return {?}
975
- */
976
- adjustIfOverlapping(comment, prevComment, zoom) {
977
- if (prevComment) {
978
- /** @type {?} */
979
- const endOfPrevComment = prevComment.commentTop + this.height(prevComment);
980
- if (comment.commentTop <= endOfPrevComment) {
981
- comment.rectTop = (endOfPrevComment - comment.totalPreviousPagesHeight) / zoom;
982
- }
983
- }
984
- }
985
- /**
986
- * @private
987
- * @param {?} a
988
- * @param {?} b
989
- * @return {?}
990
- */
991
- processSort(a, b) {
992
- if (this.onSameLine(a, b)) {
993
- return a.rectLeft >= b.rectLeft ? 1 : -1;
994
- }
995
- return a.commentTop >= b.commentTop ? 1 : -1;
996
- }
997
- /**
998
- * @private
999
- * @param {?} a
1000
- * @param {?} b
1001
- * @return {?}
1002
- */
1003
- onSameLine(a, b) {
1004
- return this.difference(a.commentTop, b.commentTop) === 0;
1005
- }
1006
- /**
1007
- * @private
1008
- * @param {?} rectangle
1009
- * @param {?} height
1010
- * @param {?} rotate
1011
- * @param {?} zoom
1012
- * @return {?}
1013
- */
1014
- top(rectangle, height, rotate, zoom) {
1015
- /** @type {?} */
1016
- const actualHeight = height / zoom;
1017
- switch (rotate) {
1018
- case 90: return rectangle.x;
1019
- case 180: return actualHeight - (rectangle.y + rectangle.height);
1020
- case 270: return actualHeight - (rectangle.x + rectangle.width);
1021
- default: return rectangle.y;
1022
- }
1023
- }
1024
- /**
1025
- * @private
1026
- * @param {?} element
1027
- * @return {?}
1028
- */
1029
- height(element) {
1030
- return element.form.nativeElement.getBoundingClientRect().height;
1031
- }
1032
- /**
1033
- * @private
1034
- * @param {?} a
1035
- * @param {?} b
1036
- * @return {?}
1037
- */
1038
- difference(a, b) { return Math.abs(a - b); }
1039
- }
1040
- CommentSetRenderService.decorators = [
1041
- { type: Injectable }
1042
- ];
1043
-
1044
- /**
1045
- * @fileoverview added by tsickle
1046
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1047
- */
1048
- /** @type {?} */
1049
- const LOAD_ANNOTATION_SET = '[Annotations] Load Annotation Set';
1050
845
  /** @type {?} */
1051
- const LOAD_ANNOTATION_SET_SUCCESS = '[Annotations] Load Annotation Set Success';
846
+ const SET_DOCUMENT_ID = '[Document] Set Document Id';
1052
847
  /** @type {?} */
1053
- const LOAD_ANNOTATION_SET_FAIL = '[Annotations] Load Annotation Set Fail';
848
+ const POSITION_UPDATED = '[Document] Position Updated';
1054
849
  /** @type {?} */
1055
- const SAVE_ANNOTATION = '[Annotations] Save Annotation';
850
+ const ADD_PAGES = '[Document] Add Pages';
1056
851
  /** @type {?} */
1057
- const SAVE_ANNOTATION_SUCCESS = '[Annotations] Save Annotation Success';
852
+ const CONVERT = '[Document] Convert';
1058
853
  /** @type {?} */
1059
- const SAVE_ANNOTATION_FAIL = '[Annotations] Save Annotation Fail';
854
+ const CONVERT_SUCCESS = '[Document] Convert Success';
1060
855
  /** @type {?} */
1061
- const ADD_OR_EDIT_COMMENT = '[Annotations] Add or Edit Comment';
856
+ const CONVERT_FAIL = '[Document] Convert Fail';
1062
857
  /** @type {?} */
1063
- const DELETE_ANNOTATION = '[Annotations] Delete Annotation';
858
+ const CLEAR_CONVERT_DOC_URL = '[Document] Clear Convert Doc Url';
1064
859
  /** @type {?} */
1065
- const DELETE_ANNOTATION_SUCCESS = '[Annotations] Delete Annotation Success';
860
+ const LOAD_ROTATION = '[Document] Load Rotation';
1066
861
  /** @type {?} */
1067
- const DELETE_ANNOTATION_FAIL = '[Annotations] Delete Annotation Fail';
862
+ const LOAD_ROTATION_SUCCESS = '[Document] Load Rotation Success';
1068
863
  /** @type {?} */
1069
- const SELECT_ANNOTATION = '[Annotations] Select Annotation';
864
+ const LOAD_ROTATION_FAIL = '[Document] Load Rotation Fail';
1070
865
  /** @type {?} */
1071
- const SEARCH_COMMENT = '[Comments] Search Comments';
866
+ const SAVE_ROTATION = '[Document] Save Rotation';
1072
867
  /** @type {?} */
1073
- const APPLY_COMMENT_SUMMARY_FILTER = '[Comments] Apply Comment Summary Filter';
868
+ const SAVE_ROTATION_SUCCESS = '[Document] Save Rotation Success';
1074
869
  /** @type {?} */
1075
- const CLEAR_COMMENT_SUMMARY_FILTER = '[Comments] Clear Comment Summary Filter';
1076
- class LoadAnnotationSet {
870
+ const SAVE_ROTATION_FAIL = '[Document] Save Rotation Fail';
871
+ class SetDocumentId {
1077
872
  /**
1078
873
  * @param {?} payload
1079
874
  */
1080
875
  constructor(payload) {
1081
876
  this.payload = payload;
1082
- this.type = LOAD_ANNOTATION_SET;
877
+ this.type = SET_DOCUMENT_ID;
1083
878
  }
1084
879
  }
1085
- class LoadAnnotationSetSucess {
880
+ class AddPages {
1086
881
  /**
1087
882
  * @param {?} payload
1088
883
  */
1089
884
  constructor(payload) {
1090
885
  this.payload = payload;
1091
- this.type = LOAD_ANNOTATION_SET_SUCCESS;
886
+ this.type = ADD_PAGES;
1092
887
  }
1093
888
  }
1094
- class LoadAnnotationSetFail {
889
+ class PdfPositionUpdate {
1095
890
  /**
1096
891
  * @param {?} payload
1097
892
  */
1098
893
  constructor(payload) {
1099
894
  this.payload = payload;
1100
- this.type = LOAD_ANNOTATION_SET_FAIL;
895
+ this.type = POSITION_UPDATED;
1101
896
  }
1102
897
  }
1103
- class SaveAnnotation {
898
+ class Convert {
1104
899
  /**
1105
900
  * @param {?} payload
1106
901
  */
1107
902
  constructor(payload) {
1108
903
  this.payload = payload;
1109
- this.type = SAVE_ANNOTATION;
904
+ this.type = CONVERT;
1110
905
  }
1111
906
  }
1112
- class SaveAnnotationSuccess {
907
+ class ConvertSuccess {
1113
908
  /**
1114
909
  * @param {?} payload
1115
910
  */
1116
911
  constructor(payload) {
1117
912
  this.payload = payload;
1118
- this.type = SAVE_ANNOTATION_SUCCESS;
913
+ this.type = CONVERT_SUCCESS;
1119
914
  }
1120
915
  }
1121
- class SaveAnnotationFail {
916
+ class ConvertFailure {
1122
917
  /**
1123
918
  * @param {?} payload
1124
919
  */
1125
920
  constructor(payload) {
1126
921
  this.payload = payload;
1127
- this.type = SAVE_ANNOTATION_FAIL;
922
+ this.type = CONVERT_FAIL;
1128
923
  }
1129
924
  }
1130
- class AddOrEditComment {
1131
- /**
925
+ class ClearConvertDocUrl {
926
+ constructor() {
927
+ this.type = CLEAR_CONVERT_DOC_URL;
928
+ }
929
+ }
930
+ class LoadRotation {
931
+ /**
1132
932
  * @param {?} payload
1133
933
  */
1134
934
  constructor(payload) {
1135
935
  this.payload = payload;
1136
- this.type = ADD_OR_EDIT_COMMENT;
936
+ this.type = LOAD_ROTATION;
1137
937
  }
1138
938
  }
1139
- class DeleteAnnotation {
939
+ class LoadRotationSuccess {
1140
940
  /**
1141
941
  * @param {?} payload
1142
942
  */
1143
943
  constructor(payload) {
1144
944
  this.payload = payload;
1145
- this.type = DELETE_ANNOTATION;
945
+ this.type = LOAD_ROTATION_SUCCESS;
1146
946
  }
1147
947
  }
1148
- class DeleteAnnotationSuccess {
948
+ class LoadRotationFailure {
1149
949
  /**
1150
950
  * @param {?} payload
1151
951
  */
1152
952
  constructor(payload) {
1153
953
  this.payload = payload;
1154
- this.type = DELETE_ANNOTATION_SUCCESS;
954
+ this.type = LOAD_ROTATION_FAIL;
1155
955
  }
1156
956
  }
1157
- class DeleteAnnotationFail {
957
+ class SaveRotation {
1158
958
  /**
1159
959
  * @param {?} payload
1160
960
  */
1161
961
  constructor(payload) {
1162
962
  this.payload = payload;
1163
- this.type = DELETE_ANNOTATION_FAIL;
963
+ this.type = SAVE_ROTATION;
1164
964
  }
1165
965
  }
1166
- class SelectedAnnotation {
966
+ class SaveRotationSuccess {
1167
967
  /**
1168
968
  * @param {?} payload
1169
969
  */
1170
970
  constructor(payload) {
1171
971
  this.payload = payload;
1172
- this.type = SELECT_ANNOTATION;
972
+ this.type = SAVE_ROTATION_SUCCESS;
1173
973
  }
1174
974
  }
1175
- class SearchComment {
975
+ class SaveRotationFailure {
1176
976
  /**
1177
977
  * @param {?} payload
1178
978
  */
1179
979
  constructor(payload) {
1180
980
  this.payload = payload;
1181
- this.type = SEARCH_COMMENT;
981
+ this.type = SAVE_ROTATION_FAIL;
1182
982
  }
1183
983
  }
1184
- class ApplyCommentSymmaryFilter {
984
+
985
+ /**
986
+ * @fileoverview added by tsickle
987
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
988
+ */
989
+ /** @type {?} */
990
+ const ADD_FILTER_TAGS = '[Tags] Add Filter Tags';
991
+ /** @type {?} */
992
+ const CLEAR_FILTER_TAGS = '[Tags] Clear Filter Tags';
993
+ class AddFilterTags {
1185
994
  /**
1186
995
  * @param {?} payload
1187
996
  */
1188
997
  constructor(payload) {
1189
998
  this.payload = payload;
1190
- this.type = APPLY_COMMENT_SUMMARY_FILTER;
999
+ this.type = ADD_FILTER_TAGS;
1191
1000
  }
1192
1001
  }
1193
- class ClearCommentSummaryFilters {
1002
+ class ClearFilterTags {
1194
1003
  constructor() {
1195
- this.type = CLEAR_COMMENT_SUMMARY_FILTER;
1004
+ this.type = CLEAR_FILTER_TAGS;
1196
1005
  }
1197
1006
  }
1198
1007
 
@@ -1201,142 +1010,87 @@ class ClearCommentSummaryFilters {
1201
1010
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1202
1011
  */
1203
1012
  /** @type {?} */
1204
- const SET_DOCUMENT_ID = '[Document] Set Document Id';
1205
- /** @type {?} */
1206
- const POSITION_UPDATED = '[Document] Position Updated';
1207
- /** @type {?} */
1208
- const ADD_PAGES = '[Document] Add Pages';
1209
- /** @type {?} */
1210
- const CONVERT = '[Document] Convert';
1211
- /** @type {?} */
1212
- const CONVERT_SUCCESS = '[Document] Convert Success';
1213
- /** @type {?} */
1214
- const CONVERT_FAIL = '[Document] Convert Fail';
1013
+ const SET_CASE_ID = '[Icp] Set Case Id';
1215
1014
  /** @type {?} */
1216
- const CLEAR_CONVERT_DOC_URL = '[Document] Clear Convert Doc Url';
1015
+ const LOAD_ICP_SESSION = '[Icp] Load Session';
1217
1016
  /** @type {?} */
1218
- const LOAD_ROTATION = '[Document] Load Rotation';
1017
+ const LOAD_ICP_SESSION_FAIL = '[Icp] Load Session Failure';
1219
1018
  /** @type {?} */
1220
- const LOAD_ROTATION_SUCCESS = '[Document] Load Rotation Success';
1019
+ const JOIN_ICP_SOCKET_SESSION = '[Icp] Join Socket Session';
1221
1020
  /** @type {?} */
1222
- const LOAD_ROTATION_FAIL = '[Document] Load Rotation Fail';
1021
+ const ICP_SOCKET_SESSION_JOINED = '[Icp] Socket Session Joined';
1223
1022
  /** @type {?} */
1224
- const SAVE_ROTATION = '[Document] Save Rotation';
1023
+ const LEAVE_ICP_SOCKET_SESSION = '[Icp] Leave Socket Session';
1225
1024
  /** @type {?} */
1226
- const SAVE_ROTATION_SUCCESS = '[Document] Save Rotation Success';
1025
+ const ICP_PRESENTER_UPDATED = '[Icp] Presenter Updated';
1227
1026
  /** @type {?} */
1228
- const SAVE_ROTATION_FAIL = '[Document] Save Rotation Fail';
1229
- class SetDocumentId {
1230
- /**
1231
- * @param {?} payload
1232
- */
1233
- constructor(payload) {
1234
- this.payload = payload;
1235
- this.type = SET_DOCUMENT_ID;
1236
- }
1237
- }
1238
- class AddPages {
1027
+ const ICP_PARTICIPANT_LIST_UPDATED = '[Icp] Participant List Updated';
1028
+ class SetCaseId {
1239
1029
  /**
1240
1030
  * @param {?} payload
1241
1031
  */
1242
1032
  constructor(payload) {
1243
1033
  this.payload = payload;
1244
- this.type = ADD_PAGES;
1034
+ this.type = SET_CASE_ID;
1245
1035
  }
1246
1036
  }
1247
- class PdfPositionUpdate {
1037
+ class LoadIcpSession {
1248
1038
  /**
1249
1039
  * @param {?} payload
1250
1040
  */
1251
1041
  constructor(payload) {
1252
1042
  this.payload = payload;
1253
- this.type = POSITION_UPDATED;
1043
+ this.type = LOAD_ICP_SESSION;
1254
1044
  }
1255
1045
  }
1256
- class Convert {
1046
+ class LoadIcpSessionFailure {
1257
1047
  /**
1258
1048
  * @param {?} payload
1259
1049
  */
1260
1050
  constructor(payload) {
1261
1051
  this.payload = payload;
1262
- this.type = CONVERT;
1052
+ this.type = LOAD_ICP_SESSION_FAIL;
1263
1053
  }
1264
1054
  }
1265
- class ConvertSuccess {
1055
+ class JoinIcpSocketSession {
1266
1056
  /**
1267
1057
  * @param {?} payload
1268
1058
  */
1269
1059
  constructor(payload) {
1270
1060
  this.payload = payload;
1271
- this.type = CONVERT_SUCCESS;
1061
+ this.type = JOIN_ICP_SOCKET_SESSION;
1272
1062
  }
1273
1063
  }
1274
- class ConvertFailure {
1064
+ class IcpSocketSessionJoined {
1275
1065
  /**
1276
1066
  * @param {?} payload
1277
1067
  */
1278
1068
  constructor(payload) {
1279
1069
  this.payload = payload;
1280
- this.type = CONVERT_FAIL;
1070
+ this.type = ICP_SOCKET_SESSION_JOINED;
1281
1071
  }
1282
1072
  }
1283
- class ClearConvertDocUrl {
1073
+ class LeaveIcpSocketSession {
1284
1074
  constructor() {
1285
- this.type = CLEAR_CONVERT_DOC_URL;
1286
- }
1287
- }
1288
- class LoadRotation {
1289
- /**
1290
- * @param {?} payload
1291
- */
1292
- constructor(payload) {
1293
- this.payload = payload;
1294
- this.type = LOAD_ROTATION;
1295
- }
1296
- }
1297
- class LoadRotationSuccess {
1298
- /**
1299
- * @param {?} payload
1300
- */
1301
- constructor(payload) {
1302
- this.payload = payload;
1303
- this.type = LOAD_ROTATION_SUCCESS;
1304
- }
1305
- }
1306
- class LoadRotationFailure {
1307
- /**
1308
- * @param {?} payload
1309
- */
1310
- constructor(payload) {
1311
- this.payload = payload;
1312
- this.type = LOAD_ROTATION_FAIL;
1313
- }
1314
- }
1315
- class SaveRotation {
1316
- /**
1317
- * @param {?} payload
1318
- */
1319
- constructor(payload) {
1320
- this.payload = payload;
1321
- this.type = SAVE_ROTATION;
1075
+ this.type = LEAVE_ICP_SOCKET_SESSION;
1322
1076
  }
1323
1077
  }
1324
- class SaveRotationSuccess {
1078
+ class IcpPresenterUpdated {
1325
1079
  /**
1326
1080
  * @param {?} payload
1327
1081
  */
1328
1082
  constructor(payload) {
1329
1083
  this.payload = payload;
1330
- this.type = SAVE_ROTATION_SUCCESS;
1084
+ this.type = ICP_PRESENTER_UPDATED;
1331
1085
  }
1332
1086
  }
1333
- class SaveRotationFailure {
1087
+ class IcpParticipantListUpdated {
1334
1088
  /**
1335
1089
  * @param {?} payload
1336
1090
  */
1337
1091
  constructor(payload) {
1338
1092
  this.payload = payload;
1339
- this.type = SAVE_ROTATION_FAIL;
1093
+ this.type = ICP_PARTICIPANT_LIST_UPDATED;
1340
1094
  }
1341
1095
  }
1342
1096
 
@@ -1508,76 +1262,231 @@ const getConvertedDocument = (/**
1508
1262
  * @fileoverview added by tsickle
1509
1263
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1510
1264
  */
1511
- /*
1512
- @dynamic
1513
- marking class as dynamic to stop compiler throwing error for lambda in static function
1514
- see https://github.com/angular/angular/issues/19698#issuecomment-338340211
1515
- */
1516
- class StoreUtils {
1265
+ /** @type {?} */
1266
+ const LOAD_ANNOTATION_SET = '[Annotations] Load Annotation Set';
1267
+ /** @type {?} */
1268
+ const LOAD_ANNOTATION_SET_SUCCESS = '[Annotations] Load Annotation Set Success';
1269
+ /** @type {?} */
1270
+ const LOAD_ANNOTATION_SET_FAIL = '[Annotations] Load Annotation Set Fail';
1271
+ /** @type {?} */
1272
+ const SAVE_ANNOTATION = '[Annotations] Save Annotation';
1273
+ /** @type {?} */
1274
+ const SAVE_ANNOTATION_SUCCESS = '[Annotations] Save Annotation Success';
1275
+ /** @type {?} */
1276
+ const SAVE_ANNOTATION_FAIL = '[Annotations] Save Annotation Fail';
1277
+ /** @type {?} */
1278
+ const ADD_OR_EDIT_COMMENT = '[Annotations] Add or Edit Comment';
1279
+ /** @type {?} */
1280
+ const DELETE_ANNOTATION = '[Annotations] Delete Annotation';
1281
+ /** @type {?} */
1282
+ const DELETE_ANNOTATION_SUCCESS = '[Annotations] Delete Annotation Success';
1283
+ /** @type {?} */
1284
+ const DELETE_ANNOTATION_FAIL = '[Annotations] Delete Annotation Fail';
1285
+ /** @type {?} */
1286
+ const SELECT_ANNOTATION = '[Annotations] Select Annotation';
1287
+ /** @type {?} */
1288
+ const SEARCH_COMMENT = '[Comments] Search Comments';
1289
+ /** @type {?} */
1290
+ const APPLY_COMMENT_SUMMARY_FILTER = '[Comments] Apply Comment Summary Filter';
1291
+ /** @type {?} */
1292
+ const CLEAR_COMMENT_SUMMARY_FILTER = '[Comments] Clear Comment Summary Filter';
1293
+ class LoadAnnotationSet {
1517
1294
  /**
1518
- * @param {?} annotations
1519
- * @param {?} key
1520
- * @return {?}
1295
+ * @param {?} payload
1521
1296
  */
1522
- static groupByKeyEntities(annotations, key) {
1523
- return annotations.reduce((/**
1524
- * @param {?} h
1525
- * @param {?} obj
1526
- * @return {?}
1527
- */
1528
- (h, obj) => Object.assign(h, { [obj[key]]: (h[obj[key]] || []).concat(obj) })), {});
1297
+ constructor(payload) {
1298
+ this.payload = payload;
1299
+ this.type = LOAD_ANNOTATION_SET;
1529
1300
  }
1301
+ }
1302
+ class LoadAnnotationSetSucess {
1530
1303
  /**
1531
- * @param {?} annotations
1532
- * @return {?}
1304
+ * @param {?} payload
1533
1305
  */
1534
- static generateCommentsEntities(annotations) {
1535
- return annotations.reduce((/**
1536
- * @param {?} commentEntities
1537
- * @param {?} annotation
1538
- * @return {?}
1539
- */
1540
- (commentEntities, annotation) => {
1541
- if (annotation.comments.length) {
1542
- /** @type {?} */
1543
- const comment = Object.assign({}, annotation.comments[0] || '', { tags: [...annotation.tags || []] });
1544
- return Object.assign({}, commentEntities, { [annotation.id]: comment });
1545
- }
1546
- return Object.assign({}, commentEntities);
1547
- }), {});
1306
+ constructor(payload) {
1307
+ this.payload = payload;
1308
+ this.type = LOAD_ANNOTATION_SET_SUCCESS;
1548
1309
  }
1310
+ }
1311
+ class LoadAnnotationSetFail {
1549
1312
  /**
1550
- * @param {?} annotations
1551
- * @return {?}
1313
+ * @param {?} payload
1552
1314
  */
1553
- static genTagNameEntities(annotations) {
1554
- /** @type {?} */
1555
- const filterAnnoWithoutCommentsTags = annotations.filter((/**
1556
- * @param {?} a
1557
- * @return {?}
1558
- */
1559
- a => (a.comments.length && a.tags.length)));
1560
- /** @type {?} */
1561
- const allTags = filterAnnoWithoutCommentsTags.map((/**
1562
- * @param {?} anno
1563
- * @return {?}
1564
- */
1565
- anno => this.groupByKeyEntities(anno.tags, 'name')));
1566
- /** @type {?} */
1567
- const groupedByName = allTags.reduce((/**
1568
- * @param {?} tagEntitiy
1569
- * @param {?} tagItem
1570
- * @return {?}
1571
- */
1572
- (tagEntitiy, tagItem) => {
1573
- return Object.assign({}, tagEntitiy, tagItem);
1574
- }), {});
1575
- return this.genNameEnt(annotations, groupedByName);
1315
+ constructor(payload) {
1316
+ this.payload = payload;
1317
+ this.type = LOAD_ANNOTATION_SET_FAIL;
1576
1318
  }
1319
+ }
1320
+ class SaveAnnotation {
1577
1321
  /**
1578
- * @param {?} annos
1579
- * @param {?} groupedByName
1580
- * @return {?}
1322
+ * @param {?} payload
1323
+ */
1324
+ constructor(payload) {
1325
+ this.payload = payload;
1326
+ this.type = SAVE_ANNOTATION;
1327
+ }
1328
+ }
1329
+ class SaveAnnotationSuccess {
1330
+ /**
1331
+ * @param {?} payload
1332
+ */
1333
+ constructor(payload) {
1334
+ this.payload = payload;
1335
+ this.type = SAVE_ANNOTATION_SUCCESS;
1336
+ }
1337
+ }
1338
+ class SaveAnnotationFail {
1339
+ /**
1340
+ * @param {?} payload
1341
+ */
1342
+ constructor(payload) {
1343
+ this.payload = payload;
1344
+ this.type = SAVE_ANNOTATION_FAIL;
1345
+ }
1346
+ }
1347
+ class AddOrEditComment {
1348
+ /**
1349
+ * @param {?} payload
1350
+ */
1351
+ constructor(payload) {
1352
+ this.payload = payload;
1353
+ this.type = ADD_OR_EDIT_COMMENT;
1354
+ }
1355
+ }
1356
+ class DeleteAnnotation {
1357
+ /**
1358
+ * @param {?} payload
1359
+ */
1360
+ constructor(payload) {
1361
+ this.payload = payload;
1362
+ this.type = DELETE_ANNOTATION;
1363
+ }
1364
+ }
1365
+ class DeleteAnnotationSuccess {
1366
+ /**
1367
+ * @param {?} payload
1368
+ */
1369
+ constructor(payload) {
1370
+ this.payload = payload;
1371
+ this.type = DELETE_ANNOTATION_SUCCESS;
1372
+ }
1373
+ }
1374
+ class DeleteAnnotationFail {
1375
+ /**
1376
+ * @param {?} payload
1377
+ */
1378
+ constructor(payload) {
1379
+ this.payload = payload;
1380
+ this.type = DELETE_ANNOTATION_FAIL;
1381
+ }
1382
+ }
1383
+ class SelectedAnnotation {
1384
+ /**
1385
+ * @param {?} payload
1386
+ */
1387
+ constructor(payload) {
1388
+ this.payload = payload;
1389
+ this.type = SELECT_ANNOTATION;
1390
+ }
1391
+ }
1392
+ class SearchComment {
1393
+ /**
1394
+ * @param {?} payload
1395
+ */
1396
+ constructor(payload) {
1397
+ this.payload = payload;
1398
+ this.type = SEARCH_COMMENT;
1399
+ }
1400
+ }
1401
+ class ApplyCommentSymmaryFilter {
1402
+ /**
1403
+ * @param {?} payload
1404
+ */
1405
+ constructor(payload) {
1406
+ this.payload = payload;
1407
+ this.type = APPLY_COMMENT_SUMMARY_FILTER;
1408
+ }
1409
+ }
1410
+ class ClearCommentSummaryFilters {
1411
+ constructor() {
1412
+ this.type = CLEAR_COMMENT_SUMMARY_FILTER;
1413
+ }
1414
+ }
1415
+
1416
+ /**
1417
+ * @fileoverview added by tsickle
1418
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1419
+ */
1420
+ /*
1421
+ @dynamic
1422
+ marking class as dynamic to stop compiler throwing error for lambda in static function
1423
+ see https://github.com/angular/angular/issues/19698#issuecomment-338340211
1424
+ */
1425
+ class StoreUtils {
1426
+ /**
1427
+ * @param {?} annotations
1428
+ * @param {?} key
1429
+ * @return {?}
1430
+ */
1431
+ static groupByKeyEntities(annotations, key) {
1432
+ return annotations.reduce((/**
1433
+ * @param {?} h
1434
+ * @param {?} obj
1435
+ * @return {?}
1436
+ */
1437
+ (h, obj) => Object.assign(h, { [obj[key]]: (h[obj[key]] || []).concat(obj) })), {});
1438
+ }
1439
+ /**
1440
+ * @param {?} annotations
1441
+ * @return {?}
1442
+ */
1443
+ static generateCommentsEntities(annotations) {
1444
+ return annotations.reduce((/**
1445
+ * @param {?} commentEntities
1446
+ * @param {?} annotation
1447
+ * @return {?}
1448
+ */
1449
+ (commentEntities, annotation) => {
1450
+ if (annotation.comments.length) {
1451
+ /** @type {?} */
1452
+ const comment = Object.assign({}, annotation.comments[0] || '', { tags: [...annotation.tags || []] });
1453
+ return Object.assign({}, commentEntities, { [annotation.id]: comment });
1454
+ }
1455
+ return Object.assign({}, commentEntities);
1456
+ }), {});
1457
+ }
1458
+ /**
1459
+ * @param {?} annotations
1460
+ * @return {?}
1461
+ */
1462
+ static genTagNameEntities(annotations) {
1463
+ /** @type {?} */
1464
+ const filterAnnoWithoutCommentsTags = annotations.filter((/**
1465
+ * @param {?} a
1466
+ * @return {?}
1467
+ */
1468
+ a => (a.comments.length && a.tags.length)));
1469
+ /** @type {?} */
1470
+ const allTags = filterAnnoWithoutCommentsTags.map((/**
1471
+ * @param {?} anno
1472
+ * @return {?}
1473
+ */
1474
+ anno => this.groupByKeyEntities(anno.tags, 'name')));
1475
+ /** @type {?} */
1476
+ const groupedByName = allTags.reduce((/**
1477
+ * @param {?} tagEntitiy
1478
+ * @param {?} tagItem
1479
+ * @return {?}
1480
+ */
1481
+ (tagEntitiy, tagItem) => {
1482
+ return Object.assign({}, tagEntitiy, tagItem);
1483
+ }), {});
1484
+ return this.genNameEnt(annotations, groupedByName);
1485
+ }
1486
+ /**
1487
+ * @param {?} annos
1488
+ * @param {?} groupedByName
1489
+ * @return {?}
1581
1490
  */
1582
1491
  static genNameEnt(annos, groupedByName) {
1583
1492
  return Object.keys(groupedByName).reduce((/**
@@ -1941,29 +1850,6 @@ const getSummaryFilters = (/**
1941
1850
  */
1942
1851
  (state) => state.commentSummaryFilters);
1943
1852
 
1944
- /**
1945
- * @fileoverview added by tsickle
1946
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
1947
- */
1948
- /** @type {?} */
1949
- const ADD_FILTER_TAGS = '[Tags] Add Filter Tags';
1950
- /** @type {?} */
1951
- const CLEAR_FILTER_TAGS = '[Tags] Clear Filter Tags';
1952
- class AddFilterTags {
1953
- /**
1954
- * @param {?} payload
1955
- */
1956
- constructor(payload) {
1957
- this.payload = payload;
1958
- this.type = ADD_FILTER_TAGS;
1959
- }
1960
- }
1961
- class ClearFilterTags {
1962
- constructor() {
1963
- this.type = CLEAR_FILTER_TAGS;
1964
- }
1965
- }
1966
-
1967
1853
  /**
1968
1854
  * @fileoverview added by tsickle
1969
1855
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
@@ -2798,157 +2684,68 @@ const getRedactedDocInfo = (/**
2798
2684
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2799
2685
  */
2800
2686
  /** @type {?} */
2801
- const SET_CASE_ID = '[Icp] Set Case Id';
2802
- /** @type {?} */
2803
- const LOAD_ICP_SESSION = '[Icp] Load Session';
2687
+ const initialIcpSessionState = {
2688
+ session: null,
2689
+ presenter: null,
2690
+ client: null,
2691
+ participants: []
2692
+ };
2693
+ /**
2694
+ * @param {?=} state
2695
+ * @param {?=} action
2696
+ * @return {?}
2697
+ */
2698
+ function icpReducer(state = initialIcpSessionState, action) {
2699
+ switch (action.type) {
2700
+ case SET_CASE_ID: {
2701
+ /** @type {?} */
2702
+ const caseId = action.payload;
2703
+ /** @type {?} */
2704
+ const session = Object.assign({}, state.session, { caseId });
2705
+ return Object.assign({}, state, { session });
2706
+ }
2707
+ case ICP_SOCKET_SESSION_JOINED: {
2708
+ /** @type {?} */
2709
+ const session = action.payload.session;
2710
+ /** @type {?} */
2711
+ const participantInfo = action.payload.participantInfo;
2712
+ return Object.assign({}, state, { session, client: participantInfo.client, presenter: participantInfo.presenter });
2713
+ }
2714
+ case ICP_PARTICIPANT_LIST_UPDATED: {
2715
+ /** @type {?} */
2716
+ const updatedParticipants = action.payload;
2717
+ /** @type {?} */
2718
+ const participants = Object.keys(updatedParticipants)
2719
+ .map((/**
2720
+ * @param {?} id
2721
+ * @return {?}
2722
+ */
2723
+ id => ({ id: id, username: updatedParticipants[id] })));
2724
+ return Object.assign({}, state, { participants });
2725
+ }
2726
+ case ICP_PRESENTER_UPDATED: {
2727
+ /** @type {?} */
2728
+ const presenter = action.payload;
2729
+ return Object.assign({}, state, { presenter });
2730
+ }
2731
+ case LEAVE_ICP_SOCKET_SESSION: {
2732
+ return Object.assign({}, state, initialIcpSessionState);
2733
+ }
2734
+ }
2735
+ return state;
2736
+ }
2804
2737
  /** @type {?} */
2805
- const LOAD_ICP_SESSION_FAIL = '[Icp] Load Session Failure';
2738
+ const getIcpSession = (/**
2739
+ * @param {?} state
2740
+ * @return {?}
2741
+ */
2742
+ (state) => state.session);
2806
2743
  /** @type {?} */
2807
- const JOIN_ICP_SOCKET_SESSION = '[Icp] Join Socket Session';
2808
- /** @type {?} */
2809
- const ICP_SOCKET_SESSION_JOINED = '[Icp] Socket Session Joined';
2810
- /** @type {?} */
2811
- const LEAVE_ICP_SOCKET_SESSION = '[Icp] Leave Socket Session';
2812
- /** @type {?} */
2813
- const ICP_PRESENTER_UPDATED = '[Icp] Presenter Updated';
2814
- /** @type {?} */
2815
- const ICP_PARTICIPANT_LIST_UPDATED = '[Icp] Participant List Updated';
2816
- class SetCaseId {
2817
- /**
2818
- * @param {?} payload
2819
- */
2820
- constructor(payload) {
2821
- this.payload = payload;
2822
- this.type = SET_CASE_ID;
2823
- }
2824
- }
2825
- class LoadIcpSession {
2826
- /**
2827
- * @param {?} payload
2828
- */
2829
- constructor(payload) {
2830
- this.payload = payload;
2831
- this.type = LOAD_ICP_SESSION;
2832
- }
2833
- }
2834
- class LoadIcpSessionFailure {
2835
- /**
2836
- * @param {?} payload
2837
- */
2838
- constructor(payload) {
2839
- this.payload = payload;
2840
- this.type = LOAD_ICP_SESSION_FAIL;
2841
- }
2842
- }
2843
- class JoinIcpSocketSession {
2844
- /**
2845
- * @param {?} payload
2846
- */
2847
- constructor(payload) {
2848
- this.payload = payload;
2849
- this.type = JOIN_ICP_SOCKET_SESSION;
2850
- }
2851
- }
2852
- class IcpSocketSessionJoined {
2853
- /**
2854
- * @param {?} payload
2855
- */
2856
- constructor(payload) {
2857
- this.payload = payload;
2858
- this.type = ICP_SOCKET_SESSION_JOINED;
2859
- }
2860
- }
2861
- class LeaveIcpSocketSession {
2862
- constructor() {
2863
- this.type = LEAVE_ICP_SOCKET_SESSION;
2864
- }
2865
- }
2866
- class IcpPresenterUpdated {
2867
- /**
2868
- * @param {?} payload
2869
- */
2870
- constructor(payload) {
2871
- this.payload = payload;
2872
- this.type = ICP_PRESENTER_UPDATED;
2873
- }
2874
- }
2875
- class IcpParticipantListUpdated {
2876
- /**
2877
- * @param {?} payload
2878
- */
2879
- constructor(payload) {
2880
- this.payload = payload;
2881
- this.type = ICP_PARTICIPANT_LIST_UPDATED;
2882
- }
2883
- }
2884
-
2885
- /**
2886
- * @fileoverview added by tsickle
2887
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2888
- */
2889
- /** @type {?} */
2890
- const initialIcpSessionState = {
2891
- session: null,
2892
- presenter: null,
2893
- client: null,
2894
- participants: []
2895
- };
2896
- /**
2897
- * @param {?=} state
2898
- * @param {?=} action
2899
- * @return {?}
2900
- */
2901
- function icpReducer(state = initialIcpSessionState, action) {
2902
- switch (action.type) {
2903
- case SET_CASE_ID: {
2904
- /** @type {?} */
2905
- const caseId = action.payload;
2906
- /** @type {?} */
2907
- const session = Object.assign({}, state.session, { caseId });
2908
- return Object.assign({}, state, { session });
2909
- }
2910
- case ICP_SOCKET_SESSION_JOINED: {
2911
- /** @type {?} */
2912
- const session = action.payload.session;
2913
- /** @type {?} */
2914
- const participantInfo = action.payload.participantInfo;
2915
- return Object.assign({}, state, { session, client: participantInfo.client, presenter: participantInfo.presenter });
2916
- }
2917
- case ICP_PARTICIPANT_LIST_UPDATED: {
2918
- /** @type {?} */
2919
- const updatedParticipants = action.payload;
2920
- /** @type {?} */
2921
- const participants = Object.keys(updatedParticipants)
2922
- .map((/**
2923
- * @param {?} id
2924
- * @return {?}
2925
- */
2926
- id => ({ id: id, username: updatedParticipants[id] })));
2927
- return Object.assign({}, state, { participants });
2928
- }
2929
- case ICP_PRESENTER_UPDATED: {
2930
- /** @type {?} */
2931
- const presenter = action.payload;
2932
- return Object.assign({}, state, { presenter });
2933
- }
2934
- case LEAVE_ICP_SOCKET_SESSION: {
2935
- return Object.assign({}, state, initialIcpSessionState);
2936
- }
2937
- }
2938
- return state;
2939
- }
2940
- /** @type {?} */
2941
- const getIcpSession = (/**
2942
- * @param {?} state
2943
- * @return {?}
2944
- */
2945
- (state) => state.session);
2946
- /** @type {?} */
2947
- const getPresenter = (/**
2948
- * @param {?} state
2949
- * @return {?}
2950
- */
2951
- (state) => state.presenter);
2744
+ const getPresenter = (/**
2745
+ * @param {?} state
2746
+ * @return {?}
2747
+ */
2748
+ (state) => state.presenter);
2952
2749
  /** @type {?} */
2953
2750
  const getClient = (/**
2954
2751
  * @param {?} state
@@ -2978,40 +2775,6 @@ const reducers = {
2978
2775
  /** @type {?} */
2979
2776
  const getMVState = createFeatureSelector('media-viewer');
2980
2777
 
2981
- /**
2982
- * @fileoverview added by tsickle
2983
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2984
- */
2985
- /** @type {?} */
2986
- const getTagsRootState = createSelector(getMVState, (/**
2987
- * @param {?} state
2988
- * @return {?}
2989
- */
2990
- (state) => state.tags));
2991
- /** @type {?} */
2992
- const getTagEntities = createSelector(getTagsRootState, getTagNameEnt);
2993
- /** @type {?} */
2994
- const getTagFilters = createSelector(getTagsRootState, getFilters);
2995
- /** @type {?} */
2996
- const getTagFiltered = createSelector(getTagsRootState, getFilteredComments);
2997
- /** @type {?} */
2998
- const getFilteredPageEntities = createSelector(getTagsRootState, getFilteredPageEnt);
2999
- /** @type {?} */
3000
- const getAllTagsArr = createSelector(getTagEntities, (/**
3001
- * @param {?} tagEnt
3002
- * @return {?}
3003
- */
3004
- (tagEnt) => Object.keys(tagEnt).map((/**
3005
- * @param {?} key
3006
- * @return {?}
3007
- */
3008
- key => {
3009
- return {
3010
- key,
3011
- length: Object.keys(tagEnt[key]).length
3012
- };
3013
- }))));
3014
-
3015
2778
  /**
3016
2779
  * @fileoverview added by tsickle
3017
2780
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
@@ -3047,378 +2810,51 @@ const rotationLoaded$1 = createSelector(getDocumentState, rotationLoaded);
3047
2810
  * @fileoverview added by tsickle
3048
2811
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3049
2812
  */
3050
- /** @type {?} */
3051
- const getAnnotationsSetState = createSelector(getMVState, (/**
3052
- * @param {?} state
3053
- * @return {?}
3054
- */
3055
- (state) => state.annotations));
3056
- /** @type {?} */
3057
- const getAnnotationEntities = createSelector(getAnnotationsSetState, getAnnoEnt);
3058
- /** @type {?} */
3059
- const getSet = createSelector(getAnnotationsSetState, getAnnoSet);
3060
- /** @type {?} */
3061
- const getDocumentIdSetId = createSelector(getSet, (/**
3062
- * @param {?} annoSet
3063
- * @return {?}
3064
- */
3065
- (annoSet) => {
3066
- return {
3067
- documentId: annoSet.documentId,
3068
- annotationSetId: annoSet.id
3069
- };
3070
- }));
3071
- /** @type {?} */
3072
- const getAnnotationSet = createSelector(getAnnotationEntities, getSet, (/**
3073
- * @param {?} entities
3074
- * @param {?} set
3075
- * @return {?}
3076
- */
3077
- (entities, set) => {
3078
- return Object.assign({}, set, { annotations: Object.keys(entities).map((/**
3079
- * @param {?} key
3080
- * @return {?}
3081
- */
3082
- key => entities[key])) });
3083
- }));
3084
- /** @type {?} */
3085
- const getSelectedAnnotation = createSelector(getAnnotationsSetState, getSelectedAnno);
3086
- /** @type {?} */
3087
- const getCommentEntities = createSelector(getAnnotationsSetState, getCommentEnts);
3088
- /** @type {?} */
3089
- const getPageEntities = createSelector(getAnnotationsSetState, getAnnoPageEnt);
3090
- /** @type {?} */
3091
- const getComponentSearchQueries = createSelector(getAnnotationsSetState, commentSearchQ);
3092
- /** @type {?} */
3093
- const getComponentSearchText = createSelector(getComponentSearchQueries, (/**
3094
- * @param {?} queries
3095
- * @return {?}
3096
- */
3097
- (queries) => queries.commentSearch));
3098
- /** @type {?} */
3099
- const getCommentSummaryFilters = createSelector(getAnnotationsSetState, getSummaryFilters);
3100
- /** @type {?} */
3101
- const getAnnoPerPage = createSelector(getPages, getPageEntities, getFilteredPageEntities, (/**
3102
- * @param {?} pages
3103
- * @param {?} pageEnt
3104
- * @param {?} filteredPageEnt
3105
- * @return {?}
3106
- */
3107
- (pages, pageEnt, filteredPageEnt) => {
3108
- /** @type {?} */
3109
- const isFiltered = !!Object.keys(filteredPageEnt).length;
3110
- /** @type {?} */
3111
- const entities = isFiltered ? filteredPageEnt : pageEnt;
3112
- if (pages) {
3113
- /** @type {?} */
3114
- const arr = [];
3115
- Object.keys(pages).forEach((/**
3116
- * @param {?} key
3117
- * @return {?}
3118
- */
3119
- key => {
3120
- arr.push({
3121
- anno: entities[key] ? entities[key] : [],
3122
- styles: pages[key].styles
3123
- });
3124
- }));
3125
- return arr;
3126
- }
3127
- }));
3128
- /** @type {?} */
3129
- const getCommentsArray = createSelector(getCommentEntities, getPages, getAnnotationEntities, getTagFiltered, (/**
3130
- * @param {?} commentEnts
3131
- * @param {?} pages
3132
- * @param {?} annoEnts
3133
- * @param {?} filtered
3134
- * @return {?}
3135
- */
3136
- (commentEnts, pages, annoEnts, filtered) => {
3137
- if (commentEnts && annoEnts && pages[1]) {
3138
- /** @type {?} */
3139
- const isFiltered = !!Object.keys(filtered).length;
3140
- /** @type {?} */
3141
- const com = isFiltered ? filtered : commentEnts;
3142
- return Object.keys(com).map((/**
3143
- * @param {?} key
3144
- * @return {?}
3145
- */
3146
- key => {
3147
- /** @type {?} */
3148
- const page = annoEnts[key].page;
3149
- return Object.assign({}, commentEnts[key], { page,
3150
- pages });
3151
- }));
3152
- }
3153
- }));
3154
- /** @type {?} */
3155
- const getCommentSummary = createSelector(getCommentsArray, getCommentSummaryFilters, (/**
3156
- * @param {?=} commentSummary
3157
- * @param {?=} filters
3158
- * @return {?}
3159
- */
3160
- (commentSummary = [], filters) => {
3161
- /** @type {?} */
3162
- const comments = StoreUtils.filterCommentsSummary(commentSummary, filters.filters);
3163
- if (comments.length) {
3164
- return comments.map((/**
3165
- * @param {?} comment
3166
- * @return {?}
3167
- */
3168
- (comment) => {
3169
- return {
3170
- page: comment.page,
3171
- user: comment.createdByDetails.forename.concat(' ').concat(comment.createdByDetails.surname),
3172
- date: moment(comment.lastModifiedDate).format('D MMMM YYYY'),
3173
- tags: comment.tags,
3174
- comment: comment.content
3175
- };
3176
- }));
3177
- }
3178
- return [''];
3179
- }));
3180
- /** @type {?} */
3181
- const getFilteredAnnotations = createSelector(getAnnotationEntities, getTagFiltered, (/**
3182
- * @param {?} annoEnt
3183
- * @param {?} filters
3184
- * @return {?}
3185
- */
3186
- (annoEnt, filters) => {
3187
- /** @type {?} */
3188
- const isFiltered = !!Object.keys(filters).length;
3189
- /** @type {?} */
3190
- const anno = isFiltered ? filters : annoEnt;
3191
- return Object.keys(anno).map((/**
3192
- * @param {?} key
3193
- * @return {?}
3194
- */
3195
- key => annoEnt[key]))
3196
- .filter((/**
3197
- * @param {?} annotation
3198
- * @return {?}
3199
- */
3200
- annotation => annotation.comments && annotation.comments.length > 0));
3201
- }));
3202
-
3203
- /**
3204
- * @fileoverview added by tsickle
3205
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3206
- */
3207
- class CommentSetComponent {
3208
- /**
3209
- * @param {?} store
3210
- * @param {?} commentService
3211
- * @param {?} renderService
3212
- * @param {?} toolbarEvents
3213
- */
3214
- constructor(store, commentService, renderService, toolbarEvents) {
3215
- this.store = store;
3216
- this.commentService = commentService;
3217
- this.renderService = renderService;
3218
- this.toolbarEvents = toolbarEvents;
3219
- this.pageHeights = [];
3220
- this.subscriptions = [];
3221
- this.clearSelection();
3222
- }
3223
- /**
3224
- * @return {?}
3225
- */
3226
- ngOnInit() {
3227
- this.comments$ = this.store.pipe(select(getCommentsArray));
3228
- this.annoEntities$ = this.store.pipe(select(getAnnotationEntities));
3229
- this.subscriptions.push(this.toolbarEvents.commentsPanelVisible.subscribe((/**
3230
- * @param {?} toggle
3231
- * @return {?}
3232
- */
3233
- toggle => {
3234
- this.redrawComments();
3235
- this.showCommentsPanel = toggle;
3236
- })));
3237
- }
3238
- /**
3239
- * @param {?} changes
3240
- * @return {?}
3241
- */
3242
- ngOnChanges(changes) {
3243
- if (changes.annotationSet) {
3244
- this.commentService.setCommentSet(this);
3245
- }
3246
- }
3247
- /**
3248
- * @return {?}
3249
- */
3250
- ngOnDestroy() {
3251
- if (this.subscriptions.length > 0) {
3252
- this.subscriptions.forEach((/**
3253
- * @param {?} subscription
3254
- * @return {?}
3255
- */
3256
- subscription => subscription.unsubscribe()));
3257
- }
3258
- }
3259
- /**
3260
- * @param {?} annotationId
3261
- * @return {?}
3262
- */
3263
- onSelect(annotationId) {
3264
- this.store.dispatch(new SelectedAnnotation(annotationId));
3265
- }
3266
- /**
3267
- * @param {?} comment
3268
- * @return {?}
3269
- */
3270
- onCommentDelete(comment) {
3271
- /** @type {?} */
3272
- const annotation = this.annotationSet.annotations.find((/**
3273
- * @param {?} anno
3274
- * @return {?}
3275
- */
3276
- anno => anno.id === comment.annotationId));
3277
- /** @type {?} */
3278
- const comments = [];
3279
- /** @type {?} */
3280
- const annot = Object.assign({}, annotation, { comments });
3281
- this.onAnnotationUpdate(annot);
3282
- this.redrawComments();
3283
- }
3284
- /**
3285
- * @return {?}
3286
- */
3287
- redrawComments() {
3288
- setTimeout((/**
3289
- * @return {?}
3290
- */
3291
- () => {
3292
- /** @type {?} */
3293
- const componentList = this.commentComponents.map((/**
3294
- * @param {?} comment
3295
- * @return {?}
3296
- */
3297
- comment => comment));
3298
- this.renderService.redrawComponents(componentList, this.pageHeights, this.rotate, this.zoom);
3299
- }), 0);
3300
- }
3301
- /**
3302
- * @param {?} payload
3303
- * @return {?}
3304
- */
3305
- onCommentUpdate(payload) {
3306
- /** @type {?} */
3307
- const annotation = this.annotationSet.annotations.find((/**
3308
- * @param {?} anno
3309
- * @return {?}
3310
- */
3311
- anno => anno.id === payload.comment.annotationId));
3312
- /** @type {?} */
3313
- const comments = [payload.comment];
3314
- /** @type {?} */
3315
- const tags = payload.tags;
3316
- /** @type {?} */
3317
- const annot = Object.assign({}, annotation, { comments,
3318
- tags });
3319
- this.onAnnotationUpdate(annot);
3320
- }
3321
- /**
3322
- * @param {?} annotation
3323
- * @return {?}
3324
- */
3325
- onAnnotationUpdate(annotation) {
3326
- this.store.dispatch(new SaveAnnotation(annotation));
3327
- }
3328
- /**
3329
- * @param {?} e
3330
- * @return {?}
3331
- */
3332
- onContainerClick(e) {
3333
- if (e.path && e.path[0] === this.container.nativeElement) {
3334
- this.clearSelection();
3335
- }
3336
- }
3337
- /**
3338
- * @return {?}
3339
- */
3340
- clearSelection() {
3341
- this.store.dispatch(new SelectedAnnotation({ annotationId: '', editable: false, selected: false }));
3342
- }
3343
- /**
3344
- * @return {?}
3345
- */
3346
- allCommentsSaved() {
3347
- this.commentService.allCommentsSaved();
3348
- }
3349
- }
3350
- CommentSetComponent.decorators = [
3351
- { type: Component, args: [{
3352
- selector: 'mv-comment-set',
3353
- template: "<div #container\n [ngClass]=\"{ 'comments-panel comment-container': true, 'expanded': showCommentsPanel }\"\n [style.height.px]=\"height\"\n (click)=\"onContainerClick($event)\">\n <ng-container *ngFor=\"let comment of (comments$ | async); let i = index;\">\n <mv-anno-comment\n [ngStyle]=\"showCommentsPanel ? {} : {'display':'none'}\"\n #commentComponent\n (commentClick)=\"onSelect($event)\"\n (delete)=\"onCommentDelete($event)\"\n (updated)=\"onCommentUpdate($event)\"\n (changes)=\"allCommentsSaved()\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [index]=\"i\"\n [page]=\"comment.page\"\n [comment]=\"comment\"\n [annotation]=\"(annoEntities$ | async)[comment.annotationId]\"\n (renderComments)=\"redrawComments()\">\n </mv-anno-comment>\n </ng-container>\n</div>\n"
3354
- }] }
3355
- ];
3356
- /** @nocollapse */
3357
- CommentSetComponent.ctorParameters = () => [
3358
- { type: Store },
3359
- { type: CommentService },
3360
- { type: CommentSetRenderService },
3361
- { type: ToolbarEventService }
3362
- ];
3363
- CommentSetComponent.propDecorators = {
3364
- annotationSet: [{ type: Input }],
3365
- zoom: [{ type: Input }],
3366
- rotate: [{ type: Input }],
3367
- height: [{ type: Input }],
3368
- pageHeights: [{ type: Input }],
3369
- container: [{ type: ViewChild, args: ['container',] }],
3370
- commentComponents: [{ type: ViewChildren, args: ['commentComponent',] }]
3371
- };
3372
-
3373
- /**
3374
- * @fileoverview added by tsickle
3375
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3376
- */
3377
- class ViewerEventService {
3378
- constructor() {
3379
- this.textHighlight = new Subject();
3380
- this.boxHighlight = new Subject();
3381
- this.ctxToolbarCleared = new Subject();
3382
- this.navigationEvent = new Subject();
3383
- }
3384
- /**
3385
- * @param {?} selectionData
3386
- * @return {?}
3387
- */
3388
- textSelected(selectionData) {
3389
- this.textHighlight.next(selectionData);
3390
- }
3391
- /**
3392
- * @param {?} selectionData
3393
- * @return {?}
3394
- */
3395
- boxSelected(selectionData) {
3396
- this.boxHighlight.next(selectionData);
3397
- }
3398
- /**
3399
- * @return {?}
3400
- */
3401
- clearCtxToolbar() {
3402
- this.ctxToolbarCleared.next();
3403
- }
3404
- /**
3405
- * @param {?} destination
3406
- * @return {?}
3407
- */
3408
- goToDestination(destination) {
3409
- this.navigationEvent.next(destination);
3410
- }
3411
- }
3412
- ViewerEventService.decorators = [
3413
- { type: Injectable, args: [{ providedIn: 'root' },] }
3414
- ];
3415
- /** @nocollapse */
3416
- ViewerEventService.ctorParameters = () => [];
3417
- /** @nocollapse */ ViewerEventService.ngInjectableDef = defineInjectable({ factory: function ViewerEventService_Factory() { return new ViewerEventService(); }, token: ViewerEventService, providedIn: "root" });
3418
-
3419
- /**
3420
- * @fileoverview added by tsickle
3421
- * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
2813
+ class ViewerEventService {
2814
+ constructor() {
2815
+ this.textHighlight = new Subject();
2816
+ this.boxHighlight = new Subject();
2817
+ this.ctxToolbarCleared = new Subject();
2818
+ this.navigationEvent = new Subject();
2819
+ }
2820
+ /**
2821
+ * @param {?} selectionData
2822
+ * @return {?}
2823
+ */
2824
+ textSelected(selectionData) {
2825
+ this.textHighlight.next(selectionData);
2826
+ }
2827
+ /**
2828
+ * @param {?} selectionData
2829
+ * @return {?}
2830
+ */
2831
+ boxSelected(selectionData) {
2832
+ this.boxHighlight.next(selectionData);
2833
+ }
2834
+ /**
2835
+ * @return {?}
2836
+ */
2837
+ clearCtxToolbar() {
2838
+ this.ctxToolbarCleared.next();
2839
+ }
2840
+ /**
2841
+ * @param {?} destination
2842
+ * @return {?}
2843
+ */
2844
+ goToDestination(destination) {
2845
+ this.navigationEvent.next(destination);
2846
+ }
2847
+ }
2848
+ ViewerEventService.decorators = [
2849
+ { type: Injectable, args: [{ providedIn: 'root' },] }
2850
+ ];
2851
+ /** @nocollapse */
2852
+ ViewerEventService.ctorParameters = () => [];
2853
+ /** @nocollapse */ ViewerEventService.ngInjectableDef = defineInjectable({ factory: function ViewerEventService_Factory() { return new ViewerEventService(); }, token: ViewerEventService, providedIn: "root" });
2854
+
2855
+ /**
2856
+ * @fileoverview added by tsickle
2857
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3422
2858
  */
3423
2859
  class PdfViewerComponent {
3424
2860
  /**
@@ -3534,14 +2970,6 @@ class PdfViewerComponent {
3534
2970
  */
3535
2971
  toggle => {
3536
2972
  this.showCommentsPanel = toggle;
3537
- if (toggle) {
3538
- setTimeout((/**
3539
- * @return {?}
3540
- */
3541
- () => {
3542
- this.scrollTwo.nativeElement.scrollBy(0, this.viewerContainer.nativeElement.scrollTop);
3543
- }));
3544
- }
3545
2973
  })));
3546
2974
  this.$subscription.add(this.viewerEvents.navigationEvent.subscribe((/**
3547
2975
  * @param {?} dest
@@ -3686,9 +3114,6 @@ class PdfViewerComponent {
3686
3114
  rotateDocument(rotation) {
3687
3115
  /** @type {?} */
3688
3116
  const pageNumber = this.pdfWrapper.getPageNumber();
3689
- if (this.commentsPanel) {
3690
- this.commentsPanel.container.nativeElement.style.height = 0;
3691
- }
3692
3117
  this.pdfWrapper.rotate(rotation);
3693
3118
  this.pdfWrapper.setPageNumber(pageNumber);
3694
3119
  this.rotation = (this.rotation + rotation) % 360;
@@ -3766,7 +3191,7 @@ class PdfViewerComponent {
3766
3191
  PdfViewerComponent.decorators = [
3767
3192
  { type: Component, args: [{
3768
3193
  selector: 'mv-pdf-viewer',
3769
- template: "<mv-side-bar *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\">\n</mv-side-bar>\n\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{'show-comments-panel': showCommentsPanel}\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\">\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ 'pdfContainer': true, hidden: errorMessage }\">\n\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n (scroll)=\"scrollTwo.scrollTop = viewerContainer.scrollTop\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"(showCommentsPanel || showIcpParticipantsList) && !(toolbarEvents.redactionMode | async)\"\n [class.grabNDrag]=\"enableGrabNDrag\">\n\n <div #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n [ngClass]=\"{ hidden: loadingDocument, highlightMode: highlightMode | async, drawMode: drawMode | async }\">\n </div>\n\n <mv-redactions *ngIf=\"(toolbarEvents.redactionMode | async); else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-metadata-layer>\n\n <mv-bookmark-icons [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-bookmark-icons>\n </ng-template>\n </div>\n\n <div #scrollTwo [ngClass]=\"{'comments': showCommentsPanel}\">\n <mv-comment-set #commentsPanel\n *ngIf=\"enableAnnotations && annotationSet && !(toolbarEvents.redactionMode | async)\"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\">\n </mv-comment-set>\n </div>\n\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">Loading...{{ loadingDocumentProgress ? loadingDocumentProgress + '%' : '' }}</h3>\n </div>\n</div>\n",
3194
+ template: "<mv-side-bar *ngIf=\"toolbarEvents.sidebarOpen\"\n id=\"sidebarContainer\"\n [url]=\"url\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [outline]=\"documentOutline\"\n [annotationsEnabled]=\"enableAnnotations\">\n</mv-side-bar>\n<mv-comment-set-header\n *ngIf=\"enableAnnotations\"\n [ngClass]=\"{'show-comments-panel': showCommentsPanel}\"\n [showCommentSummary]=\"toolbarButtons.showCommentSummary\"\n (showCommentSummaryDialog)=\"toggleCommentsSummary()\">\n</mv-comment-set-header>\n<mv-participants-list></mv-participants-list>\n<div\n class=\"pdfContainer\"\n [ngStyle]=\"{ height: height }\"\n [ngClass]=\"{ 'pdfContainer': true, hidden: errorMessage }\">\n <div\n #viewerContainer\n mvGrabNDrag\n [dragX]=\"viewerContainer\"\n [dragEnabled]=\"enableGrabNDrag\"\n id=\"viewerContainer\"\n class=\"viewer-container\"\n [class.annotations]=\"enableAnnotations\"\n [class.show-comments-panel]=\"(showCommentsPanel || showIcpParticipantsList) && !(toolbarEvents.redactionMode | async)\"\n [class.grabNDrag]=\"enableGrabNDrag\">\n <div #pdfViewer\n class=\"pdfViewer\"\n mvCreateTextHighlight\n [ngClass]=\"{ hidden: loadingDocument, highlightMode: highlightMode | async, drawMode: drawMode | async }\">\n </div>\n <mv-redactions *ngIf=\"(toolbarEvents.redactionMode | async); else annotationTemplate\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n ></mv-redactions>\n <ng-template #annotationTemplate>\n <mv-metadata-layer\n *ngIf=\"enableAnnotations && annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-metadata-layer>\n <mv-bookmark-icons [zoom]=\"zoom\"\n [rotate]=\"rotation\">\n </mv-bookmark-icons>\n </ng-template>\n </div>\n <mv-comment-set [contentScrollTop]=\"viewerContainer.scrollTop\"\n *ngIf=\"enableAnnotations && annotationSet && !(toolbarEvents.redactionMode | async)\"\n [annotationSet]=\"annotationSet\"\n [zoom]=\"zoom\"\n [rotate]=\"rotation\"\n [height]=\"pdfViewer.offsetHeight\"\n [pageHeights]=\"pageHeights\">\n </mv-comment-set>\n <div class=\"loadingMessage\" *ngIf=\"loadingDocument\">\n <h3 class=\"govuk-heading-m\">Loading...{{ loadingDocumentProgress ? loadingDocumentProgress + '%' : '' }}</h3>\n </div>\n</div>\n",
3770
3195
  encapsulation: ViewEncapsulation.None
3771
3196
  }] }
3772
3197
  ];
@@ -3795,8 +3220,6 @@ PdfViewerComponent.propDecorators = {
3795
3220
  caseId: [{ type: Input }],
3796
3221
  viewerContainer: [{ type: ViewChild, args: ['viewerContainer',] }],
3797
3222
  pdfViewer: [{ type: ViewChild, args: ['pdfViewer',] }],
3798
- commentsPanel: [{ type: ViewChild, args: ['commentsPanel',] }],
3799
- scrollTwo: [{ type: ViewChild, args: ['scrollTwo',] }],
3800
3223
  searchBarHidden: [{ type: Input }]
3801
3224
  };
3802
3225
 
@@ -4168,111 +3591,387 @@ class AnnotationApiService {
4168
3591
  * @param {?} documentId
4169
3592
  * @return {?}
4170
3593
  */
4171
- getAnnotationSet(documentId) {
4172
- // todo add model
3594
+ getAnnotationSet(documentId) {
3595
+ // todo add model
3596
+ /** @type {?} */
3597
+ const fixedUrl = `${this.annotationSetsFullUrl}/filter?documentId=${documentId}`;
3598
+ return this.httpClient
3599
+ .get(fixedUrl, { observe: 'response', withCredentials: true });
3600
+ }
3601
+ /**
3602
+ * @param {?} body
3603
+ * @return {?}
3604
+ */
3605
+ postAnnotationSet(body) {
3606
+ return this.httpClient
3607
+ .post(this.annotationSetsFullUrl, body, { observe: 'response', withCredentials: true })
3608
+ .pipe(map((/**
3609
+ * @param {?} response
3610
+ * @return {?}
3611
+ */
3612
+ response => response.body)), catchError((/**
3613
+ * @return {?}
3614
+ */
3615
+ () => [])));
3616
+ }
3617
+ /**
3618
+ * @param {?} annotationSet
3619
+ * @return {?}
3620
+ */
3621
+ getComments(annotationSet) {
3622
+ return annotationSet
3623
+ .pipe(map(this.sortAnnotations), map(this.extractComments));
3624
+ }
3625
+ /**
3626
+ * Sort the annotations in the response by page and then y position of their first rectangle
3627
+ * @private
3628
+ * @param {?} r
3629
+ * @return {?}
3630
+ */
3631
+ sortAnnotations(r) {
3632
+ return r.annotations.sort((/**
3633
+ * @param {?} a
3634
+ * @param {?} b
3635
+ * @return {?}
3636
+ */
3637
+ (a, b) => a.page !== b.page ? a.page - b.page : a.rectangles[0].y - b.rectangles[0].y));
3638
+ }
3639
+ /**
3640
+ * @private
3641
+ * @param {?} annotations
3642
+ * @return {?}
3643
+ */
3644
+ extractComments(annotations) {
3645
+ return [].concat(...annotations.map((/**
3646
+ * @param {?} a
3647
+ * @return {?}
3648
+ */
3649
+ a => a.comments)));
3650
+ }
3651
+ /**
3652
+ * @param {?} annotationId
3653
+ * @return {?}
3654
+ */
3655
+ deleteAnnotation(annotationId) {
3656
+ /** @type {?} */
3657
+ const url = `${this.annotationFullsUrl}/${annotationId}`;
3658
+ return this.httpClient
3659
+ .delete(url, { observe: 'response', withCredentials: true })
3660
+ .pipe(map((/**
3661
+ * @param {?} response
3662
+ * @return {?}
3663
+ */
3664
+ response => response.body)));
3665
+ }
3666
+ /**
3667
+ * @param {?} annotation
3668
+ * @return {?}
3669
+ */
3670
+ postAnnotation(annotation) {
3671
+ return this.httpClient
3672
+ .post(this.annotationFullsUrl, annotation, { observe: 'response', withCredentials: true })
3673
+ .pipe(map((/**
3674
+ * @param {?} response
3675
+ * @return {?}
3676
+ */
3677
+ response => response.body)));
3678
+ }
3679
+ /**
3680
+ * @return {?}
3681
+ */
3682
+ get annotationSetsFullUrl() {
3683
+ return this.annotationApiUrl + this.annotationSetBaseUrl;
3684
+ }
3685
+ /**
3686
+ * @return {?}
3687
+ */
3688
+ get annotationFullsUrl() {
3689
+ return this.annotationApiUrl + this.annotationBaseUrl;
3690
+ }
3691
+ }
3692
+ AnnotationApiService.decorators = [
3693
+ { type: Injectable }
3694
+ ];
3695
+ /** @nocollapse */
3696
+ AnnotationApiService.ctorParameters = () => [
3697
+ { type: HttpClient }
3698
+ ];
3699
+
3700
+ /**
3701
+ * @fileoverview added by tsickle
3702
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3703
+ */
3704
+ // TODO: replace by NgRx
3705
+ class CommentService {
3706
+ constructor() {
3707
+ this.unsavedChanges = new Subject();
3708
+ }
3709
+ /**
3710
+ * @param {?} commentSetComponent
3711
+ * @return {?}
3712
+ */
3713
+ setCommentSet(commentSetComponent) {
3714
+ this.commentSetComponent = commentSetComponent;
3715
+ }
3716
+ /**
3717
+ * @param {?} changes
3718
+ * @return {?}
3719
+ */
3720
+ onCommentChange(changes) {
3721
+ this.unsavedChanges.next(changes);
3722
+ }
3723
+ /**
3724
+ * @return {?}
3725
+ */
3726
+ getUnsavedChanges() {
3727
+ return this.unsavedChanges.asObservable();
3728
+ }
3729
+ /**
3730
+ * @param {?} annotation
3731
+ * @return {?}
3732
+ */
3733
+ hasUnsavedComments(annotation) {
3734
+ if (annotation.comments.length > 0) {
3735
+ /** @type {?} */
3736
+ const comment = this.getComment(annotation);
3737
+ return comment.hasUnsavedChanges;
3738
+ }
3739
+ return false;
3740
+ }
3741
+ /**
3742
+ * @param {?} annotation
3743
+ * @param {?} hasUnsavedChanges
3744
+ * @return {?}
3745
+ */
3746
+ updateUnsavedCommentsStatus(annotation, hasUnsavedChanges) {
4173
3747
  /** @type {?} */
4174
- const fixedUrl = `${this.annotationSetsFullUrl}/filter?documentId=${documentId}`;
4175
- return this.httpClient
4176
- .get(fixedUrl, { observe: 'response', withCredentials: true });
3748
+ const comment = this.getComment(annotation);
3749
+ comment.hasUnsavedChanges = hasUnsavedChanges;
3750
+ this.allCommentsSaved();
4177
3751
  }
4178
3752
  /**
4179
- * @param {?} body
3753
+ * @param {?} annotation
4180
3754
  * @return {?}
4181
3755
  */
4182
- postAnnotationSet(body) {
4183
- return this.httpClient
4184
- .post(this.annotationSetsFullUrl, body, { observe: 'response', withCredentials: true })
4185
- .pipe(map((/**
4186
- * @param {?} response
4187
- * @return {?}
4188
- */
4189
- response => response.body)), catchError((/**
3756
+ getComment(annotation) {
3757
+ return this.commentSetComponent.commentComponents
3758
+ .find((/**
3759
+ * @param {?} c
4190
3760
  * @return {?}
4191
3761
  */
4192
- () => [])));
3762
+ c => c.comment.annotationId === annotation.comments[0].annotationId));
4193
3763
  }
4194
3764
  /**
4195
- * @param {?} annotationSet
4196
3765
  * @return {?}
4197
3766
  */
4198
- getComments(annotationSet) {
4199
- return annotationSet
4200
- .pipe(map(this.sortAnnotations), map(this.extractComments));
3767
+ resetCommentSet() {
3768
+ this.commentSetComponent = null;
4201
3769
  }
4202
3770
  /**
4203
- * Sort the annotations in the response by page and then y position of their first rectangle
4204
- * @private
4205
- * @param {?} r
4206
3771
  * @return {?}
4207
3772
  */
4208
- sortAnnotations(r) {
4209
- return r.annotations.sort((/**
4210
- * @param {?} a
4211
- * @param {?} b
3773
+ allCommentsSaved() {
3774
+ this.onCommentChange(this.commentSetComponent.commentComponents.some((/**
3775
+ * @param {?} comment
4212
3776
  * @return {?}
4213
3777
  */
4214
- (a, b) => a.page !== b.page ? a.page - b.page : a.rectangles[0].y - b.rectangles[0].y));
3778
+ comment => comment.hasUnsavedChanges === true)));
4215
3779
  }
4216
- /**
4217
- * @private
4218
- * @param {?} annotations
4219
- * @return {?}
4220
- */
4221
- extractComments(annotations) {
4222
- return [].concat(...annotations.map((/**
4223
- * @param {?} a
3780
+ }
3781
+ CommentService.decorators = [
3782
+ { type: Injectable }
3783
+ ];
3784
+
3785
+ /**
3786
+ * @fileoverview added by tsickle
3787
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3788
+ */
3789
+ /** @type {?} */
3790
+ const getTagsRootState = createSelector(getMVState, (/**
3791
+ * @param {?} state
3792
+ * @return {?}
3793
+ */
3794
+ (state) => state.tags));
3795
+ /** @type {?} */
3796
+ const getTagEntities = createSelector(getTagsRootState, getTagNameEnt);
3797
+ /** @type {?} */
3798
+ const getTagFilters = createSelector(getTagsRootState, getFilters);
3799
+ /** @type {?} */
3800
+ const getTagFiltered = createSelector(getTagsRootState, getFilteredComments);
3801
+ /** @type {?} */
3802
+ const getFilteredPageEntities = createSelector(getTagsRootState, getFilteredPageEnt);
3803
+ /** @type {?} */
3804
+ const getAllTagsArr = createSelector(getTagEntities, (/**
3805
+ * @param {?} tagEnt
3806
+ * @return {?}
3807
+ */
3808
+ (tagEnt) => Object.keys(tagEnt).map((/**
3809
+ * @param {?} key
3810
+ * @return {?}
3811
+ */
3812
+ key => {
3813
+ return {
3814
+ key,
3815
+ length: Object.keys(tagEnt[key]).length
3816
+ };
3817
+ }))));
3818
+
3819
+ /**
3820
+ * @fileoverview added by tsickle
3821
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
3822
+ */
3823
+ /** @type {?} */
3824
+ const getAnnotationsSetState = createSelector(getMVState, (/**
3825
+ * @param {?} state
3826
+ * @return {?}
3827
+ */
3828
+ (state) => state.annotations));
3829
+ /** @type {?} */
3830
+ const getAnnotationEntities = createSelector(getAnnotationsSetState, getAnnoEnt);
3831
+ /** @type {?} */
3832
+ const getSet = createSelector(getAnnotationsSetState, getAnnoSet);
3833
+ /** @type {?} */
3834
+ const getDocumentIdSetId = createSelector(getSet, (/**
3835
+ * @param {?} annoSet
3836
+ * @return {?}
3837
+ */
3838
+ (annoSet) => {
3839
+ return {
3840
+ documentId: annoSet.documentId,
3841
+ annotationSetId: annoSet.id
3842
+ };
3843
+ }));
3844
+ /** @type {?} */
3845
+ const getAnnotationSet = createSelector(getAnnotationEntities, getSet, (/**
3846
+ * @param {?} entities
3847
+ * @param {?} set
3848
+ * @return {?}
3849
+ */
3850
+ (entities, set) => {
3851
+ return Object.assign({}, set, { annotations: Object.keys(entities).map((/**
3852
+ * @param {?} key
4224
3853
  * @return {?}
4225
3854
  */
4226
- a => a.comments)));
4227
- }
4228
- /**
4229
- * @param {?} annotationId
4230
- * @return {?}
4231
- */
4232
- deleteAnnotation(annotationId) {
3855
+ key => entities[key])) });
3856
+ }));
3857
+ /** @type {?} */
3858
+ const getSelectedAnnotation = createSelector(getAnnotationsSetState, getSelectedAnno);
3859
+ /** @type {?} */
3860
+ const getCommentEntities = createSelector(getAnnotationsSetState, getCommentEnts);
3861
+ /** @type {?} */
3862
+ const getPageEntities = createSelector(getAnnotationsSetState, getAnnoPageEnt);
3863
+ /** @type {?} */
3864
+ const getComponentSearchQueries = createSelector(getAnnotationsSetState, commentSearchQ);
3865
+ /** @type {?} */
3866
+ const getComponentSearchText = createSelector(getComponentSearchQueries, (/**
3867
+ * @param {?} queries
3868
+ * @return {?}
3869
+ */
3870
+ (queries) => queries.commentSearch));
3871
+ /** @type {?} */
3872
+ const getCommentSummaryFilters = createSelector(getAnnotationsSetState, getSummaryFilters);
3873
+ /** @type {?} */
3874
+ const getAnnoPerPage = createSelector(getPages, getPageEntities, getFilteredPageEntities, (/**
3875
+ * @param {?} pages
3876
+ * @param {?} pageEnt
3877
+ * @param {?} filteredPageEnt
3878
+ * @return {?}
3879
+ */
3880
+ (pages, pageEnt, filteredPageEnt) => {
3881
+ /** @type {?} */
3882
+ const isFiltered = !!Object.keys(filteredPageEnt).length;
3883
+ /** @type {?} */
3884
+ const entities = isFiltered ? filteredPageEnt : pageEnt;
3885
+ if (pages) {
4233
3886
  /** @type {?} */
4234
- const url = `${this.annotationFullsUrl}/${annotationId}`;
4235
- return this.httpClient
4236
- .delete(url, { observe: 'response', withCredentials: true })
4237
- .pipe(map((/**
4238
- * @param {?} response
3887
+ const arr = [];
3888
+ Object.keys(pages).forEach((/**
3889
+ * @param {?} key
4239
3890
  * @return {?}
4240
3891
  */
4241
- response => response.body)));
3892
+ key => {
3893
+ arr.push({
3894
+ anno: entities[key] ? entities[key] : [],
3895
+ styles: pages[key].styles
3896
+ });
3897
+ }));
3898
+ return arr;
4242
3899
  }
4243
- /**
4244
- * @param {?} annotation
4245
- * @return {?}
4246
- */
4247
- postAnnotation(annotation) {
4248
- return this.httpClient
4249
- .post(this.annotationFullsUrl, annotation, { observe: 'response', withCredentials: true })
4250
- .pipe(map((/**
4251
- * @param {?} response
3900
+ }));
3901
+ /** @type {?} */
3902
+ const getCommentsArray = createSelector(getCommentEntities, getPages, getAnnotationEntities, getTagFiltered, (/**
3903
+ * @param {?} commentEnts
3904
+ * @param {?} pages
3905
+ * @param {?} annoEnts
3906
+ * @param {?} filtered
3907
+ * @return {?}
3908
+ */
3909
+ (commentEnts, pages, annoEnts, filtered) => {
3910
+ if (commentEnts && annoEnts && pages[1]) {
3911
+ /** @type {?} */
3912
+ const isFiltered = !!Object.keys(filtered).length;
3913
+ /** @type {?} */
3914
+ const com = isFiltered ? filtered : commentEnts;
3915
+ return Object.keys(com).map((/**
3916
+ * @param {?} key
4252
3917
  * @return {?}
4253
3918
  */
4254
- response => response.body)));
3919
+ key => {
3920
+ /** @type {?} */
3921
+ const page = annoEnts[key].page;
3922
+ return Object.assign({}, commentEnts[key], { page,
3923
+ pages });
3924
+ }));
4255
3925
  }
4256
- /**
4257
- * @return {?}
4258
- */
4259
- get annotationSetsFullUrl() {
4260
- return this.annotationApiUrl + this.annotationSetBaseUrl;
3926
+ }));
3927
+ /** @type {?} */
3928
+ const getCommentSummary = createSelector(getCommentsArray, getCommentSummaryFilters, (/**
3929
+ * @param {?=} commentSummary
3930
+ * @param {?=} filters
3931
+ * @return {?}
3932
+ */
3933
+ (commentSummary = [], filters) => {
3934
+ /** @type {?} */
3935
+ const comments = StoreUtils.filterCommentsSummary(commentSummary, filters.filters);
3936
+ if (comments.length) {
3937
+ return comments.map((/**
3938
+ * @param {?} comment
3939
+ * @return {?}
3940
+ */
3941
+ (comment) => {
3942
+ return {
3943
+ page: comment.page,
3944
+ user: comment.createdByDetails.forename.concat(' ').concat(comment.createdByDetails.surname),
3945
+ date: moment(comment.lastModifiedDate).format('D MMMM YYYY'),
3946
+ tags: comment.tags,
3947
+ comment: comment.content
3948
+ };
3949
+ }));
4261
3950
  }
4262
- /**
3951
+ return [''];
3952
+ }));
3953
+ /** @type {?} */
3954
+ const getFilteredAnnotations = createSelector(getAnnotationEntities, getTagFiltered, (/**
3955
+ * @param {?} annoEnt
3956
+ * @param {?} filters
3957
+ * @return {?}
3958
+ */
3959
+ (annoEnt, filters) => {
3960
+ /** @type {?} */
3961
+ const isFiltered = !!Object.keys(filters).length;
3962
+ /** @type {?} */
3963
+ const anno = isFiltered ? filters : annoEnt;
3964
+ return Object.keys(anno).map((/**
3965
+ * @param {?} key
4263
3966
  * @return {?}
4264
3967
  */
4265
- get annotationFullsUrl() {
4266
- return this.annotationApiUrl + this.annotationBaseUrl;
4267
- }
4268
- }
4269
- AnnotationApiService.decorators = [
4270
- { type: Injectable }
4271
- ];
4272
- /** @nocollapse */
4273
- AnnotationApiService.ctorParameters = () => [
4274
- { type: HttpClient }
4275
- ];
3968
+ key => annoEnt[key]))
3969
+ .filter((/**
3970
+ * @param {?} annotation
3971
+ * @return {?}
3972
+ */
3973
+ annotation => annotation.comments && annotation.comments.length > 0));
3974
+ }));
4276
3975
 
4277
3976
  /**
4278
3977
  * @fileoverview added by tsickle
@@ -4814,7 +4513,7 @@ class MainToolbarComponent {
4814
4513
  MainToolbarComponent.decorators = [
4815
4514
  { type: Component, args: [{
4816
4515
  selector: 'mv-main-toolbar',
4817
- template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button id=\"mvMoreOptionsBtn\" class=\"mv-button mv-toolbar__menu-button--more-options\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"mvToolbar.offsetWidth >= allButtonsWidth\" aria-pressed=\"false\"\n (click)=\"toggleMoreOptions()\" cdkOverlayOrigin #trigger=\"cdkOverlayOrigin\">\n <span>More options</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\" [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\">\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n\n <button *ngIf=\"toolbarButtons.showSidebar\" id=\"mvIndexBtn\" title=\"Index\" data-l10n-id=\"index\" #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\" aria-pressed=\"false\"\n (click)=\"toggleSideBar()\">\n <span>Index</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showDrawButton\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvDrawBtn\"\n #mvDrawBtn class=\"mv-button mv-toolbar__menu-button--draw\" title=\"Draw a box\" tabindex=\"-1\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\" aria-hidden=\"true\" aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\" (click)=\"onClickDrawToggle()\">\n <span data-l10n-id=\"draw_label\">Draw a box</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showHighlightButton\" [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\" #mvHighlightBtn class=\"mv-button mv-toolbar__menu-button--highlight\" title=\"Highlight\"\n tabindex=\"-1\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\"\n [class.toggled]=\"toolbarEvents.highlightModeSubject | async\" aria-hidden=\"true\" aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle()\" data-l10n-id=\"toggleHighlightButton\">\n <span data-l10n-id=\"highlight_label\">Highlight</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div id=\"mvPageBtn\" #mvPageBtn class=\"mv-toolbar__menu-button--page\" aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\">\n <span>Page</span>\n\n <button id=\"mvUpBtn\" [disabled]=\"pageNumber === 1\" title=\"Previous Page\"\n class=\"mv-toolbar__menu-button--up button-image\" data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"><span></span></button>\n <button id=\"mvDownBtn\" [disabled]=\"pageNumber === pageCount\" title=\"Next Page\"\n class=\"mv-toolbar__menu-button--down button-image\" data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"><span></span></button>\n\n <input type=\"number\" id=\"pageNumber\" class=\"hmcts-toolbar-input govuk-input--width-2\" title=\"Page Number\"\n value=\"1\" size=\"4\" min=\"1\" [value]=\"pageNumber\" aria-label=\"page number\" tabindex=\"0\"\n data-l10n-id=\"page\" (change)=\"onPageNumberInputChange(pageNumberInput.value)\" #pageNumberInput>\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div id=\"mvZoomBtn\" #mvZoomBtn class=\"mv-toolbar__menu-button--zoom\" aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\">\n <span>Zoom</span>\n <button [disabled]=\"toolbarEvents.zoomValueSubject.value == 0.1\" id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image\" title=\"Zoom Out\" data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"><span></span></button>\n <select id=\"scaleSelect\" class=\"hmcts-toolbar-select\" title=\"Zoom\" tabindex=\"0\" data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\" aria-label=\"zoom\">\n <option #zoomSelect id=\"customScaleOption\" title=\"\" [value]=\"toolbarEvents.zoomValueSubject.value\">\n {{(toolbarEvents.zoomValueSubject.value) * 100 | number: '1.0-0'}}%</option>\n <option *ngFor=\"let zoomScale of zoomScales\" title=\"\" [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale*100\">{{ zoomScale *100 }}%\n </option>\n </select>\n\n <button [disabled]=\"toolbarEvents.zoomValueSubject.value == 5\" id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image\" (click)=\"stepZoom(0.1)\" title=\"Zoom In\"\n data-l10n-id=\"zoom_in\"><span></span></button>\n </div>\n </ng-container>\n\n <div *ngIf=\"toolbarButtons.showRotate\" id=\"mvRotateBtn\" #mvRotateBtn class=\"mv-toolbar__menu-button--rotate\"\n aria-pressed=\"false\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\">\n <button id=\"mvRotateLeftBtn\" class=\"mv-toolbar__menu-button--rotate_left button-image\"\n title=\"Rotate Counterclockwise\" data-l10n-id=\"page_rotate_ccw\" (click)=\"rotate(270)\"><span></span>\n </button>\n <button id=\"mvRotateRightBtn\" class=\"mv-toolbar__menu-button--rotate_right button-image\"\n title=\"Rotate Clockwise\" data-l10n-id=\"page_rotate_cw\" (click)=\"rotate(90)\"><span></span>\n </button>\n <span>Rotate</span>\n </div>\n\n <button *ngIf=\"toolbarButtons.showSearchBar\" [disabled]=\"icpEnabled\" id=\"mvSearchBtn\" #mvSearchBtn\n title=\"Search\" data-l10n-id=\"searchbar\" class=\"mv-button mv-toolbar__menu-button--search\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\" aria-pressed=\"false\"\n (click)=\"toggleSearchBar()\">\n <span data-l10n-id=\"search_label\">Search</span>\n </button>\n\n <button *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\" id=\"mvPresentBtn\" #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present\" title=\"In-Court Presentation Mode\"\n data-l10n-id=\"icpMode_label\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPresentBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPresentBtn']\" aria-pressed=\"false\"\n (click)=\"togglePresentBar()\"><span data-l10n-id=\"icpMode_label\">Present</span>\n </button>\n\n <button *ngIf=\"enableRedactions && toolbarButtons.showRedact\" [disabled]=\"icpEnabled\" id=\"mvRedactBtn\"\n #mvRedactBtn title=\"Redact\" data-l10n-id=\"redact\" class=\"mv-button mv-toolbar__menu-button--redact\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRedactBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRedactBtn']\" aria-pressed=\"false\"\n (click)=\"toggleRedactBar()\">\n <span>Redact</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showGrabNDragButton\" [disabled]=\"icpEnabled\" id=\"mvGrabBtn\" #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvGrabBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvGrabBtn']\" aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag()\">\n <span>Grab and drag</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showDownload\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvDownloadBtn\"\n #mvDownloadBtn class=\"mv-button mv-toolbar__menu-button--download\" title=\"Download\" data-l10n-id=\"download\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDownloadBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDownloadBtn']\" aria-pressed=\"false\"\n (click)=\"downloadFile()\">\n <span>Download</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showPrint\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvPrintBtn\"\n #mvPrintBtn title=\"Print\" data-l10n-id=\"print\" class=\"mv-button mv-toolbar__menu-button--print\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPrintBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPrintBtn']\" aria-pressed=\"false\"\n (click)=\"printFile()\">\n <span>Print</span>\n </button>\n\n <button *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\" [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\" #mvCommentsBtn class=\"mv-button mv-toolbar__menu-button--comments\" title=\"Comments\"\n data-l10n-id=\"comments\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvCommentsBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvCommentsBtn']\" aria-pressed=\"false\"\n (click)=\"toggleCommentsPanel()\">\n <span>Comments</span>\n </button>\n </ng-template>\n </div>\n <mv-search-bar></mv-search-bar>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\">\n </div>\n </div>\n </div>\n </div>\n</div>\n"
4516
+ template: "<div class=\"toolbar\">\n <div id=\"toolbarContainer\">\n <div class=\"mv-toolbar__container\">\n <div #mvToolbar class=\"mv-toolbar\" [class.notSupported]=\"!contentType\">\n <!-- The mvToolbarMain div contains all toolbar buttons except the \"More options\" button. This allows for calculation of the available space to display buttons -->\n <div id=\"mvToolbarMain\" class=\"mv-toolbar-main\" #mvToolbarMain>\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n <!-- The mvToolbarMoreOptions div contains the \"More options\" toolbar button (and the overlay template for the dropdown menu).\n The space occupied by the button (if visible) is excluded from the toolbar space available calculation -->\n <div id=\"mvToolbarMoreOptions\" class=\"mv-toolbar-more-options\">\n <button id=\"mvMoreOptionsBtn\" class=\"mv-button mv-toolbar__menu-button--more-options\"\n [class.mv-toolbar__menu-button--more-options__hidden]=\"mvToolbar.offsetWidth >= allButtonsWidth\" aria-pressed=\"false\"\n (click)=\"toggleMoreOptions()\" cdkOverlayOrigin #trigger=\"cdkOverlayOrigin\">\n <span>More options</span>\n </button>\n <!-- This template displays the overlay content for the dropdown menu and is connected to the \"More options\" button -->\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]=\"trigger\"\n [cdkConnectedOverlayOpen]=\"isDropdownMenuOpen\" [cdkConnectedOverlayPositions]=\"dropdownMenuPositions\">\n <div class=\"dropdown-menu\" #dropdownMenu tabindex=\"0\">\n <ng-container *ngTemplateOutlet=\"menuItems\"></ng-container>\n </div>\n </ng-template>\n </div>\n </div>\n\n <div id=\"mvMenuItems\" #mvMenuItems>\n <ng-template #menuItems>\n\n <button *ngIf=\"toolbarButtons.showSidebar\" id=\"mvIndexBtn\" title=\"Index\" data-l10n-id=\"index\" #mvIndexBtn\n class=\"mv-button mv-toolbar__menu-button--index\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvIndexBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvIndexBtn']\" aria-pressed=\"false\"\n (click)=\"toggleSideBar(); isDropdownMenuOpen = false\">\n <span>Index</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showDrawButton\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvDrawBtn\"\n #mvDrawBtn class=\"mv-button mv-toolbar__menu-button--draw\" title=\"Draw a box\" tabindex=\"-1\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDrawBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDrawBtn']\"\n [class.toggled]=\"toolbarEvents.drawModeSubject | async\" aria-hidden=\"true\" aria-pressed=\"false\"\n data-l10n-id=\"toggleDrawButton\" (click)=\"onClickDrawToggle(); isDropdownMenuOpen = false\">\n <span data-l10n-id=\"draw_label\">Draw a box</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showHighlightButton\" [disabled]=\"icpEnabled || redactionEnabled\"\n id=\"mvHighlightBtn\" #mvHighlightBtn class=\"mv-button mv-toolbar__menu-button--highlight\" title=\"Highlight\"\n tabindex=\"-1\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvHighlightBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvHighlightBtn']\"\n [class.toggled]=\"toolbarEvents.highlightModeSubject | async\" aria-hidden=\"true\" aria-pressed=\"false\"\n (click)=\"onClickHighlightToggle(); isDropdownMenuOpen = false\" data-l10n-id=\"toggleHighlightButton\">\n <span data-l10n-id=\"highlight_label\">Highlight</span>\n </button>\n\n <ng-container *ngIf=\"toolbarButtons.showNavigation\">\n <div id=\"mvPageBtn\" #mvPageBtn class=\"mv-toolbar__menu-button--page\" aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPageBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPageBtn']\">\n <span>Page</span>\n\n <button id=\"mvUpBtn\" [disabled]=\"pageNumber === 1\" title=\"Previous Page\"\n class=\"mv-toolbar__menu-button--up button-image\" data-l10n-id=\"previous\"\n (click)=\"decreasePageNumber()\"><span></span></button>\n <button id=\"mvDownBtn\" [disabled]=\"pageNumber === pageCount\" title=\"Next Page\"\n class=\"mv-toolbar__menu-button--down button-image\" data-l10n-id=\"next\"\n (click)=\"increasePageNumber()\"><span></span></button>\n\n <input type=\"number\" id=\"pageNumber\" class=\"hmcts-toolbar-input govuk-input--width-2\" title=\"Page Number\"\n value=\"1\" size=\"4\" min=\"1\" [value]=\"pageNumber\" aria-label=\"page number\" tabindex=\"0\"\n data-l10n-id=\"page\" (change)=\"onPageNumberInputChange(pageNumberInput.value)\" #pageNumberInput>\n <span id=\"numPages\" class=\"toolbarLabel\">/ {{ pageCount }}</span>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"toolbarButtons.showZoom\">\n <div id=\"mvZoomBtn\" #mvZoomBtn class=\"mv-toolbar__menu-button--zoom\" aria-pressed=\"false\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvZoomBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvZoomBtn']\">\n <span>Zoom</span>\n <button [disabled]=\"toolbarEvents.zoomValueSubject.value == 0.1\" id=\"mvMinusBtn\"\n class=\"mv-toolbar__menu-button--zoom-out button-image\" title=\"Zoom Out\" data-l10n-id=\"zoom_out\"\n (click)=\"stepZoom(-0.1)\"><span></span></button>\n <select id=\"scaleSelect\" class=\"hmcts-toolbar-select\" title=\"Zoom\" tabindex=\"0\" data-l10n-id=\"zoom\"\n (change)=\"zoom($event.target.value)\" aria-label=\"zoom\">\n <option #zoomSelect id=\"customScaleOption\" title=\"\" [value]=\"toolbarEvents.zoomValueSubject.value\">\n {{(toolbarEvents.zoomValueSubject.value) * 100 | number: '1.0-0'}}%</option>\n <option *ngFor=\"let zoomScale of zoomScales\" title=\"\" [value]=\"zoomScale\"\n [attr.data-l10n-id]=\"'page_scale_percent_' + zoomScale*100\">{{ zoomScale *100 }}%\n </option>\n </select>\n\n <button [disabled]=\"toolbarEvents.zoomValueSubject.value == 5\" id=\"mvPlusBtn\"\n class=\"mv-toolbar__menu-button--zoom-in button-image\" (click)=\"stepZoom(0.1)\" title=\"Zoom In\"\n data-l10n-id=\"zoom_in\"><span></span></button>\n </div>\n </ng-container>\n\n <div *ngIf=\"toolbarButtons.showRotate\" id=\"mvRotateBtn\" #mvRotateBtn class=\"mv-toolbar__menu-button--rotate\"\n aria-pressed=\"false\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRotateBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRotateBtn']\">\n <button id=\"mvRotateLeftBtn\" class=\"mv-toolbar__menu-button--rotate_left button-image\"\n title=\"Rotate Counterclockwise\" data-l10n-id=\"page_rotate_ccw\" (click)=\"rotate(270)\"><span></span>\n </button>\n <button id=\"mvRotateRightBtn\" class=\"mv-toolbar__menu-button--rotate_right button-image\"\n title=\"Rotate Clockwise\" data-l10n-id=\"page_rotate_cw\" (click)=\"rotate(90)\"><span></span>\n </button>\n <span>Rotate</span>\n </div>\n\n <button *ngIf=\"toolbarButtons.showSearchBar\" [disabled]=\"icpEnabled\" id=\"mvSearchBtn\" #mvSearchBtn\n title=\"Search\" data-l10n-id=\"searchbar\" class=\"mv-button mv-toolbar__menu-button--search\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvSearchBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvSearchBtn']\" aria-pressed=\"false\"\n (click)=\"toggleSearchBar(); isDropdownMenuOpen = false\">\n <span data-l10n-id=\"search_label\">Search</span>\n </button>\n\n <button *ngIf=\"enableICP && toolbarButtons.showPresentationMode && isPdf()\"\n [disabled]=\"icpEnabled || !contentType || redactionEnabled\" id=\"mvPresentBtn\" #mvPresentBtn\n class=\"mv-button mv-toolbar__menu-button--present\" title=\"In-Court Presentation Mode\"\n data-l10n-id=\"icpMode_label\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPresentBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPresentBtn']\" aria-pressed=\"false\"\n (click)=\"togglePresentBar(); isDropdownMenuOpen = false\"><span data-l10n-id=\"icpMode_label\">Present</span>\n </button>\n\n <button *ngIf=\"enableRedactions && toolbarButtons.showRedact\" [disabled]=\"icpEnabled\" id=\"mvRedactBtn\"\n #mvRedactBtn title=\"Redact\" data-l10n-id=\"redact\" class=\"mv-button mv-toolbar__menu-button--redact\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvRedactBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvRedactBtn']\" aria-pressed=\"false\"\n (click)=\"toggleRedactBar(); isDropdownMenuOpen = false\">\n <span>Redact</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showGrabNDragButton\" [disabled]=\"icpEnabled\" id=\"mvGrabBtn\" #mvGrabBtn\n class=\"mv-button mv-toolbar__menu-button--grab\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvGrabBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvGrabBtn']\" aria-pressed=\"false\"\n (click)=\"toggleGrabNDrag(); isDropdownMenuOpen = false\">\n <span>Grab and drag</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showDownload\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvDownloadBtn\"\n #mvDownloadBtn class=\"mv-button mv-toolbar__menu-button--download\" title=\"Download\" data-l10n-id=\"download\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvDownloadBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvDownloadBtn']\" aria-pressed=\"false\"\n (click)=\"downloadFile(); isDropdownMenuOpen = false\">\n <span>Download</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showPrint\" [disabled]=\"icpEnabled || redactionEnabled\" id=\"mvPrintBtn\"\n #mvPrintBtn title=\"Print\" data-l10n-id=\"print\" class=\"mv-button mv-toolbar__menu-button--print\"\n [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvPrintBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvPrintBtn']\" aria-pressed=\"false\"\n (click)=\"printFile(); isDropdownMenuOpen = false\">\n <span>Print</span>\n </button>\n\n <button *ngIf=\"enableAnnotations && toolbarButtons.showCommentSummary\" [disabled]=\"redactionEnabled\"\n id=\"mvCommentsBtn\" #mvCommentsBtn class=\"mv-button mv-toolbar__menu-button--comments\" title=\"Comments\"\n data-l10n-id=\"comments\" [class.button-hidden-on-toolbar]=\"mvToolbarMain.offsetWidth < widthRequiredForBtn['mvCommentsBtn']\"\n [class.button-hidden-on-dropdown]=\"mvToolbarMain.offsetWidth >= widthRequiredForBtn['mvCommentsBtn']\" aria-pressed=\"false\"\n (click)=\"toggleCommentsPanel(); isDropdownMenuOpen = false\">\n <span>Comments</span>\n </button>\n </ng-template>\n </div>\n <mv-search-bar></mv-search-bar>\n </div>\n\n <div id=\"loadingBar\">\n <div class=\"progress\">\n <div class=\"glimmer\">\n </div>\n </div>\n </div>\n </div>\n</div>\n"
4818
4517
  }] }
4819
4518
  ];
4820
4519
  /** @nocollapse */
@@ -4958,11 +4657,17 @@ class SearchBarComponent {
4958
4657
  toggleAdvancedSearch() {
4959
4658
  this.advancedSearchVisible = !this.advancedSearchVisible;
4960
4659
  }
4660
+ /**
4661
+ * @return {?}
4662
+ */
4663
+ toggleSearchBar() {
4664
+ this.toolbarEvents.searchBarHidden.next(!this.toolbarEvents.searchBarHidden.getValue());
4665
+ }
4961
4666
  }
4962
4667
  SearchBarComponent.decorators = [
4963
4668
  { type: Component, args: [{
4964
4669
  selector: 'mv-search-bar',
4965
- template: "<div class=\"searchbar govuk-!-padding-3\" [hidden]=\"toolbarEvents.searchBarHidden | async\">\n <div class=\"govuk-grid-row\">\n <div class=\"govuk-grid-column-full\">\n <input class=\"govuk-input govuk-!-display-inline-block govuk-!-width-three-quarters govuk-!-margin-bottom-1\"\n type=\"text\" aria-label=\"Find in document\" #findInput [(ngModel)]=\"searchText\" (keydown.escape)=\"onEscapeKeyPress($event)\" (keydown.enter)=\"onEnterKeyPress($event)\" title=\"Find in document\"\n placeholder=\"Find in document\u2026\" tabindex=\"0\" data-l10n-id=\"find_input\" />\n <button class=\"govuk-button govuk-!-display-inline-block govuk-!-margin-bottom-4\" data-module=\"govuk-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n </div>\n\n <div class=\"govuk-grid-row\">\n <div class=\"govuk-grid-column-three-quarters\">\n <span id=\"findResultsCount\" class=\"govuk-!-display-inline-block govuk-!-margin-right-4\">{{resultsText}}</span>\n <a *ngIf=\"resultCount > 0\" [routerLink]=\"\" class=\"govuk-link govuk-link--no-visited-state govuk-!-margin-right-2\"\n (click)=\"searchPrev()\" title=\"Find the previous occurrence of the phrase\" data-l10n-id=\"find_previous\">Prev</a>\n <a *ngIf=\"resultCount > 0\" [routerLink]=\"\" class=\"govuk-link govuk-link--no-visited-state\" (click)=\"searchNext()\"\n title=\"Find the next occurrence of the phrase\" data-l10n-id=\"find_next\">Next</a>\n </div>\n <div class=\"govuk-grid-column-one-quarter\">\n <a [routerLink]=\"\" class=\"govuk-link govuk-link--no-visited-state\" (click)=\"toggleAdvancedSearch()\" title=\"Advanced\"\n data-l10n-id=\"find_advanced\">Advanced</a>\n </div>\n </div>\n\n <div class=\"govuk-grid-row\" *ngIf=\"advancedSearchVisible\">\n <div class=\"govuk-grid-column-full\">\n <div class=\"govuk-form-group govuk-!-margin-top-3 govuk-!-margin-bottom-1\">\n <fieldset class=\"govuk-fieldset\" aria-describedby=\"advanced\">\n <div class=\"govuk-checkboxes\">\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"findHighlightAll\" name=\"findHighlightAll\" type=\"checkbox\"\n (change)=\"highlightAll = !highlightAll; search()\" [checked]=\"highlightAll\">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"findHighlightAll\" data-l10n-id=\"find_highlight\">\n Highlight all (instances of matches)\n </label>\n </div>\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"findMatchCase\" name=\"findMatchCase\" type=\"checkbox\"\n (change)=\"matchCase = !matchCase; search()\" [checked]=\"matchCase\">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"findMatchCase\"\n data-l10n-id=\"find_match_case_label\">\n Match text (exact words)\n </label>\n </div>\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"findEntireWord\" name=\"findMatchCase\" type=\"checkbox\"\n (change)=\"wholeWord = !wholeWord; search()\" [checked]=\"wholeWord\">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"findEntireWord\"\n data-l10n-id=\"find_entire_word_label\">\n Match sentence (strings of words)\n </label>\n </div>\n </div>\n </fieldset>\n </div>\n </div>\n </div>"
4670
+ template: "<div class=\"searchbar govuk-!-padding-3\" [hidden]=\"toolbarEvents.searchBarHidden | async\">\n <div class=\"govuk-grid-row\">\n <button id=\"mvCloseBtn\" #mvCloseBtn class=\"mv-button searchbar-button--close\" title=\"Close Search\" data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleSearchBar()\">\n </button>\n <div class=\"govuk-grid-column-full\">\n <input class=\"govuk-input govuk-!-display-inline-block govuk-!-width-three-quarters govuk-!-margin-bottom-1\"\n type=\"text\" aria-label=\"Find in document\" #findInput [(ngModel)]=\"searchText\" (keydown.escape)=\"onEscapeKeyPress($event)\" (keydown.enter)=\"onEnterKeyPress($event)\" title=\"Find in document\"\n placeholder=\"Find in document\u2026\" tabindex=\"0\" data-l10n-id=\"find_input\" />\n <button class=\"govuk-button govuk-!-display-inline-block govuk-!-margin-bottom-4\" data-module=\"govuk-button\"\n (click)=\"search()\">\n Search\n </button>\n </div>\n </div>\n\n <div class=\"govuk-grid-row\">\n <div class=\"govuk-grid-column-three-quarters\">\n <span id=\"findResultsCount\" class=\"govuk-!-display-inline-block govuk-!-margin-right-4\">{{resultsText}}</span>\n <a *ngIf=\"resultCount > 0\" [routerLink]=\"\" class=\"govuk-link govuk-link--no-visited-state govuk-!-margin-right-2\"\n (click)=\"searchPrev()\" title=\"Find the previous occurrence of the phrase\" data-l10n-id=\"find_previous\">Prev</a>\n <a *ngIf=\"resultCount > 0\" [routerLink]=\"\" class=\"govuk-link govuk-link--no-visited-state\" (click)=\"searchNext()\"\n title=\"Find the next occurrence of the phrase\" data-l10n-id=\"find_next\">Next</a>\n </div>\n <div class=\"govuk-grid-column-one-quarter\">\n <a [routerLink]=\"\" class=\"govuk-link govuk-link--no-visited-state\" (click)=\"toggleAdvancedSearch()\" title=\"Advanced\"\n data-l10n-id=\"find_advanced\">Advanced</a>\n </div>\n </div>\n\n <div class=\"govuk-grid-row\" *ngIf=\"advancedSearchVisible\">\n <div class=\"govuk-grid-column-full\">\n <div class=\"govuk-form-group govuk-!-margin-top-3 govuk-!-margin-bottom-1\">\n <fieldset class=\"govuk-fieldset\" aria-describedby=\"advanced\">\n <div class=\"govuk-checkboxes\">\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"findHighlightAll\" name=\"findHighlightAll\" type=\"checkbox\"\n (change)=\"highlightAll = !highlightAll; search()\" [checked]=\"highlightAll\">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"findHighlightAll\" data-l10n-id=\"find_highlight\">\n Highlight all\n </label>\n </div>\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"findMatchCase\" name=\"findMatchCase\" type=\"checkbox\"\n (change)=\"matchCase = !matchCase; search()\" [checked]=\"matchCase\">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"findMatchCase\"\n data-l10n-id=\"find_match_case_label\">\n Match text (exact case)\n </label>\n </div>\n <div class=\"govuk-checkboxes__item\">\n <input class=\"govuk-checkboxes__input\" id=\"findEntireWord\" name=\"findMatchCase\" type=\"checkbox\"\n (change)=\"wholeWord = !wholeWord; search()\" [checked]=\"wholeWord\">\n <label class=\"govuk-label govuk-checkboxes__label\" for=\"findEntireWord\"\n data-l10n-id=\"find_entire_word_label\">\n Match whole words or sentences\n </label>\n </div>\n </div>\n </fieldset>\n </div>\n </div>\n </div>\n</div>\n"
4966
4671
  }] }
4967
4672
  ];
4968
4673
  /** @nocollapse */
@@ -5092,6 +4797,12 @@ class RedactionToolbarComponent {
5092
4797
  redact() {
5093
4798
  this.toolbarEventService.applyRedactionToDocument();
5094
4799
  }
4800
+ /**
4801
+ * @return {?}
4802
+ */
4803
+ toggleRedactBar() {
4804
+ this.toolbarEventService.toggleRedactionMode();
4805
+ }
5095
4806
  /**
5096
4807
  * @return {?}
5097
4808
  */
@@ -5102,7 +4813,7 @@ class RedactionToolbarComponent {
5102
4813
  RedactionToolbarComponent.decorators = [
5103
4814
  { type: Component, args: [{
5104
4815
  selector: 'mv-redaction-toolbar',
5105
- template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\">Redaction options</label>\n <button id=\"toggleDrawButton\" class=\"mv-button redaction-button--draw\" title=\"Draw a box\"\n data-l10n-id=\"toggleDrawButton\" (click)=\"toggleDrawMode()\">\n <span data-l10n-id=\"toggleDrawButton_label\">Draw a box</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showHighlightButton\" id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact\" aria-pressed=\"false\" title=\"Redact text\"\n data-l10n-id=\"toggleTextRedactionButton\" (click)=\"toggleTextRedactionMode()\">\n <span data-l10n-id=\"toggleTextRedactionButton_label\">Redact text</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvClearBtn\" #mvClearBtn class=\"mv-button redaction-button--clear\" aria-pressed=\"false\" title=\"Clear all\"\n data-l10n-id=\"toggleClearAllButton\" (click)=\"unmarkAll()\">\n <span data-l10n-id=\"Clear all\">Clear all</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvPreviewBtn\" class=\"mv-button\" [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\" redaction-button--preview aria-pressed=\"false\" title=\"Preview\"\n data-l10n-id=\"togglePreviewButton\" (click)=\"togglePreview()\">\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">Preview</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\">Hide preview</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvRedactBtn\" class=\"mv-button redaction-button--download\" aria-pressed=\"false\" title=\"Redact\"\n data-l10n-id=\"mvRedactBtn\" (click)=\"redact()\">\n <span data-l10n-id=\"Save Document\">Save document</span>\n </button>\n\n</div>\n"
4816
+ template: "<div class=\"redaction\">\n <label class=\"govuk-label redaction-title\" data-l10n-id=\"redaction_options\">Redaction options</label>\n <button id=\"toggleDrawButton\" class=\"mv-button redaction-button--draw\" title=\"Draw a box\"\n data-l10n-id=\"toggleDrawButton\" (click)=\"toggleDrawMode()\">\n <span data-l10n-id=\"toggleDrawButton_label\">Draw a box</span>\n </button>\n\n <button *ngIf=\"toolbarButtons.showHighlightButton\" id=\"toggleHighlightButton\"\n class=\"mv-button redaction-button--redact\" aria-pressed=\"false\" title=\"Redact text\"\n data-l10n-id=\"toggleTextRedactionButton\" (click)=\"toggleTextRedactionMode()\">\n <span data-l10n-id=\"toggleTextRedactionButton_label\">Redact text</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvClearBtn\" #mvClearBtn class=\"mv-button redaction-button--clear\" aria-pressed=\"false\" title=\"Clear all\"\n data-l10n-id=\"toggleClearAllButton\" (click)=\"unmarkAll()\">\n <span data-l10n-id=\"Clear all\">Clear all</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvPreviewBtn\" class=\"mv-button\" [class.redaction-button--preview]=\"!preview\"\n [class.redaction-button--hide-preview]=\"preview\" redaction-button--preview aria-pressed=\"false\" title=\"Preview\"\n data-l10n-id=\"togglePreviewButton\" (click)=\"togglePreview()\">\n <span *ngIf=\"!preview\" data-l10n-id=\"redaction-preview_label\">Preview</span>\n <span *ngIf=\"preview\" data-l10n-id=\"redaction-hide-preview_label\">Hide preview</span>\n </button>\n\n <button [disabled]=\"!hasRedactions\" id=\"mvRedactBtn\" class=\"mv-button redaction-button--download\" aria-pressed=\"false\" title=\"Redact\"\n data-l10n-id=\"mvRedactBtn\" (click)=\"redact()\">\n <span data-l10n-id=\"Save Document\">Save document</span>\n </button>\n\n <button id=\"mvCloseBtn\" #mvCloseBtn class=\"mv-button redaction-button--close\" title=\"Close Redaction\" data-l10n-id=\"mvRedactBtn\"\n (click)=\"toggleRedactBar()\">\n <span data-l10n-id=\"Close Redaction\">Close Redaction</span>\n </button>\n\n</div>\n"
5106
4817
  }] }
5107
4818
  ];
5108
4819
  /** @nocollapse */
@@ -5765,366 +5476,675 @@ TagsServices.ctorParameters = () => [
5765
5476
  */
5766
5477
  class CommentComponent {
5767
5478
  /**
5768
- * @param {?} store
5769
- * @param {?} commentService
5770
- * @param {?} tagsServices
5479
+ * @param {?} store
5480
+ * @param {?} commentService
5481
+ * @param {?} tagsServices
5482
+ */
5483
+ constructor(store, commentService, tagsServices) {
5484
+ this.store = store;
5485
+ this.commentService = commentService;
5486
+ this.tagsServices = tagsServices;
5487
+ this.CHAR_LIMIT = 5000;
5488
+ this.totalPrevPagesHeight = 0;
5489
+ this.hasUnsavedChanges = false;
5490
+ this.commentClick = new EventEmitter();
5491
+ this.renderComments = new EventEmitter();
5492
+ this.delete = new EventEmitter();
5493
+ this.updated = new EventEmitter();
5494
+ this.changes = new EventEmitter();
5495
+ this.rotate = 0;
5496
+ this.zoom = 1;
5497
+ }
5498
+ /**
5499
+ * @return {?}
5500
+ */
5501
+ ngOnInit() {
5502
+ this.subscriptions = this.store.select(getComponentSearchText)
5503
+ .pipe(distinctUntilChanged()).subscribe((/**
5504
+ * @param {?} searchString
5505
+ * @return {?}
5506
+ */
5507
+ searchString => this.searchString = searchString));
5508
+ this.reRenderComments();
5509
+ }
5510
+ /**
5511
+ * @return {?}
5512
+ */
5513
+ ngAfterContentInit() {
5514
+ if (this.tagItems && this.tagItems.length) {
5515
+ this.tagsServices.updateTagItems(this.tagItems, this._comment.annotationId);
5516
+ }
5517
+ }
5518
+ /**
5519
+ * @return {?}
5520
+ */
5521
+ ngOnDestroy() {
5522
+ this.subscriptions.unsubscribe();
5523
+ }
5524
+ /**
5525
+ * @param {?} comment
5526
+ * @return {?}
5527
+ */
5528
+ set comment(comment) {
5529
+ this._comment = Object.assign({}, comment);
5530
+ this.page = this._comment.page;
5531
+ this.lastUpdate = comment.lastModifiedDate ? comment.lastModifiedDate : comment.createdDate;
5532
+ this.author = comment.createdByDetails;
5533
+ this.createdBy = comment.createdBy;
5534
+ this.editor = comment.lastModifiedByDetails;
5535
+ this.originalComment = comment.content;
5536
+ this.fullComment = this.originalComment;
5537
+ this.selected = this._comment.selected;
5538
+ this._editable = this._comment.editable;
5539
+ this.tagItems = this._comment.tags;
5540
+ /** @type {?} */
5541
+ const pageMarginBottom = 10;
5542
+ this.totalPrevPagesHeight = 0;
5543
+ for (let i = 0; i < this.page - 1; i++) {
5544
+ /** @type {?} */
5545
+ const height = this._comment.pages[i + 1] ? this._comment.pages[i + 1].styles.height : undefined;
5546
+ if (height) {
5547
+ this.totalPrevPagesHeight += height + pageMarginBottom;
5548
+ }
5549
+ }
5550
+ }
5551
+ /**
5552
+ * @return {?}
5553
+ */
5554
+ get comment() {
5555
+ return this._comment;
5556
+ }
5557
+ /**
5558
+ * @param {?} annotation
5559
+ * @return {?}
5560
+ */
5561
+ set annotation(annotation) {
5562
+ this._rectangle = annotation.rectangles
5563
+ .reduce((/**
5564
+ * @param {?} prev
5565
+ * @param {?} current
5566
+ * @return {?}
5567
+ */
5568
+ (prev, current) => prev.y < current.y ? prev : current));
5569
+ /** @type {?} */
5570
+ const actualHeight = this._comment.pages[this.page].styles.height / this.zoom;
5571
+ switch (this.rotate) {
5572
+ case 90:
5573
+ this.rectTop = this._rectangle.x;
5574
+ break;
5575
+ case 180:
5576
+ this.rectTop = actualHeight - (this._rectangle.y + this._rectangle.height);
5577
+ break;
5578
+ case 270:
5579
+ this.rectTop = actualHeight - (this._rectangle.x + this._rectangle.width);
5580
+ break;
5581
+ default: this.rectTop = this._rectangle.y;
5582
+ }
5583
+ this.rectLeft = this._rectangle.x;
5584
+ }
5585
+ /**
5586
+ * @return {?}
5587
+ */
5588
+ get editable() {
5589
+ return this._editable;
5590
+ }
5591
+ /**
5592
+ * @param {?} updatedComment
5593
+ * @return {?}
5594
+ */
5595
+ onCommentChange(updatedComment) {
5596
+ this.hasUnsavedChanges =
5597
+ this.originalComment.substring(0, this.CHAR_LIMIT) !== updatedComment.substring(0, this.CHAR_LIMIT);
5598
+ this.commentService.onCommentChange(this.hasUnsavedChanges);
5599
+ }
5600
+ /**
5601
+ * @return {?}
5602
+ */
5603
+ deleteOrCancel() {
5604
+ if (!this.editable) {
5605
+ this.delete.emit(this._comment);
5606
+ }
5607
+ else {
5608
+ this.hasUnsavedChanges = false;
5609
+ this._editable = false;
5610
+ this.fullComment = this.originalComment;
5611
+ this.changes.emit(false);
5612
+ if (!this.author && !this.fullComment) {
5613
+ this.delete.emit(this._comment);
5614
+ }
5615
+ }
5616
+ }
5617
+ /**
5618
+ * @return {?}
5619
+ */
5620
+ editOrSave() {
5621
+ if (!this.editable) {
5622
+ this._editable = true;
5623
+ }
5624
+ else {
5625
+ this._comment.content = this.fullComment.substring(0, this.CHAR_LIMIT);
5626
+ /** @type {?} */
5627
+ const tags = this.tagsServices.getNewTags(this._comment.annotationId);
5628
+ /** @type {?} */
5629
+ const payload = {
5630
+ comment: this._comment,
5631
+ tags
5632
+ };
5633
+ this.updated.emit(payload);
5634
+ this.hasUnsavedChanges = false;
5635
+ this._editable = false;
5636
+ this.changes.emit(false);
5637
+ }
5638
+ }
5639
+ /**
5640
+ * @return {?}
5641
+ */
5642
+ onCommentClick() {
5643
+ if (!this.selected) {
5644
+ this.selected = true;
5645
+ this._editable = false;
5646
+ this.commentClick.emit({ annotationId: this._comment.annotationId, editable: this._editable, selected: true });
5647
+ }
5648
+ }
5649
+ /**
5650
+ * @return {?}
5651
+ */
5652
+ reRenderComments() {
5653
+ this.renderComments.emit(this._comment);
5654
+ }
5655
+ /**
5656
+ * @return {?}
5657
+ */
5658
+ get commentTop() {
5659
+ return this.totalPrevPagesHeight + (this.rectTop * this.zoom);
5660
+ }
5661
+ /**
5662
+ * @return {?}
5663
+ */
5664
+ get height() {
5665
+ return this.form.nativeElement.getBoundingClientRect().height / this.zoom;
5666
+ }
5667
+ }
5668
+ CommentComponent.decorators = [
5669
+ { type: Component, args: [{
5670
+ selector: 'mv-anno-comment',
5671
+ template: "<div #form (click)=\"onCommentClick()\" class=\"aui-comment\"\n [style.top.px]=\"commentTop\"\n [style.zIndex]=\"selected ? 100 : 0\">\n <div id=\"detailsWrapper {{index}}\" class=\"aui-comment__header\">\n <span *ngIf=\"author && !editor\" class=\"aui-comment__author\">\n {{ author.forename }} {{ author.surname }}\n </span>\n <span *ngIf=\"editor\" class=\"aui-comment__author\">\n {{ editor.forename }} {{ editor.surname }}\n </span>\n <time [hidden]=\"!selected && !this.editable\" class=\"aui-comment__meta\">\n {{ lastUpdate | momentDate: 'd MMMM y h:mm a' }}\n </time>\n </div>\n <mv-tags\n [tagItems]=\"tagItems\"\n [userId]=\"createdBy\"\n [editable]=\"editable\"\n [annoId]=\"_comment.annotationId\">\n </mv-tags>\n <textarea *ngIf=\"selected && editable\"\n #editableComment\n mvTextAreaAutoExpand\n type=\"text\"\n required\n name=\"content\"\n [maxlength]=\"CHAR_LIMIT\"\n class=\"aui-comment__content form-control mimic-focus edit-mode expanded\"\n [(ngModel)]=\"fullComment\"\n (ngModelChange)=\"reRenderComments(); onCommentChange($event);\"\n aria-label=\"comment\">\n </textarea>\n <p *ngIf=\"!editable\"\n mvTextHighlight class=\"commentText\" [textToHighlight]=\"searchString\">\n {{ fullComment }}\n </p>\n <div *ngIf=\"selected || this.editable || (!fullComment.length && (tagItems && !tagItems.length))\"\n class=\"aui-comment__footer commentBtns\">\n <button class=\"govuk-button\"\n type=\"button\" role=\"button\"\n (click)=\"editOrSave()\">\n {{ !editable ? 'Edit' : 'Save' }}\n </button>\n <button type=\"button\" role=\"button\"\n class=\"govuk-button govuk-button--secondary\"\n (click)=\"deleteOrCancel()\">\n {{ !editable ? 'Delete' : 'Cancel' }}\n </button>\n </div>\n <span class=\"aui-comment__private\">private</span>\n</div>\n"
5672
+ }] }
5673
+ ];
5674
+ /** @nocollapse */
5675
+ CommentComponent.ctorParameters = () => [
5676
+ { type: Store },
5677
+ { type: CommentService },
5678
+ { type: TagsServices }
5679
+ ];
5680
+ CommentComponent.propDecorators = {
5681
+ commentClick: [{ type: Output }],
5682
+ renderComments: [{ type: Output }],
5683
+ delete: [{ type: Output }],
5684
+ updated: [{ type: Output }],
5685
+ changes: [{ type: Output }],
5686
+ rotate: [{ type: Input }],
5687
+ zoom: [{ type: Input }],
5688
+ index: [{ type: Input }],
5689
+ page: [{ type: Input }],
5690
+ form: [{ type: ViewChild, args: ['form',] }],
5691
+ editableComment: [{ type: ViewChild, args: ['editableComment',] }],
5692
+ comment: [{ type: Input }],
5693
+ annotation: [{ type: Input }]
5694
+ };
5695
+
5696
+ /**
5697
+ * @fileoverview added by tsickle
5698
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5699
+ */
5700
+ class CtxToolbarComponent {
5701
+ constructor() {
5702
+ this.createHighlightEvent = new EventEmitter();
5703
+ this.deleteHighlightEvent = new EventEmitter();
5704
+ this.addOrEditCommentEvent = new EventEmitter();
5705
+ this.createBookmarkEvent = new EventEmitter();
5706
+ this.defaultHeight = 70;
5707
+ this.defaultWidth = 300;
5708
+ }
5709
+ /**
5710
+ * @param {?} changes
5711
+ * @return {?}
5712
+ */
5713
+ ngOnChanges(changes) {
5714
+ this.setRectangle();
5715
+ this.top = this.popupTop();
5716
+ this.left = this.popupLeft();
5717
+ }
5718
+ /**
5719
+ * @param {?} rectangles
5720
+ * @return {?}
5771
5721
  */
5772
- constructor(store, commentService, tagsServices) {
5773
- this.store = store;
5774
- this.commentService = commentService;
5775
- this.tagsServices = tagsServices;
5776
- this.COMMENT_CHAR_LIMIT = 5000;
5777
- this.totalPreviousPagesHeight = 0;
5778
- this.hasUnsavedChanges = false;
5779
- this.commentClick = new EventEmitter();
5780
- this.renderComments = new EventEmitter();
5781
- this.delete = new EventEmitter();
5782
- this.updated = new EventEmitter();
5783
- this.changes = new EventEmitter();
5784
- this.rotate = 0;
5785
- this.zoom = 1;
5722
+ set rectangles(rectangles) {
5723
+ if (rectangles) {
5724
+ this._rectangles = rectangles;
5725
+ this.setRectangle();
5726
+ }
5786
5727
  }
5787
5728
  /**
5788
5729
  * @return {?}
5789
5730
  */
5790
- ngOnInit() {
5791
- this.subscriptions = this.store.select(getComponentSearchText)
5792
- .pipe(distinctUntilChanged()).subscribe((/**
5793
- * @param {?} searchString
5794
- * @return {?}
5795
- */
5796
- searchString => this.searchString = searchString));
5797
- this.reRenderComments();
5731
+ get rectangles() {
5732
+ return this._rectangles;
5798
5733
  }
5799
5734
  /**
5800
5735
  * @return {?}
5801
5736
  */
5802
- ngAfterContentInit() {
5803
- if (this.tagItems && this.tagItems.length) {
5804
- this.tagsServices.updateTagItems(this.tagItems, this._comment.annotationId);
5805
- }
5737
+ createHighlight() {
5738
+ this.createHighlightEvent.emit();
5739
+ this.rectangle = undefined;
5806
5740
  }
5807
5741
  /**
5808
5742
  * @return {?}
5809
5743
  */
5810
- ngOnDestroy() {
5811
- this.subscriptions.unsubscribe();
5744
+ deleteHighlight() {
5745
+ this.deleteHighlightEvent.emit();
5812
5746
  }
5813
5747
  /**
5814
- * @param {?} comment
5815
5748
  * @return {?}
5816
5749
  */
5817
- set comment(comment) {
5818
- this._comment = Object.assign({}, comment);
5819
- this.page = this._comment.page;
5820
- this.lastUpdate = comment.lastModifiedDate ? comment.lastModifiedDate : comment.createdDate;
5821
- this.author = comment.createdByDetails;
5822
- this.createdBy = comment.createdBy;
5823
- this.editor = comment.lastModifiedByDetails;
5824
- this.originalComment = comment.content;
5825
- this.fullComment = this.originalComment;
5826
- this.selected = this._comment.selected;
5827
- this._editable = this._comment.editable;
5828
- this.tagItems = this._comment.tags;
5829
- /** @type {?} */
5830
- const pageMarginBottom = 10;
5831
- this.totalPreviousPagesHeight = 0;
5832
- for (let i = 0; i < this.page - 1; i++) {
5833
- /** @type {?} */
5834
- const height = this._comment.pages[i + 1] ? this._comment.pages[i + 1].styles.height : undefined;
5835
- if (height) {
5836
- this.totalPreviousPagesHeight += height + pageMarginBottom;
5837
- }
5838
- }
5750
+ addOrEditComment() {
5751
+ this.addOrEditCommentEvent.emit();
5839
5752
  }
5840
5753
  /**
5841
5754
  * @return {?}
5842
5755
  */
5843
- get comment() {
5844
- return this._comment;
5756
+ createBookmark() {
5757
+ this.createBookmarkEvent.emit(this.rectangle);
5758
+ this.rectangle = undefined;
5845
5759
  }
5846
5760
  /**
5847
- * @param {?} annotation
5848
5761
  * @return {?}
5849
5762
  */
5850
- set annotation(annotation) {
5851
- this._rectangle = annotation.rectangles
5763
+ setRectangle() {
5764
+ /** @type {?} */
5765
+ const rectangle = this.rectangles
5852
5766
  .reduce((/**
5853
5767
  * @param {?} prev
5854
5768
  * @param {?} current
5855
5769
  * @return {?}
5856
5770
  */
5857
5771
  (prev, current) => prev.y < current.y ? prev : current));
5858
- /** @type {?} */
5859
- const actualHeight = this._comment.pages[this.page].styles.height / this.zoom;
5772
+ this.rectangle = Object.assign({}, rectangle);
5860
5773
  switch (this.rotate) {
5861
5774
  case 90:
5862
- this.rectTop = this._rectangle.x;
5775
+ this.rectangle.width = rectangle.height;
5776
+ this.rectangle.height = rectangle.width;
5777
+ this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.y - rectangle.height;
5778
+ this.rectangle.y = rectangle.x;
5863
5779
  break;
5864
5780
  case 180:
5865
- this.rectTop = actualHeight - (this._rectangle.y + this._rectangle.height);
5781
+ this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.x - rectangle.width;
5782
+ this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.y - rectangle.height;
5866
5783
  break;
5867
5784
  case 270:
5868
- this.rectTop = actualHeight - (this._rectangle.x + this._rectangle.width);
5785
+ this.rectangle.width = rectangle.height;
5786
+ this.rectangle.height = rectangle.width;
5787
+ this.rectangle.x = rectangle.y;
5788
+ this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.x - rectangle.width;
5869
5789
  break;
5870
- default: this.rectTop = this._rectangle.y;
5871
5790
  }
5872
- this.rectLeft = this._rectangle.x;
5873
5791
  }
5874
5792
  /**
5875
5793
  * @return {?}
5876
5794
  */
5877
- get editable() {
5878
- return this._editable;
5795
+ popupTop() {
5796
+ /** @type {?} */
5797
+ const popupTop = this.rectangle.y * this.zoom - this.defaultHeight;
5798
+ return popupTop <= 0 ? this.defaultHeight : popupTop;
5879
5799
  }
5880
5800
  /**
5881
- * @param {?} updatedComment
5882
5801
  * @return {?}
5883
5802
  */
5884
- onCommentChange(updatedComment) {
5885
- this.hasUnsavedChanges = this.originalComment.substring(0, this.COMMENT_CHAR_LIMIT) !==
5886
- updatedComment.substring(0, this.COMMENT_CHAR_LIMIT);
5887
- this.commentService.onCommentChange(this.hasUnsavedChanges);
5803
+ popupLeft() {
5804
+ /** @type {?} */
5805
+ const popupLeft = (this.rectangle.x + (this.rectangle.width / 2)) * this.zoom - (this.defaultWidth / 2);
5806
+ if (popupLeft <= 0) {
5807
+ return 0;
5808
+ }
5809
+ else if (popupLeft >= this.pageWidth - this.defaultWidth) {
5810
+ return this.pageWidth - this.defaultWidth;
5811
+ }
5812
+ else {
5813
+ return popupLeft;
5814
+ }
5815
+ }
5816
+ }
5817
+ CtxToolbarComponent.decorators = [
5818
+ { type: Component, args: [{
5819
+ selector: 'mv-ctx-toolbar',
5820
+ template: "<div class=\"toolbar\" *ngIf=\"rectangle\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\">\n <button *ngIf=\"canHighlight\"\n type=\"button\" title=\"Highlight\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton aui__toolbar-button-highlight\"\n (mousedown)=\"createHighlight()\">\n <span>Highlight</span>\n </button>\n <button *ngIf=\"canDelete\"\n type=\"button\" title=\"Delete\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n (mousedown)=\"deleteHighlight()\">\n <span>Remove</span>\n </button>\n <button *ngIf=\"canComment\"\n type=\"button\" title=\"Comment\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-comment\"\n (mousedown)=\"addOrEditComment()\">\n <span>Comment</span></button>\n <button *ngIf=\"canBookmark\"\n type=\"button\" title=\"Bookmark\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-bookmark\"\n id=\"bookmarkButton\"\n (mousedown)=\"createBookmark()\">\n <span>Bookmark</span></button>\n <div class=\"arrow-down\">\n <div class=\"inner-triangle\"></div>\n </div>\n</div>\n"
5821
+ }] }
5822
+ ];
5823
+ /** @nocollapse */
5824
+ CtxToolbarComponent.ctorParameters = () => [];
5825
+ CtxToolbarComponent.propDecorators = {
5826
+ zoom: [{ type: Input }],
5827
+ rotate: [{ type: Input }],
5828
+ pageHeight: [{ type: Input }],
5829
+ pageWidth: [{ type: Input }],
5830
+ canHighlight: [{ type: Input }],
5831
+ canBookmark: [{ type: Input }],
5832
+ canComment: [{ type: Input }],
5833
+ canDelete: [{ type: Input }],
5834
+ createHighlightEvent: [{ type: Output }],
5835
+ deleteHighlightEvent: [{ type: Output }],
5836
+ addOrEditCommentEvent: [{ type: Output }],
5837
+ createBookmarkEvent: [{ type: Output }],
5838
+ rectangles: [{ type: Input }]
5839
+ };
5840
+
5841
+ /**
5842
+ * @fileoverview added by tsickle
5843
+ * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5844
+ */
5845
+ class CommentSetRenderService {
5846
+ /**
5847
+ * @param {?} commentComponents
5848
+ * @param {?} pageHeights
5849
+ * @param {?} rotate
5850
+ * @param {?} zoom
5851
+ * @return {?}
5852
+ */
5853
+ redrawComponents(commentComponents, pageHeights, rotate, zoom) {
5854
+ /** @type {?} */
5855
+ let prevComment;
5856
+ this.sortComponents(commentComponents, pageHeights, rotate, zoom).forEach((/**
5857
+ * @param {?} comment
5858
+ * @return {?}
5859
+ */
5860
+ (comment) => {
5861
+ this.adjustIfOverlapping(comment, prevComment, zoom);
5862
+ prevComment = comment;
5863
+ }));
5888
5864
  }
5889
5865
  /**
5866
+ * @param {?} commentComponents
5867
+ * @param {?} pageHeights
5868
+ * @param {?} rotate
5869
+ * @param {?} zoom
5890
5870
  * @return {?}
5891
5871
  */
5892
- deleteOrCancel() {
5893
- if (!this.editable) {
5894
- this.delete.emit(this._comment);
5895
- }
5896
- else {
5897
- this.hasUnsavedChanges = false;
5898
- this._editable = false;
5899
- this.fullComment = this.originalComment;
5900
- this.changes.emit(false);
5901
- if (!this.author && !this.fullComment) {
5902
- this.delete.emit(this._comment);
5903
- }
5904
- }
5872
+ sortComponents(commentComponents, pageHeights, rotate, zoom) {
5873
+ return commentComponents.sort((/**
5874
+ * @param {?} a
5875
+ * @param {?} b
5876
+ * @return {?}
5877
+ */
5878
+ (a, b) => {
5879
+ a.rectTop = this.top(a._rectangle, pageHeights[a.page - 1], rotate, zoom);
5880
+ b.rectTop = this.top(b._rectangle, pageHeights[b.page - 1], rotate, zoom);
5881
+ return this.processSort(a, b);
5882
+ }));
5905
5883
  }
5906
5884
  /**
5885
+ * @private
5886
+ * @param {?} comment
5887
+ * @param {?} prevComment
5888
+ * @param {?} zoom
5907
5889
  * @return {?}
5908
5890
  */
5909
- editOrSave() {
5910
- if (!this.editable) {
5911
- this._editable = true;
5912
- }
5913
- else {
5914
- this._comment.content = this.fullComment.substring(0, this.COMMENT_CHAR_LIMIT);
5915
- /** @type {?} */
5916
- const tags = this.tagsServices.getNewTags(this._comment.annotationId);
5891
+ adjustIfOverlapping(comment, prevComment, zoom) {
5892
+ if (prevComment) {
5917
5893
  /** @type {?} */
5918
- const payload = {
5919
- comment: this._comment,
5920
- tags
5921
- };
5922
- this.updated.emit(payload);
5923
- this.hasUnsavedChanges = false;
5924
- this._editable = false;
5925
- this.changes.emit(false);
5894
+ const endOfPrevComment = prevComment.commentTop + this.height(prevComment);
5895
+ if (comment.commentTop <= endOfPrevComment) {
5896
+ comment.rectTop = (endOfPrevComment - comment.totalPrevPagesHeight) / zoom;
5897
+ }
5926
5898
  }
5927
5899
  }
5928
5900
  /**
5901
+ * @private
5902
+ * @param {?} a
5903
+ * @param {?} b
5929
5904
  * @return {?}
5930
5905
  */
5931
- onCommentClick() {
5932
- if (!this.selected) {
5933
- this.selected = true;
5934
- this._editable = false;
5935
- this.commentClick.emit({ annotationId: this._comment.annotationId, editable: this._editable, selected: true });
5906
+ processSort(a, b) {
5907
+ if (this.onSameLine(a, b)) {
5908
+ return a.rectLeft >= b.rectLeft ? 1 : -1;
5936
5909
  }
5910
+ return a.commentTop >= b.commentTop ? 1 : -1;
5937
5911
  }
5938
5912
  /**
5913
+ * @private
5914
+ * @param {?} a
5915
+ * @param {?} b
5939
5916
  * @return {?}
5940
5917
  */
5941
- reRenderComments() {
5942
- this.renderComments.emit(this._comment);
5918
+ onSameLine(a, b) {
5919
+ return this.difference(a.commentTop, b.commentTop) === 0;
5920
+ }
5921
+ /**
5922
+ * @private
5923
+ * @param {?} rectangle
5924
+ * @param {?} height
5925
+ * @param {?} rotate
5926
+ * @param {?} zoom
5927
+ * @return {?}
5928
+ */
5929
+ top(rectangle, height, rotate, zoom) {
5930
+ /** @type {?} */
5931
+ const actualHeight = height / zoom;
5932
+ switch (rotate) {
5933
+ case 90: return rectangle.x;
5934
+ case 180: return actualHeight - (rectangle.y + rectangle.height);
5935
+ case 270: return actualHeight - (rectangle.x + rectangle.width);
5936
+ default: return rectangle.y;
5937
+ }
5943
5938
  }
5944
5939
  /**
5940
+ * @private
5941
+ * @param {?} element
5945
5942
  * @return {?}
5946
5943
  */
5947
- get commentTop() {
5948
- return this.totalPreviousPagesHeight + (this.rectTop * this.zoom);
5944
+ height(element) {
5945
+ return element.form.nativeElement.getBoundingClientRect().height;
5949
5946
  }
5950
5947
  /**
5948
+ * @private
5949
+ * @param {?} a
5950
+ * @param {?} b
5951
5951
  * @return {?}
5952
5952
  */
5953
- get height() {
5954
- return this.form.nativeElement.getBoundingClientRect().height / this.zoom;
5955
- }
5953
+ difference(a, b) { return Math.abs(a - b); }
5956
5954
  }
5957
- CommentComponent.decorators = [
5958
- { type: Component, args: [{
5959
- selector: 'mv-anno-comment',
5960
- template: "<div #form (click)=\"onCommentClick()\" class=\"aui-comment\"\n [style.top.px]=\"commentTop\"\n [style.zIndex]=\"selected ? 100 : 0\">\n <div id=\"detailsWrapper {{index}}\" class=\"aui-comment__header\">\n <span *ngIf=\"author && !editor\" class=\"aui-comment__author\">\n {{ author.forename }} {{ author.surname }}\n </span>\n <span *ngIf=\"editor\" class=\"aui-comment__author\">\n {{ editor.forename }} {{ editor.surname }}\n </span>\n <time [hidden]=\"!selected && !this.editable\" class=\"aui-comment__meta\">\n {{ lastUpdate | momentDate: 'd MMMM y h:mm a' }}\n </time>\n </div>\n <mv-tags\n [tagItems]=\"tagItems\"\n [userId]=\"createdBy\"\n [editable]=\"editable\"\n [annoId]=\"_comment.annotationId\">\n </mv-tags>\n <textarea *ngIf=\"selected && editable\"\n #editableComment\n mvTextAreaAutoExpand\n type=\"text\"\n required\n name=\"content\"\n [maxlength]=\"COMMENT_CHAR_LIMIT\"\n class=\"aui-comment__content form-control mimic-focus edit-mode expanded\"\n [(ngModel)]=\"fullComment\"\n (ngModelChange)=\"reRenderComments(); onCommentChange($event);\"\n aria-label=\"comment\">\n </textarea>\n <p *ngIf=\"!editable\"\n mvTextHighlight class=\"commentText\" [textToHighlight]=\"searchString\">\n {{ fullComment }}\n </p>\n <div *ngIf=\"selected || this.editable || (!fullComment.length && (tagItems && !tagItems.length))\"\n class=\"aui-comment__footer commentBtns\">\n <button class=\"govuk-button\"\n type=\"button\" role=\"button\"\n (click)=\"editOrSave()\">\n {{ !editable ? 'Edit' : 'Save' }}\n </button>\n <button type=\"button\" role=\"button\"\n class=\"govuk-button govuk-button--secondary\"\n (click)=\"deleteOrCancel()\">\n {{ !editable ? 'Delete' : 'Cancel' }}\n </button>\n </div>\n <span class=\"aui-comment__private\">private</span>\n</div>\n"
5961
- }] }
5962
- ];
5963
- /** @nocollapse */
5964
- CommentComponent.ctorParameters = () => [
5965
- { type: Store },
5966
- { type: CommentService },
5967
- { type: TagsServices }
5955
+ CommentSetRenderService.decorators = [
5956
+ { type: Injectable }
5968
5957
  ];
5969
- CommentComponent.propDecorators = {
5970
- commentClick: [{ type: Output }],
5971
- renderComments: [{ type: Output }],
5972
- delete: [{ type: Output }],
5973
- updated: [{ type: Output }],
5974
- changes: [{ type: Output }],
5975
- rotate: [{ type: Input }],
5976
- zoom: [{ type: Input }],
5977
- index: [{ type: Input }],
5978
- page: [{ type: Input }],
5979
- form: [{ type: ViewChild, args: ['form',] }],
5980
- editableComment: [{ type: ViewChild, args: ['editableComment',] }],
5981
- comment: [{ type: Input }],
5982
- annotation: [{ type: Input }]
5983
- };
5984
5958
 
5985
5959
  /**
5986
5960
  * @fileoverview added by tsickle
5987
5961
  * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5988
5962
  */
5989
- class CtxToolbarComponent {
5990
- constructor() {
5991
- this.createHighlightEvent = new EventEmitter();
5992
- this.deleteHighlightEvent = new EventEmitter();
5993
- this.addOrEditCommentEvent = new EventEmitter();
5994
- this.createBookmarkEvent = new EventEmitter();
5995
- this.defaultHeight = 70;
5996
- this.defaultWidth = 300;
5963
+ class CommentSetComponent {
5964
+ /**
5965
+ * @param {?} store
5966
+ * @param {?} commentService
5967
+ * @param {?} renderService
5968
+ * @param {?} toolbarEvents
5969
+ */
5970
+ constructor(store, commentService, renderService, toolbarEvents) {
5971
+ this.store = store;
5972
+ this.commentService = commentService;
5973
+ this.renderService = renderService;
5974
+ this.toolbarEvents = toolbarEvents;
5975
+ this.pageHeights = [];
5976
+ this.subscriptions = [];
5977
+ this.clearSelection();
5997
5978
  }
5998
5979
  /**
5999
- * @param {?} changes
6000
5980
  * @return {?}
6001
5981
  */
6002
- ngOnChanges(changes) {
6003
- this.setRectangle();
6004
- this.top = this.popupTop();
6005
- this.left = this.popupLeft();
5982
+ ngOnInit() {
5983
+ this.comments$ = this.store.pipe(select(getCommentsArray));
5984
+ this.annoEntities$ = this.store.pipe(select(getAnnotationEntities));
5985
+ this.subscriptions.push(this.toolbarEvents.commentsPanelVisible.subscribe((/**
5986
+ * @param {?} toggle
5987
+ * @return {?}
5988
+ */
5989
+ toggle => {
5990
+ this.redrawComments();
5991
+ this.showCommentsPanel = toggle;
5992
+ })));
5993
+ this.subscriptions.push(this.toolbarEvents.rotateSubject.subscribe((/**
5994
+ * @param {?} rotate
5995
+ * @return {?}
5996
+ */
5997
+ rotate => this.rotateDocument())));
6006
5998
  }
6007
5999
  /**
6008
- * @param {?} rectangles
6000
+ * @param {?} changes
6009
6001
  * @return {?}
6010
6002
  */
6011
- set rectangles(rectangles) {
6012
- if (rectangles) {
6013
- this._rectangles = rectangles;
6014
- this.setRectangle();
6003
+ ngOnChanges(changes) {
6004
+ if (changes.annotationSet) {
6005
+ this.commentService.setCommentSet(this);
6006
+ }
6007
+ if (changes.contentScrollTop) {
6008
+ if (this.container) {
6009
+ this.container.nativeElement.scrollTo(0, this.contentScrollTop);
6010
+ }
6015
6011
  }
6016
6012
  }
6017
6013
  /**
6018
6014
  * @return {?}
6019
6015
  */
6020
- get rectangles() {
6021
- return this._rectangles;
6016
+ ngOnDestroy() {
6017
+ if (this.subscriptions.length > 0) {
6018
+ this.subscriptions.forEach((/**
6019
+ * @param {?} subscription
6020
+ * @return {?}
6021
+ */
6022
+ subscription => subscription.unsubscribe()));
6023
+ }
6022
6024
  }
6023
6025
  /**
6026
+ * @param {?} annotationId
6024
6027
  * @return {?}
6025
6028
  */
6026
- createHighlight() {
6027
- this.createHighlightEvent.emit();
6028
- this.rectangle = undefined;
6029
+ onSelect(annotationId) {
6030
+ this.store.dispatch(new SelectedAnnotation(annotationId));
6029
6031
  }
6030
6032
  /**
6033
+ * @param {?} comment
6031
6034
  * @return {?}
6032
6035
  */
6033
- deleteHighlight() {
6034
- this.deleteHighlightEvent.emit();
6036
+ onCommentDelete(comment) {
6037
+ /** @type {?} */
6038
+ const annotation = this.annotationSet.annotations.find((/**
6039
+ * @param {?} anno
6040
+ * @return {?}
6041
+ */
6042
+ anno => anno.id === comment.annotationId));
6043
+ /** @type {?} */
6044
+ const comments = [];
6045
+ /** @type {?} */
6046
+ const annot = Object.assign({}, annotation, { comments });
6047
+ this.onAnnotationUpdate(annot);
6048
+ this.redrawComments();
6035
6049
  }
6036
6050
  /**
6037
6051
  * @return {?}
6038
6052
  */
6039
- addOrEditComment() {
6040
- this.addOrEditCommentEvent.emit();
6053
+ redrawComments() {
6054
+ setTimeout((/**
6055
+ * @return {?}
6056
+ */
6057
+ () => {
6058
+ /** @type {?} */
6059
+ const componentList = this.commentComponents.map((/**
6060
+ * @param {?} comment
6061
+ * @return {?}
6062
+ */
6063
+ comment => comment));
6064
+ this.renderService.redrawComponents(componentList, this.pageHeights, this.rotate, this.zoom);
6065
+ }), 0);
6041
6066
  }
6042
6067
  /**
6068
+ * @private
6043
6069
  * @return {?}
6044
6070
  */
6045
- createBookmark() {
6046
- this.createBookmarkEvent.emit(this.rectangle);
6047
- this.rectangle = undefined;
6071
+ rotateDocument() {
6072
+ if (this.panel) {
6073
+ this.panel.nativeElement.style.height = '0';
6074
+ }
6048
6075
  }
6049
6076
  /**
6077
+ * @param {?} payload
6050
6078
  * @return {?}
6051
6079
  */
6052
- setRectangle() {
6080
+ onCommentUpdate(payload) {
6053
6081
  /** @type {?} */
6054
- const rectangle = this.rectangles
6055
- .reduce((/**
6056
- * @param {?} prev
6057
- * @param {?} current
6082
+ const annotation = this.annotationSet.annotations.find((/**
6083
+ * @param {?} anno
6058
6084
  * @return {?}
6059
6085
  */
6060
- (prev, current) => prev.y < current.y ? prev : current));
6061
- this.rectangle = Object.assign({}, rectangle);
6062
- switch (this.rotate) {
6063
- case 90:
6064
- this.rectangle.width = rectangle.height;
6065
- this.rectangle.height = rectangle.width;
6066
- this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.y - rectangle.height;
6067
- this.rectangle.y = rectangle.x;
6068
- break;
6069
- case 180:
6070
- this.rectangle.x = (this.pageWidth / this.zoom) - rectangle.x - rectangle.width;
6071
- this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.y - rectangle.height;
6072
- break;
6073
- case 270:
6074
- this.rectangle.width = rectangle.height;
6075
- this.rectangle.height = rectangle.width;
6076
- this.rectangle.x = rectangle.y;
6077
- this.rectangle.y = (this.pageHeight / this.zoom) - rectangle.x - rectangle.width;
6078
- break;
6079
- }
6086
+ anno => anno.id === payload.comment.annotationId));
6087
+ /** @type {?} */
6088
+ const comments = [payload.comment];
6089
+ /** @type {?} */
6090
+ const tags = payload.tags;
6091
+ /** @type {?} */
6092
+ const annot = Object.assign({}, annotation, { comments,
6093
+ tags });
6094
+ this.onAnnotationUpdate(annot);
6080
6095
  }
6081
6096
  /**
6097
+ * @param {?} annotation
6082
6098
  * @return {?}
6083
6099
  */
6084
- popupTop() {
6085
- /** @type {?} */
6086
- const popupTop = this.rectangle.y * this.zoom - this.defaultHeight;
6087
- return popupTop <= 0 ? this.defaultHeight : popupTop;
6100
+ onAnnotationUpdate(annotation) {
6101
+ this.store.dispatch(new SaveAnnotation(annotation));
6088
6102
  }
6089
6103
  /**
6104
+ * @param {?} e
6090
6105
  * @return {?}
6091
6106
  */
6092
- popupLeft() {
6093
- /** @type {?} */
6094
- const popupLeft = (this.rectangle.x + (this.rectangle.width / 2)) * this.zoom - (this.defaultWidth / 2);
6095
- if (popupLeft <= 0) {
6096
- return 0;
6097
- }
6098
- else if (popupLeft >= this.pageWidth - this.defaultWidth) {
6099
- return this.pageWidth - this.defaultWidth;
6100
- }
6101
- else {
6102
- return popupLeft;
6107
+ onContainerClick(e) {
6108
+ if (e.path && e.path[0] === this.panel.nativeElement) {
6109
+ this.clearSelection();
6103
6110
  }
6104
6111
  }
6112
+ /**
6113
+ * @return {?}
6114
+ */
6115
+ clearSelection() {
6116
+ this.store.dispatch(new SelectedAnnotation({ annotationId: '', editable: false, selected: false }));
6117
+ }
6118
+ /**
6119
+ * @return {?}
6120
+ */
6121
+ allCommentsSaved() {
6122
+ this.commentService.allCommentsSaved();
6123
+ }
6105
6124
  }
6106
- CtxToolbarComponent.decorators = [
6125
+ CommentSetComponent.decorators = [
6107
6126
  { type: Component, args: [{
6108
- selector: 'mv-ctx-toolbar',
6109
- template: "<div class=\"toolbar\" *ngIf=\"rectangle\"\n [style.top.px]=\"top\"\n [style.left.px]=\"left\">\n <button *ngIf=\"canHighlight\"\n type=\"button\" title=\"Highlight\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton aui__toolbar-button-highlight\"\n (mousedown)=\"createHighlight()\">\n <span>Highlight</span>\n </button>\n <button *ngIf=\"canDelete\"\n type=\"button\" title=\"Delete\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n (mousedown)=\"deleteHighlight()\">\n <span>Remove</span>\n </button>\n <button *ngIf=\"canComment\"\n type=\"button\" title=\"Comment\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-comment\"\n (mousedown)=\"addOrEditComment()\">\n <span>Comment</span></button>\n <button *ngIf=\"canBookmark\"\n type=\"button\" title=\"Bookmark\"\n class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton aui__toolbar-button-bookmark\"\n id=\"bookmarkButton\"\n (mousedown)=\"createBookmark()\">\n <span>Bookmark</span></button>\n <div class=\"arrow-down\">\n <div class=\"inner-triangle\"></div>\n </div>\n</div>\n"
6127
+ selector: 'mv-comment-set',
6128
+ template: "<div #container [ngClass]=\"{'comments': showCommentsPanel}\">\n <div #panel [ngClass]=\"{ 'comments-panel comment-container': true, 'expanded': showCommentsPanel }\"\n [style.height.px]=\"height\"\n (click)=\"onContainerClick($event)\">\n <ng-container *ngFor=\"let comment of (comments$ | async); let i = index;\">\n <mv-anno-comment\n [ngStyle]=\"showCommentsPanel ? {} : {'display':'none'}\"\n #commentComponent\n (commentClick)=\"onSelect($event)\"\n (delete)=\"onCommentDelete($event)\"\n (updated)=\"onCommentUpdate($event)\"\n (changes)=\"allCommentsSaved()\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [index]=\"i\"\n [page]=\"comment.page\"\n [comment]=\"comment\"\n [annotation]=\"(annoEntities$ | async)[comment.annotationId]\"\n (renderComments)=\"redrawComments()\">\n </mv-anno-comment>\n </ng-container>\n </div>\n</div>\n"
6110
6129
  }] }
6111
6130
  ];
6112
6131
  /** @nocollapse */
6113
- CtxToolbarComponent.ctorParameters = () => [];
6114
- CtxToolbarComponent.propDecorators = {
6132
+ CommentSetComponent.ctorParameters = () => [
6133
+ { type: Store },
6134
+ { type: CommentService },
6135
+ { type: CommentSetRenderService },
6136
+ { type: ToolbarEventService }
6137
+ ];
6138
+ CommentSetComponent.propDecorators = {
6139
+ annotationSet: [{ type: Input }],
6115
6140
  zoom: [{ type: Input }],
6116
6141
  rotate: [{ type: Input }],
6117
- pageHeight: [{ type: Input }],
6118
- pageWidth: [{ type: Input }],
6119
- canHighlight: [{ type: Input }],
6120
- canBookmark: [{ type: Input }],
6121
- canComment: [{ type: Input }],
6122
- canDelete: [{ type: Input }],
6123
- createHighlightEvent: [{ type: Output }],
6124
- deleteHighlightEvent: [{ type: Output }],
6125
- addOrEditCommentEvent: [{ type: Output }],
6126
- createBookmarkEvent: [{ type: Output }],
6127
- rectangles: [{ type: Input }]
6142
+ height: [{ type: Input }],
6143
+ pageHeights: [{ type: Input }],
6144
+ contentScrollTop: [{ type: Input }],
6145
+ container: [{ type: ViewChild, args: ['container',] }],
6146
+ panel: [{ type: ViewChild, args: ['panel',] }],
6147
+ commentComponents: [{ type: ViewChildren, args: ['commentComponent',] }]
6128
6148
  };
6129
6149
 
6130
6150
  /**
@@ -6469,7 +6489,7 @@ class CommentSetHeaderComponent {
6469
6489
  this.toolbarEvents = toolbarEvents;
6470
6490
  this.showCommentSummaryDialog = new EventEmitter();
6471
6491
  this.tabs = [];
6472
- this.tabSelected = 'comments';
6492
+ this.tabSelected = '';
6473
6493
  }
6474
6494
  /**
6475
6495
  * @return {?}
@@ -6510,6 +6530,12 @@ class CommentSetHeaderComponent {
6510
6530
  selectTab(tab) {
6511
6531
  this.tabSelected = tab !== this.tabSelected ? tab : undefined;
6512
6532
  }
6533
+ /**
6534
+ * @return {?}
6535
+ */
6536
+ toggleCommentsPanel() {
6537
+ this.toolbarEvents.toggleCommentsPanel(!this.toolbarEvents.commentsPanelVisible.getValue());
6538
+ }
6513
6539
  /**
6514
6540
  * @return {?}
6515
6541
  */
@@ -6520,7 +6546,7 @@ class CommentSetHeaderComponent {
6520
6546
  CommentSetHeaderComponent.decorators = [
6521
6547
  { type: Component, args: [{
6522
6548
  selector: 'mv-comment-set-header',
6523
- template: "<div class=\"govuk-tabs commentSummaryHeader\" [ngClass]=\"{'icp-mode': toolbarEvents.icp.enabled | async}\" data-module=\"govuk-tabs\">\n <ul class=\"govuk-tabs__list\">\n <li *ngFor=\"let tab of tabs\" class=\"govuk-tabs__list-item govuk-tabs__list-item\"\n [ngClass]=\"{'govuk-tabs__list-item--selected': tabSelected === tab.label}\">\n <a (click)=\"selectTab(tab.label)\" [routerLink]=\"\" [ngClass]=\"{'govuk-tabs__list-item--filtered': tab.isFiltered}\"\n class=\"govuk-tabs__tab\">\n {{ tab.label | titlecase }}\n </a>\n\n </li>\n </ul>\n <div class=\"govuk-tabs__panel\" [hidden]=\"!tabSelected\">\n <ng-container *ngIf=\"tabSelected === 'comments'\">\n <div style=\"width: 100%\">\n <div class=\"hmcts-banner\" *ngIf=\"navigationList?.length === 0\">\n <svg class=\"hmcts-banner__icon\" fill=\"currentColor\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 25 25\" height=\"25\" width=\"25\">\n <path d=\"M13.7,18.5h-2.4v-2.4h2.4V18.5z M12.5,13.7c-0.7,0-1.2-0.5-1.2-1.2V7.7c0-0.7,0.5-1.2,1.2-1.2s1.2,0.5,1.2,1.2v4.8\nC13.7,13.2,13.2,13.7,12.5,13.7z M12.5,0.5c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S19.1,0.5,12.5,0.5z\" /></svg>\n <div class=\"hmcts-banner__message\">\n <span class=\"hmcts-banner__assistive\">information</span>\n Select text to add a comment or highlight.\n </div>\n </div>\n <button type=\"button\" class=\"govuk-button\"\n id=\"commentSummary\" tabindex=\"0\"\n data-l10n-id=\"commentSummary\"\n title=\"Open collate summary\"\n (click)=\"toggleCommentsSummary()\">Collate comments</button>\n </div>\n <ng-container *ngIf=\"navigationList?.length > 0\">\n <mv-comments-navigate\n [annotationList]=\"navigationList\">\n </mv-comments-navigate>\n </ng-container>\n <p class=\"aui-comment__private-text\">\n <span class=\"aui-comment__private\">private</span>\n All comments can only be seen by you\n </p>\n </ng-container>\n <div [hidden]=\"tabSelected !== 'filter'\">\n <div class=\"govuk-tabs__panel--container\">\n <mv-comment-filter></mv-comment-filter>\n <mv-comments-navigate\n *ngIf=\"navigationList?.length > 0\"\n [annotationList]=\"navigationList\">\n </mv-comments-navigate>\n </div>\n </div>\n\n <div [hidden]=\"tabSelected !== 'search'\">\n <mv-comment-search [annotations]=\"navigationList\"></mv-comment-search>\n </div>\n </div>\n</div>\n",
6549
+ template: "<div class=\"govuk-tabs commentSummaryHeader\" [ngClass]=\"{'icp-mode': toolbarEvents.icp.enabled | async}\" data-module=\"govuk-tabs\">\n <ul class=\"govuk-tabs__list\">\n <li *ngFor=\"let tab of tabs\" class=\"govuk-tabs__list-item govuk-tabs__list-item\"\n [ngClass]=\"{'govuk-tabs__list-item--selected': tabSelected === tab.label}\">\n <a (click)=\"selectTab(tab.label)\" [routerLink]=\"\" [ngClass]=\"{'govuk-tabs__list-item--filtered': tab.isFiltered}\"\n class=\"govuk-tabs__tab\">\n {{ tab.label | titlecase }}\n </a>\n </li>\n <li>\n <button id=\"mvCloseBtn\" #mvCloseBtn class=\"mv-button commentSummaryHeader-button--close\"\n title=\"Close Comments\" (click)=\"toggleCommentsPanel()\">\n </button>\n </li>\n </ul>\n <div class=\"govuk-tabs__panel\" [hidden]=\"!tabSelected\">\n <ng-container *ngIf=\"tabSelected === 'comments'\">\n <div style=\"width: 100%\">\n <div class=\"hmcts-banner\" *ngIf=\"navigationList?.length === 0\">\n <svg class=\"hmcts-banner__icon\" fill=\"currentColor\" focusable=\"false\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 25 25\" height=\"25\" width=\"25\">\n <path d=\"M13.7,18.5h-2.4v-2.4h2.4V18.5z M12.5,13.7c-0.7,0-1.2-0.5-1.2-1.2V7.7c0-0.7,0.5-1.2,1.2-1.2s1.2,0.5,1.2,1.2v4.8\nC13.7,13.2,13.2,13.7,12.5,13.7z M12.5,0.5c-6.6,0-12,5.4-12,12s5.4,12,12,12s12-5.4,12-12S19.1,0.5,12.5,0.5z\" /></svg>\n <div class=\"hmcts-banner__message\">\n <span class=\"hmcts-banner__assistive\">information</span>\n Select text to add a comment or highlight.\n </div>\n </div>\n <button type=\"button\" class=\"govuk-button\"\n id=\"commentSummary\" tabindex=\"0\"\n data-l10n-id=\"commentSummary\"\n title=\"Open collate summary\"\n (click)=\"toggleCommentsSummary()\">Collate comments</button>\n </div>\n <ng-container *ngIf=\"navigationList?.length > 0\">\n <mv-comments-navigate\n [annotationList]=\"navigationList\">\n </mv-comments-navigate>\n </ng-container>\n <p class=\"aui-comment__private-text\">\n <span class=\"aui-comment__private\">private</span>\n All comments can only be seen by you\n </p>\n </ng-container>\n <div [hidden]=\"tabSelected !== 'filter'\">\n <div class=\"govuk-tabs__panel--container\">\n <mv-comment-filter></mv-comment-filter>\n <mv-comments-navigate\n *ngIf=\"navigationList?.length > 0\"\n [annotationList]=\"navigationList\">\n </mv-comments-navigate>\n </div>\n </div>\n\n <div [hidden]=\"tabSelected !== 'search'\">\n <mv-comment-search [annotations]=\"navigationList\"></mv-comment-search>\n </div>\n </div>\n</div>\n",
6524
6550
  encapsulation: ViewEncapsulation.None
6525
6551
  }] }
6526
6552
  ];
@@ -9609,7 +9635,12 @@ class ConvertibleContentViewerComponent {
9609
9635
  * @return {?}
9610
9636
  */
9611
9637
  extractDMStoreDocId(url) {
9612
- url = url.includes('/documents/') ? url.split('/documents/')[1] : url;
9638
+ if (url.includes('/documents/')) {
9639
+ url = url.split('/documents/')[1];
9640
+ }
9641
+ else if (url.includes('/documentsv2/')) {
9642
+ url = url.split('/documentsv2/')[1];
9643
+ }
9613
9644
  return url.replace('/binary', '');
9614
9645
  }
9615
9646
  }