@hmcts/media-viewer 4.1.8-exui-2821-1 → 4.1.8-exui-2600

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 (37) hide show
  1. package/assets/sass/box-highlight.scss +38 -0
  2. package/esm2022/lib/annotations/annotation-set/annotation-create/box-highlight-create/box-highlight-create.component.mjs +74 -19
  3. package/esm2022/lib/annotations/annotation-set/annotation-create/box-highlight-create/keyboard-box-draw.directive.mjs +258 -0
  4. package/esm2022/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.service.mjs +4 -4
  5. package/esm2022/lib/annotations/annotation-set/annotation-view/annotation-view.component.mjs +37 -3
  6. package/esm2022/lib/annotations/annotation-set/annotation-view/rectangle/keyboard-box-move.directive.mjs +122 -0
  7. package/esm2022/lib/annotations/annotation-set/annotation-view/rectangle/rectangle.component.mjs +39 -3
  8. package/esm2022/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.mjs +3 -3
  9. package/esm2022/lib/annotations/annotations.module.mjs +9 -3
  10. package/esm2022/lib/icp/confirm-exit/confirm-action-dialog.component.mjs +5 -13
  11. package/esm2022/lib/store/actions/annotation.actions.mjs +3 -2
  12. package/esm2022/lib/store/effects/annotation.effects.mjs +14 -3
  13. package/fesm2022/hmcts-media-viewer.mjs +547 -44
  14. package/fesm2022/hmcts-media-viewer.mjs.map +1 -1
  15. package/lib/annotations/annotation-set/annotation-create/box-highlight-create/box-highlight-create.component.d.ts +16 -2
  16. package/lib/annotations/annotation-set/annotation-create/box-highlight-create/box-highlight-create.component.d.ts.map +1 -1
  17. package/lib/annotations/annotation-set/annotation-create/box-highlight-create/keyboard-box-draw.directive.d.ts +59 -0
  18. package/lib/annotations/annotation-set/annotation-create/box-highlight-create/keyboard-box-draw.directive.d.ts.map +1 -0
  19. package/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.service.d.ts +1 -1
  20. package/lib/annotations/annotation-set/annotation-create/highlight-create/highlight-create.service.d.ts.map +1 -1
  21. package/lib/annotations/annotation-set/annotation-view/annotation-view.component.d.ts +8 -2
  22. package/lib/annotations/annotation-set/annotation-view/annotation-view.component.d.ts.map +1 -1
  23. package/lib/annotations/annotation-set/annotation-view/rectangle/keyboard-box-move.directive.d.ts +27 -0
  24. package/lib/annotations/annotation-set/annotation-view/rectangle/keyboard-box-move.directive.d.ts.map +1 -0
  25. package/lib/annotations/annotation-set/annotation-view/rectangle/rectangle.component.d.ts +10 -1
  26. package/lib/annotations/annotation-set/annotation-view/rectangle/rectangle.component.d.ts.map +1 -1
  27. package/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.d.ts +2 -1
  28. package/lib/annotations/annotation-set/metadata-layer/metadata-layer.component.d.ts.map +1 -1
  29. package/lib/annotations/annotations.module.d.ts +13 -11
  30. package/lib/annotations/annotations.module.d.ts.map +1 -1
  31. package/lib/icp/confirm-exit/confirm-action-dialog.component.d.ts +1 -4
  32. package/lib/icp/confirm-exit/confirm-action-dialog.component.d.ts.map +1 -1
  33. package/lib/store/actions/annotation.actions.d.ts +2 -1
  34. package/lib/store/actions/annotation.actions.d.ts.map +1 -1
  35. package/lib/store/effects/annotation.effects.d.ts +1 -0
  36. package/lib/store/effects/annotation.effects.d.ts.map +1 -1
  37. package/package.json +1 -1
@@ -8,8 +8,8 @@ import * as i2 from '@angular/forms';
8
8
  import { UntypedFormControl, FormGroup, FormControl, Validators, FormsModule, ReactiveFormsModule } from '@angular/forms';
9
9
  import * as i1$1 from '@angular/common/http';
10
10
  import { HttpClientModule } from '@angular/common/http';
11
- import { BehaviorSubject, Subject, of, combineLatest, asyncScheduler } from 'rxjs';
12
- import { take, distinctUntilChanged, filter, auditTime, tap, throttleTime, map, catchError, switchMap, concatMap, exhaustMap, withLatestFrom } from 'rxjs/operators';
11
+ import { BehaviorSubject, Subject, of, combineLatest, debounceTime as debounceTime$1, asyncScheduler } from 'rxjs';
12
+ import { take, distinctUntilChanged, filter, auditTime, tap, debounceTime, throttleTime, map, catchError, switchMap, concatMap, exhaustMap, withLatestFrom } from 'rxjs/operators';
13
13
  import * as i1 from '@ngrx/store';
14
14
  import { createFeatureSelector, createSelector, select, StoreModule } from '@ngrx/store';
15
15
  import { v4 } from 'uuid';
@@ -433,8 +433,9 @@ class SaveAnnotationSetFail {
433
433
  }
434
434
  }
435
435
  class SaveAnnotation {
436
- constructor(payload) {
436
+ constructor(payload, autoSelect) {
437
437
  this.payload = payload;
438
+ this.autoSelect = autoSelect;
438
439
  this.type = SAVE_ANNOTATION;
439
440
  }
440
441
  }
@@ -2715,10 +2716,10 @@ class HighlightCreateService {
2715
2716
  this.toolBarEvents = toolBarEvents;
2716
2717
  this.store = store;
2717
2718
  }
2718
- saveAnnotation(rectangles, page) {
2719
+ saveAnnotation(rectangles, page, annotationId) {
2719
2720
  this.store.pipe(select(getDocumentIdSetId), take(1)).subscribe(anoSetDocId => {
2720
2721
  const anno = {
2721
- id: v4(),
2722
+ id: annotationId || v4(),
2722
2723
  color: 'FFFF00',
2723
2724
  comments: [],
2724
2725
  page: page,
@@ -2733,7 +2734,7 @@ class HighlightCreateService {
2733
2734
  lastModifiedDate: '',
2734
2735
  tags: [],
2735
2736
  };
2736
- this.store.dispatch(new SaveAnnotation(anno));
2737
+ this.store.dispatch(new SaveAnnotation(anno, !!annotationId));
2737
2738
  });
2738
2739
  }
2739
2740
  saveAnnotationSet(searchRectangles) {
@@ -3889,6 +3890,262 @@ const getBookmarksPerPage = createSelector(getPages, getBookmarkPages, (pages, p
3889
3890
  }
3890
3891
  });
3891
3892
 
3893
+ class KeyboardBoxDrawDirective {
3894
+ set enabled(value) {
3895
+ const wasEnabled = this._enabled;
3896
+ this._enabled = value;
3897
+ if (value && !wasEnabled && KeyboardBoxDrawDirective.lastInteractionWasKeyboard && !this.showCursor) {
3898
+ this.initializeCursorForKeyboard();
3899
+ }
3900
+ }
3901
+ get enabled() {
3902
+ return this._enabled;
3903
+ }
3904
+ static { this.lastInteractionWasKeyboard = false; }
3905
+ constructor(elementRef) {
3906
+ this.elementRef = elementRef;
3907
+ this._enabled = false;
3908
+ this.minBoxSize = 10;
3909
+ this.incrementSmall = 1;
3910
+ this.incrementMedium = 5;
3911
+ this.incrementLarge = 10;
3912
+ this.drawingStarted = new EventEmitter();
3913
+ this.drawingUpdated = new EventEmitter();
3914
+ this.drawingConfirmed = new EventEmitter();
3915
+ this.drawingCancelled = new EventEmitter();
3916
+ this.cursorPositionChanged = new EventEmitter();
3917
+ this.isDrawing = false;
3918
+ this.showCursor = false;
3919
+ if (typeof window !== 'undefined') {
3920
+ window.addEventListener('keydown', KeyboardBoxDrawDirective.onGlobalKeyDown, { capture: true });
3921
+ window.addEventListener('mousedown', KeyboardBoxDrawDirective.onGlobalMouseDown, { capture: true });
3922
+ }
3923
+ }
3924
+ static onGlobalKeyDown() {
3925
+ KeyboardBoxDrawDirective.lastInteractionWasKeyboard = true;
3926
+ }
3927
+ static onGlobalMouseDown() {
3928
+ KeyboardBoxDrawDirective.lastInteractionWasKeyboard = false;
3929
+ }
3930
+ ngOnDestroy() {
3931
+ this.cleanup();
3932
+ }
3933
+ initializeCursorForKeyboard() {
3934
+ if (this.enabled && !this.showCursor && !this.isDrawing) {
3935
+ const rect = this.elementRef.nativeElement.getBoundingClientRect();
3936
+ if (rect.width > 0 && rect.height > 0) {
3937
+ this.cursorX = rect.width / 2;
3938
+ this.cursorY = rect.height / 2;
3939
+ this.showCursor = true;
3940
+ this.emitCursorPosition();
3941
+ }
3942
+ }
3943
+ }
3944
+ onKeyDown(event) {
3945
+ if (!this.enabled) {
3946
+ return;
3947
+ }
3948
+ if (event.key === 'Enter') {
3949
+ event.preventDefault();
3950
+ event.stopPropagation();
3951
+ if (!this.isDrawing) {
3952
+ this.startDrawing();
3953
+ }
3954
+ else {
3955
+ this.confirmDrawing();
3956
+ }
3957
+ return;
3958
+ }
3959
+ if (event.key === 'Escape') {
3960
+ event.preventDefault();
3961
+ event.stopPropagation();
3962
+ if (this.isDrawing) {
3963
+ this.cancelDrawing();
3964
+ }
3965
+ else if (this.showCursor) {
3966
+ this.hideCursor();
3967
+ }
3968
+ return;
3969
+ }
3970
+ if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
3971
+ event.preventDefault();
3972
+ event.stopPropagation();
3973
+ if (this.isDrawing) {
3974
+ this.resizeBox(event);
3975
+ }
3976
+ else {
3977
+ this.moveCursor(event);
3978
+ }
3979
+ }
3980
+ }
3981
+ onBlur() {
3982
+ if (this.showCursor && !this.isDrawing) {
3983
+ this.hideCursor();
3984
+ }
3985
+ }
3986
+ moveCursor(event) {
3987
+ const increment = event.shiftKey ? this.incrementLarge : this.incrementMedium;
3988
+ if (!this.showCursor) {
3989
+ const rect = this.elementRef.nativeElement.getBoundingClientRect();
3990
+ this.cursorX = rect.width / 2;
3991
+ this.cursorY = rect.height / 2;
3992
+ this.showCursor = true;
3993
+ this.emitCursorPosition();
3994
+ return;
3995
+ }
3996
+ const rect = this.elementRef.nativeElement.getBoundingClientRect();
3997
+ switch (event.key) {
3998
+ case 'ArrowUp':
3999
+ this.cursorY = Math.max(0, this.cursorY - increment);
4000
+ break;
4001
+ case 'ArrowDown':
4002
+ this.cursorY = Math.min(rect.height, this.cursorY + increment);
4003
+ break;
4004
+ case 'ArrowLeft':
4005
+ this.cursorX = Math.max(0, this.cursorX - increment);
4006
+ break;
4007
+ case 'ArrowRight':
4008
+ this.cursorX = Math.min(rect.width, this.cursorX + increment);
4009
+ break;
4010
+ }
4011
+ this.emitCursorPosition();
4012
+ }
4013
+ startDrawing() {
4014
+ let startX;
4015
+ let startY;
4016
+ if (this.showCursor) {
4017
+ startX = this.cursorX;
4018
+ startY = this.cursorY;
4019
+ this.showCursor = false;
4020
+ this.emitCursorPosition();
4021
+ }
4022
+ else {
4023
+ // default to center
4024
+ const rect = this.elementRef.nativeElement.getBoundingClientRect();
4025
+ startX = rect.width / 2;
4026
+ startY = rect.height / 2;
4027
+ }
4028
+ this.isDrawing = true;
4029
+ this.drawStartX = startX;
4030
+ this.drawStartY = startY;
4031
+ this.currentWidth = this.minBoxSize;
4032
+ this.currentHeight = this.minBoxSize;
4033
+ this.emitDrawingStarted();
4034
+ }
4035
+ resizeBox(event) {
4036
+ const increment = event.shiftKey ? this.incrementLarge : this.incrementSmall;
4037
+ const rect = this.elementRef.nativeElement.getBoundingClientRect();
4038
+ switch (event.key) {
4039
+ case 'ArrowRight':
4040
+ const maxWidth = rect.width - this.drawStartX;
4041
+ this.currentWidth = Math.min(maxWidth, this.currentWidth + increment);
4042
+ break;
4043
+ case 'ArrowLeft':
4044
+ this.currentWidth = Math.max(this.minBoxSize, this.currentWidth - increment);
4045
+ break;
4046
+ case 'ArrowDown':
4047
+ const maxHeight = rect.height - this.drawStartY;
4048
+ this.currentHeight = Math.min(maxHeight, this.currentHeight + increment);
4049
+ break;
4050
+ case 'ArrowUp':
4051
+ this.currentHeight = Math.max(this.minBoxSize, this.currentHeight - increment);
4052
+ break;
4053
+ }
4054
+ this.emitDrawingUpdated();
4055
+ }
4056
+ confirmDrawing() {
4057
+ this.emitDrawingConfirmed();
4058
+ this.cleanup();
4059
+ }
4060
+ cancelDrawing() {
4061
+ this.drawingCancelled.emit();
4062
+ this.cleanup();
4063
+ }
4064
+ hideCursor() {
4065
+ this.showCursor = false;
4066
+ this.emitCursorPosition();
4067
+ }
4068
+ cleanup() {
4069
+ this.isDrawing = false;
4070
+ this.showCursor = false;
4071
+ this.cursorX = undefined;
4072
+ this.cursorY = undefined;
4073
+ this.drawStartX = undefined;
4074
+ this.drawStartY = undefined;
4075
+ this.currentWidth = undefined;
4076
+ this.currentHeight = undefined;
4077
+ }
4078
+ emitCursorPosition() {
4079
+ this.cursorPositionChanged.emit({
4080
+ x: this.cursorX,
4081
+ y: this.cursorY,
4082
+ visible: this.showCursor
4083
+ });
4084
+ }
4085
+ emitDrawingStarted() {
4086
+ this.drawingStarted.emit({
4087
+ startX: this.drawStartX,
4088
+ startY: this.drawStartY,
4089
+ width: this.currentWidth,
4090
+ height: this.currentHeight
4091
+ });
4092
+ }
4093
+ emitDrawingUpdated() {
4094
+ this.drawingUpdated.emit({
4095
+ startX: this.drawStartX,
4096
+ startY: this.drawStartY,
4097
+ width: this.currentWidth,
4098
+ height: this.currentHeight
4099
+ });
4100
+ }
4101
+ emitDrawingConfirmed() {
4102
+ this.drawingConfirmed.emit({
4103
+ startX: this.drawStartX,
4104
+ startY: this.drawStartY,
4105
+ width: this.currentWidth,
4106
+ height: this.currentHeight
4107
+ });
4108
+ }
4109
+ reset() {
4110
+ this.cleanup();
4111
+ this.emitCursorPosition();
4112
+ }
4113
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KeyboardBoxDrawDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
4114
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: KeyboardBoxDrawDirective, selector: "[mvKeyboardBoxDraw]", inputs: { enabled: "enabled", minBoxSize: "minBoxSize", incrementSmall: "incrementSmall", incrementMedium: "incrementMedium", incrementLarge: "incrementLarge" }, outputs: { drawingStarted: "drawingStarted", drawingUpdated: "drawingUpdated", drawingConfirmed: "drawingConfirmed", drawingCancelled: "drawingCancelled", cursorPositionChanged: "cursorPositionChanged" }, host: { listeners: { "keydown": "onKeyDown($event)", "blur": "onBlur()" } }, ngImport: i0 }); }
4115
+ }
4116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KeyboardBoxDrawDirective, decorators: [{
4117
+ type: Directive,
4118
+ args: [{
4119
+ selector: '[mvKeyboardBoxDraw]'
4120
+ }]
4121
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { enabled: [{
4122
+ type: Input
4123
+ }], minBoxSize: [{
4124
+ type: Input
4125
+ }], incrementSmall: [{
4126
+ type: Input
4127
+ }], incrementMedium: [{
4128
+ type: Input
4129
+ }], incrementLarge: [{
4130
+ type: Input
4131
+ }], drawingStarted: [{
4132
+ type: Output
4133
+ }], drawingUpdated: [{
4134
+ type: Output
4135
+ }], drawingConfirmed: [{
4136
+ type: Output
4137
+ }], drawingCancelled: [{
4138
+ type: Output
4139
+ }], cursorPositionChanged: [{
4140
+ type: Output
4141
+ }], onKeyDown: [{
4142
+ type: HostListener,
4143
+ args: ['keydown', ['$event']]
4144
+ }], onBlur: [{
4145
+ type: HostListener,
4146
+ args: ['blur']
4147
+ }] } });
4148
+
3892
4149
  class BoxHighlightCreateComponent {
3893
4150
  constructor(toolbarEvents, highlightService) {
3894
4151
  this.toolbarEvents = toolbarEvents;
@@ -3897,6 +4154,8 @@ class BoxHighlightCreateComponent {
3897
4154
  this.drawStartX = -1;
3898
4155
  this.drawStartY = -1;
3899
4156
  this.backgroundColor = 'none';
4157
+ this.keyboardDrawingMode = false;
4158
+ this.showCursor = false;
3900
4159
  this.subscriptions = [];
3901
4160
  }
3902
4161
  ngOnInit() {
@@ -3904,6 +4163,14 @@ class BoxHighlightCreateComponent {
3904
4163
  this.toolbarEvents.drawModeSubject.subscribe(drawMode => {
3905
4164
  this.defaultHeight = drawMode ? '100%' : '0px';
3906
4165
  this.defaultWidth = drawMode ? '100%' : '0px';
4166
+ this.drawMode = drawMode;
4167
+ if (drawMode) {
4168
+ setTimeout(() => {
4169
+ if (this.drawingContainer?.nativeElement && this.isElementInViewport(this.drawingContainer.nativeElement)) {
4170
+ this.drawingContainer.nativeElement.focus();
4171
+ }
4172
+ }, 100);
4173
+ }
3907
4174
  }),
3908
4175
  this.toolbarEvents.redactWholePage.subscribe(() => {
3909
4176
  this.wholePage = true;
@@ -3915,13 +4182,20 @@ class BoxHighlightCreateComponent {
3915
4182
  subscription.unsubscribe();
3916
4183
  });
3917
4184
  }
4185
+ isElementInViewport(el) {
4186
+ const rect = el.getBoundingClientRect();
4187
+ const windowHeight = (window.innerHeight || document.documentElement.clientHeight);
4188
+ const windowWidth = (window.innerWidth || document.documentElement.clientWidth);
4189
+ const verticallyVisible = rect.bottom > 0 && rect.top < windowHeight;
4190
+ const horizontallyVisible = rect.right > 0 && rect.left < windowWidth;
4191
+ return verticallyVisible && horizontallyVisible;
4192
+ }
3918
4193
  initHighlight(event) {
3919
4194
  if (this.wholePage) {
3920
4195
  this.highlightPage();
3921
4196
  return;
3922
4197
  }
3923
4198
  const rect = HtmlTemplatesHelper.getAdjustedBoundingRect(event.target), offsetX = event.clientX - rect.left, offsetY = event.clientY - rect.top;
3924
- console.log(`initHighlight: rect=${JSON.stringify(rect)}, clientX=${event.clientX}, clientY=${event.clientY}, offsetX=${offsetX}, offsetY=${offsetY}`);
3925
4199
  this.position = 'absolute';
3926
4200
  this.backgroundColor = 'yellow';
3927
4201
  this.drawStartX = offsetX;
@@ -3931,18 +4205,7 @@ class BoxHighlightCreateComponent {
3931
4205
  this.width = 50;
3932
4206
  this.top = this.drawStartY;
3933
4207
  this.left = this.drawStartX;
3934
- switch (this.rotate) {
3935
- case 90:
3936
- this.top = this.drawStartY - this.height;
3937
- break;
3938
- case 180:
3939
- this.top = this.drawStartY - this.height;
3940
- this.left = this.drawStartX - this.width;
3941
- break;
3942
- case 270:
3943
- this.left = this.drawStartX - this.width;
3944
- break;
3945
- }
4208
+ this.adjustForRotation();
3946
4209
  }
3947
4210
  updateHighlight(event) {
3948
4211
  const rect = HtmlTemplatesHelper.getAdjustedBoundingRect(event.target, false), offsetX = event.clientX - rect.left, offsetY = event.clientY - rect.top;
@@ -3957,12 +4220,56 @@ class BoxHighlightCreateComponent {
3957
4220
  if (this.height / this.zoom > 5 || this.width / this.zoom > 5) {
3958
4221
  let rectangle = this.highlightService
3959
4222
  .applyRotation(this.pageHeight, this.pageWidth, this.height, this.width, this.top, this.left, this.rotate, this.zoom);
3960
- rectangle = { id: v4(), ...rectangle };
3961
- console.log(`createHighlight: rectangle=${JSON.stringify(rectangle)}`);
3962
- this.saveSelection.emit({ rectangles: [rectangle], page: this.page });
4223
+ const annotationId = v4();
4224
+ rectangle = { id: annotationId, ...rectangle };
4225
+ this.saveSelection.emit({ rectangles: [rectangle], page: this.page, annotationId });
3963
4226
  this.resetHighlight();
3964
4227
  }
3965
4228
  }
4229
+ onCursorPositionChanged(position) {
4230
+ this.cursorX = position.x;
4231
+ this.cursorY = position.y;
4232
+ this.showCursor = position.visible;
4233
+ }
4234
+ onDrawingStarted(event) {
4235
+ this.keyboardDrawingMode = true;
4236
+ this.position = 'absolute';
4237
+ this.backgroundColor = 'yellow';
4238
+ this.display = 'block';
4239
+ this.drawStartX = event.startX;
4240
+ this.drawStartY = event.startY;
4241
+ this.width = event.width;
4242
+ this.height = event.height;
4243
+ this.top = this.drawStartY;
4244
+ this.left = this.drawStartX;
4245
+ this.adjustForRotation();
4246
+ }
4247
+ onDrawingUpdated(event) {
4248
+ this.width = event.width;
4249
+ this.height = event.height;
4250
+ }
4251
+ onDrawingConfirmed(event) {
4252
+ this.keyboardDrawingMode = false;
4253
+ this.createHighlight();
4254
+ }
4255
+ onDrawingCancelled() {
4256
+ this.keyboardDrawingMode = false;
4257
+ this.resetHighlight();
4258
+ }
4259
+ adjustForRotation() {
4260
+ switch (this.rotate) {
4261
+ case 90:
4262
+ this.top = this.drawStartY - this.height;
4263
+ break;
4264
+ case 180:
4265
+ this.top = this.drawStartY - this.height;
4266
+ this.left = this.drawStartX - this.width;
4267
+ break;
4268
+ case 270:
4269
+ this.left = this.drawStartX - this.width;
4270
+ break;
4271
+ }
4272
+ }
3966
4273
  resetHighlight() {
3967
4274
  this.drawStartX = -1;
3968
4275
  this.drawStartY = -1;
@@ -3981,11 +4288,11 @@ class BoxHighlightCreateComponent {
3981
4288
  this.createHighlight();
3982
4289
  }
3983
4290
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BoxHighlightCreateComponent, deps: [{ token: ToolbarEventService }, { token: HighlightCreateService }], target: i0.ɵɵFactoryTarget.Component }); }
3984
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BoxHighlightCreateComponent, selector: "mv-box-highlight-create", inputs: { page: "page", pageHeight: "pageHeight", pageWidth: "pageWidth", rotate: "rotate", zoom: "zoom", container: "container" }, outputs: { saveSelection: "saveSelection" }, viewQueries: [{ propertyName: "highlight", first: true, predicate: ["boxHighlight"], descendants: true }], ngImport: i0, template: "<div [style.height]=\"defaultHeight\"\n [style.width]=\"defaultWidth\"\n (mousedown)=\"initHighlight($event)\"\n (mousemove)=\"updateHighlight($event)\"\n (mouseup)=\"createHighlight()\">\n <div #boxHighlight\n class=\"box-highlight\"\n [style.display]=\"display\"\n [style.position]=\"position\"\n [style.background-color]=\"backgroundColor\"\n [style.height]=\"height ? height + 'px' : '100%'\"\n [style.width]=\"width ? width + 'px' : '100%'\"\n [style.top]=\"top + 'px'\"\n [style.left]=\"left + 'px'\">\n </div>\n</div>\n" }); }
4291
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: BoxHighlightCreateComponent, selector: "mv-box-highlight-create", inputs: { page: "page", pageHeight: "pageHeight", pageWidth: "pageWidth", rotate: "rotate", zoom: "zoom", container: "container" }, outputs: { saveSelection: "saveSelection" }, viewQueries: [{ propertyName: "highlight", first: true, predicate: ["boxHighlight"], descendants: true }, { propertyName: "drawingContainer", first: true, predicate: ["drawingContainer"], descendants: true }], ngImport: i0, template: "<div #drawingContainer\n [style.height]=\"defaultHeight\"\n [style.width]=\"defaultWidth\"\n [tabindex]=\"drawMode ? 0 : -1\"\n mvKeyboardBoxDraw\n [enabled]=\"drawMode\"\n (cursorPositionChanged)=\"onCursorPositionChanged($event)\"\n (drawingStarted)=\"onDrawingStarted($event)\"\n (drawingUpdated)=\"onDrawingUpdated($event)\"\n (drawingConfirmed)=\"onDrawingConfirmed($event)\"\n (drawingCancelled)=\"onDrawingCancelled()\"\n (mousedown)=\"initHighlight($event)\"\n (mousemove)=\"updateHighlight($event)\"\n (mouseup)=\"createHighlight()\">\n\n <div *ngIf=\"showCursor\"\n class=\"drawing-cursor\"\n [style.position]=\"'absolute'\"\n [style.top]=\"cursorY + 'px'\"\n [style.left]=\"cursorX + 'px'\">\n </div>\n\n <div #boxHighlight\n class=\"box-highlight\"\n [style.display]=\"display\"\n [style.position]=\"position\"\n [style.background-color]=\"backgroundColor\"\n [style.height]=\"height ? height + 'px' : '100%'\"\n [style.width]=\"width ? width + 'px' : '100%'\"\n [style.top]=\"top + 'px'\"\n [style.left]=\"left + 'px'\">\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: KeyboardBoxDrawDirective, selector: "[mvKeyboardBoxDraw]", inputs: ["enabled", "minBoxSize", "incrementSmall", "incrementMedium", "incrementLarge"], outputs: ["drawingStarted", "drawingUpdated", "drawingConfirmed", "drawingCancelled", "cursorPositionChanged"] }] }); }
3985
4292
  }
3986
4293
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: BoxHighlightCreateComponent, decorators: [{
3987
4294
  type: Component,
3988
- args: [{ selector: 'mv-box-highlight-create', template: "<div [style.height]=\"defaultHeight\"\n [style.width]=\"defaultWidth\"\n (mousedown)=\"initHighlight($event)\"\n (mousemove)=\"updateHighlight($event)\"\n (mouseup)=\"createHighlight()\">\n <div #boxHighlight\n class=\"box-highlight\"\n [style.display]=\"display\"\n [style.position]=\"position\"\n [style.background-color]=\"backgroundColor\"\n [style.height]=\"height ? height + 'px' : '100%'\"\n [style.width]=\"width ? width + 'px' : '100%'\"\n [style.top]=\"top + 'px'\"\n [style.left]=\"left + 'px'\">\n </div>\n</div>\n" }]
4295
+ args: [{ selector: 'mv-box-highlight-create', template: "<div #drawingContainer\n [style.height]=\"defaultHeight\"\n [style.width]=\"defaultWidth\"\n [tabindex]=\"drawMode ? 0 : -1\"\n mvKeyboardBoxDraw\n [enabled]=\"drawMode\"\n (cursorPositionChanged)=\"onCursorPositionChanged($event)\"\n (drawingStarted)=\"onDrawingStarted($event)\"\n (drawingUpdated)=\"onDrawingUpdated($event)\"\n (drawingConfirmed)=\"onDrawingConfirmed($event)\"\n (drawingCancelled)=\"onDrawingCancelled()\"\n (mousedown)=\"initHighlight($event)\"\n (mousemove)=\"updateHighlight($event)\"\n (mouseup)=\"createHighlight()\">\n\n <div *ngIf=\"showCursor\"\n class=\"drawing-cursor\"\n [style.position]=\"'absolute'\"\n [style.top]=\"cursorY + 'px'\"\n [style.left]=\"cursorX + 'px'\">\n </div>\n\n <div #boxHighlight\n class=\"box-highlight\"\n [style.display]=\"display\"\n [style.position]=\"position\"\n [style.background-color]=\"backgroundColor\"\n [style.height]=\"height ? height + 'px' : '100%'\"\n [style.width]=\"width ? width + 'px' : '100%'\"\n [style.top]=\"top + 'px'\"\n [style.left]=\"left + 'px'\">\n </div>\n</div>\n" }]
3989
4296
  }], ctorParameters: () => [{ type: ToolbarEventService }, { type: HighlightCreateService }], propDecorators: { page: [{
3990
4297
  type: Input
3991
4298
  }], pageHeight: [{
@@ -4003,6 +4310,127 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
4003
4310
  }], highlight: [{
4004
4311
  type: ViewChild,
4005
4312
  args: ['boxHighlight', { static: false }]
4313
+ }], drawingContainer: [{
4314
+ type: ViewChild,
4315
+ args: ['drawingContainer', { static: false }]
4316
+ }] } });
4317
+
4318
+ class KeyboardBoxMoveDirective {
4319
+ constructor(elementRef) {
4320
+ this.elementRef = elementRef;
4321
+ this.enabled = true;
4322
+ this.incrementSmall = 1;
4323
+ this.incrementLarge = 10;
4324
+ this.keyboardMovingChange = new EventEmitter();
4325
+ this.boxDelete = new EventEmitter();
4326
+ this.moveSubject = new Subject();
4327
+ this.isMoving = false;
4328
+ this.moveSubscription = this.moveSubject
4329
+ .pipe(debounceTime(500))
4330
+ .subscribe(() => {
4331
+ this.setMoving(false);
4332
+ this.emitStoppedEvent();
4333
+ });
4334
+ }
4335
+ ngOnDestroy() {
4336
+ if (this.moveSubscription) {
4337
+ this.moveSubscription.unsubscribe();
4338
+ }
4339
+ this.moveSubject.complete();
4340
+ }
4341
+ onKeyDown(event) {
4342
+ if (event.key === 'Delete' || event.key === 'Backspace') {
4343
+ event.preventDefault();
4344
+ event.stopPropagation();
4345
+ this.boxDelete.emit();
4346
+ return;
4347
+ }
4348
+ if (!this.enabled) {
4349
+ return;
4350
+ }
4351
+ if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(event.key)) {
4352
+ event.preventDefault();
4353
+ event.stopPropagation();
4354
+ this.moveBox(event);
4355
+ }
4356
+ }
4357
+ moveBox(event) {
4358
+ const element = this.elementRef.nativeElement;
4359
+ const increment = event.shiftKey ? this.incrementLarge : this.incrementSmall;
4360
+ if (!this.isMoving) {
4361
+ this.setMoving(true);
4362
+ }
4363
+ const currentTop = parseFloat(element.style.top) || 0;
4364
+ const currentLeft = parseFloat(element.style.left) || 0;
4365
+ const currentWidth = element.offsetWidth;
4366
+ const currentHeight = element.offsetHeight;
4367
+ let newTop = currentTop;
4368
+ let newLeft = currentLeft;
4369
+ switch (event.key) {
4370
+ case 'ArrowUp':
4371
+ newTop = currentTop - increment;
4372
+ break;
4373
+ case 'ArrowDown':
4374
+ newTop = currentTop + increment;
4375
+ break;
4376
+ case 'ArrowLeft':
4377
+ newLeft = currentLeft - increment;
4378
+ break;
4379
+ case 'ArrowRight':
4380
+ newLeft = currentLeft + increment;
4381
+ break;
4382
+ }
4383
+ if (this.movementBounds) {
4384
+ newTop = Math.max(0, Math.min(newTop, this.movementBounds.containerHeight - currentHeight));
4385
+ newLeft = Math.max(0, Math.min(newLeft, this.movementBounds.containerWidth - currentWidth));
4386
+ }
4387
+ element.style.top = `${newTop}px`;
4388
+ element.style.left = `${newLeft}px`;
4389
+ this.moveSubject.next();
4390
+ }
4391
+ setMoving(moving) {
4392
+ if (this.isMoving !== moving) {
4393
+ this.isMoving = moving;
4394
+ this.keyboardMovingChange.emit(moving);
4395
+ }
4396
+ }
4397
+ emitStoppedEvent() {
4398
+ const element = this.elementRef.nativeElement;
4399
+ const wasFocused = document.activeElement === element;
4400
+ const stoppedEvent = new CustomEvent('stopped', {
4401
+ detail: element,
4402
+ bubbles: true
4403
+ });
4404
+ element.dispatchEvent(stoppedEvent);
4405
+ if (wasFocused) {
4406
+ setTimeout(() => {
4407
+ element.focus();
4408
+ }, 50);
4409
+ }
4410
+ }
4411
+ /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KeyboardBoxMoveDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
4412
+ /** @nocollapse */ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: KeyboardBoxMoveDirective, selector: "[mvKeyboardBoxMove]", inputs: { enabled: "enabled", incrementSmall: "incrementSmall", incrementLarge: "incrementLarge", movementBounds: "movementBounds" }, outputs: { keyboardMovingChange: "keyboardMovingChange", boxDelete: "boxDelete" }, host: { listeners: { "keydown": "onKeyDown($event)" } }, ngImport: i0 }); }
4413
+ }
4414
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: KeyboardBoxMoveDirective, decorators: [{
4415
+ type: Directive,
4416
+ args: [{
4417
+ selector: '[mvKeyboardBoxMove]'
4418
+ }]
4419
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { enabled: [{
4420
+ type: Input
4421
+ }], incrementSmall: [{
4422
+ type: Input
4423
+ }], incrementLarge: [{
4424
+ type: Input
4425
+ }], movementBounds: [{
4426
+ type: Input
4427
+ }], keyboardMovingChange: [{
4428
+ type: Output
4429
+ }], boxDelete: [{
4430
+ type: Output
4431
+ }], onKeyDown: [{
4432
+ type: HostListener,
4433
+ args: ['keydown', ['$event']]
4006
4434
  }] } });
4007
4435
 
4008
4436
  class RectangleComponent {
@@ -4019,8 +4447,11 @@ class RectangleComponent {
4019
4447
  constructor(toolbarEvents, highlightService) {
4020
4448
  this.toolbarEvents = toolbarEvents;
4021
4449
  this.highlightService = highlightService;
4450
+ this.rectangleTabIndex = 0;
4022
4451
  this.selectEvent = new EventEmitter();
4023
4452
  this.updateEvent = new EventEmitter();
4453
+ this.deleteEvent = new EventEmitter();
4454
+ this.keyboardMovingChange = new EventEmitter();
4024
4455
  this.subscriptions = [];
4025
4456
  this.enableGrabNDrag = false;
4026
4457
  }
@@ -4028,9 +4459,16 @@ class RectangleComponent {
4028
4459
  if (changes.rotate) {
4029
4460
  this.adjustForRotation(this.rotate);
4030
4461
  }
4462
+ if (changes.pageHeight || changes.pageWidth) {
4463
+ this.updateMovementBounds();
4464
+ }
4031
4465
  }
4032
4466
  ngAfterViewInit() {
4033
4467
  this.subscriptions.push(this.toolbarEvents.grabNDrag.subscribe(grabNDrag => this.enableGrabNDrag = grabNDrag));
4468
+ setTimeout(() => this.updateMovementBounds(), 0);
4469
+ if (this._selected && this.viewRect) {
4470
+ this.viewRect.nativeElement.focus();
4471
+ }
4034
4472
  }
4035
4473
  ngOnDestroy() {
4036
4474
  this.subscriptions.filter(subscription => !subscription.closed)
@@ -4048,6 +4486,9 @@ class RectangleComponent {
4048
4486
  onClick() {
4049
4487
  this.selectEvent.emit(this.annoRect);
4050
4488
  }
4489
+ onFocus() {
4490
+ this.selectEvent.emit(this.annoRect);
4491
+ }
4051
4492
  onUpdate(viewRect) {
4052
4493
  const { offsetHeight, offsetWidth, offsetTop, offsetLeft } = viewRect;
4053
4494
  if (this.hasRectangleChanged(viewRect)) {
@@ -4084,12 +4525,28 @@ class RectangleComponent {
4084
4525
  Math.round(this.width) !== viewRect.offsetWidth ||
4085
4526
  Math.round(this.height) !== viewRect.offsetHeight;
4086
4527
  }
4528
+ updateMovementBounds() {
4529
+ if (this.pageHeight && this.pageWidth) {
4530
+ this.movementBounds = {
4531
+ containerHeight: this.pageHeight,
4532
+ containerWidth: this.pageWidth
4533
+ };
4534
+ }
4535
+ }
4536
+ onKeyboardMovingChange(isMoving) {
4537
+ this.keyboardMovingChange.emit(isMoving);
4538
+ }
4539
+ onDelete() {
4540
+ if (this._selected) {
4541
+ this.deleteEvent.emit(this.annoRect);
4542
+ }
4543
+ }
4087
4544
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RectangleComponent, deps: [{ token: ToolbarEventService }, { token: HighlightCreateService }], target: i0.ɵɵFactoryTarget.Component }); }
4088
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: { color: "color", zoom: "zoom", rotate: "rotate", editable: "editable", pageHeight: "pageHeight", pageWidth: "pageWidth", annoRect: "annoRect", selected: "selected" }, outputs: { selectEvent: "selectEvent", updateEvent: "updateEvent" }, viewQueries: [{ propertyName: "viewRect", first: true, predicate: ["rectElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n (click)=\"onClick()\"\n (stopped)=\"onUpdate(rectElement)\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n (click)=\"onClick()\">\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.DraggableElementDirective, selector: "[draggable]", inputs: ["rotate"], outputs: ["coordinates", "stopped"] }, { kind: "directive", type: i4$1.ResizableElementDirective, selector: "[resizable]", inputs: ["rotate", "selected"], outputs: ["stopped"] }] }); }
4545
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: { color: "color", zoom: "zoom", rotate: "rotate", editable: "editable", pageHeight: "pageHeight", pageWidth: "pageWidth", rectangleTabIndex: "rectangleTabIndex", annoRect: "annoRect", selected: "selected" }, outputs: { selectEvent: "selectEvent", updateEvent: "updateEvent", deleteEvent: "deleteEvent", keyboardMovingChange: "keyboardMovingChange" }, viewQueries: [{ propertyName: "viewRect", first: true, predicate: ["rectElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n mvKeyboardBoxMove\n [tabindex]=\"rectangleTabIndex\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n [movementBounds]=\"movementBounds\"\n (click)=\"onClick()\"\n (focus)=\"onFocus()\"\n (stopped)=\"onUpdate(rectElement)\"\n (keyboardMovingChange)=\"onKeyboardMovingChange($event)\"\n (boxDelete)=\"onDelete()\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n mvKeyboardBoxMove\n [tabindex]=\"rectangleTabIndex\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [enabled]=\"false\"\n (click)=\"onClick()\"\n (focus)=\"onFocus()\"\n (boxDelete)=\"onDelete()\">\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4$1.DraggableElementDirective, selector: "[draggable]", inputs: ["rotate"], outputs: ["coordinates", "stopped"] }, { kind: "directive", type: i4$1.ResizableElementDirective, selector: "[resizable]", inputs: ["rotate", "selected"], outputs: ["stopped"] }, { kind: "directive", type: KeyboardBoxMoveDirective, selector: "[mvKeyboardBoxMove]", inputs: ["enabled", "incrementSmall", "incrementLarge", "movementBounds"], outputs: ["keyboardMovingChange", "boxDelete"] }] }); }
4089
4546
  }
4090
4547
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: RectangleComponent, decorators: [{
4091
4548
  type: Component,
4092
- args: [{ selector: 'mv-anno-rectangle', template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n (click)=\"onClick()\"\n (stopped)=\"onUpdate(rectElement)\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n [tabindex]=\"annoRect.id\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n (click)=\"onClick()\">\n </div>\n</ng-template>\n" }]
4549
+ args: [{ selector: 'mv-anno-rectangle', template: "<div *ngIf=\"editable; else nonEditable\">\n <div #rectElement\n class=\"rectangle\"\n draggable\n resizable\n mvKeyboardBoxMove\n [tabindex]=\"rectangleTabIndex\"\n [ngClass]=\"{ 'selected': selected, 'grabNDrag': enableGrabNDrag }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height + 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [rotate]=\"0\"\n [selected]=\"selected\"\n [movementBounds]=\"movementBounds\"\n (click)=\"onClick()\"\n (focus)=\"onFocus()\"\n (stopped)=\"onUpdate(rectElement)\"\n (keyboardMovingChange)=\"onKeyboardMovingChange($event)\"\n (boxDelete)=\"onDelete()\">\n </div>\n</div>\n<ng-template #nonEditable>\n <div #rectElement\n class=\"rectangle\"\n mvKeyboardBoxMove\n [tabindex]=\"rectangleTabIndex\"\n [ngClass]=\"{ 'selected': selected }\"\n [style.backgroundColor]=\"'#' + color\"\n [style.width]=\"width + 'px'\"\n [style.height]=\"height+ 'px'\"\n [style.left]=\"left + 'px'\"\n [style.top]=\"top + 'px'\"\n [enabled]=\"false\"\n (click)=\"onClick()\"\n (focus)=\"onFocus()\"\n (boxDelete)=\"onDelete()\">\n </div>\n</ng-template>\n" }]
4093
4550
  }], ctorParameters: () => [{ type: ToolbarEventService }, { type: HighlightCreateService }], propDecorators: { color: [{
4094
4551
  type: Input
4095
4552
  }], zoom: [{
@@ -4102,10 +4559,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
4102
4559
  type: Input
4103
4560
  }], pageWidth: [{
4104
4561
  type: Input
4562
+ }], rectangleTabIndex: [{
4563
+ type: Input
4105
4564
  }], selectEvent: [{
4106
4565
  type: Output
4107
4566
  }], updateEvent: [{
4108
4567
  type: Output
4568
+ }], deleteEvent: [{
4569
+ type: Output
4570
+ }], keyboardMovingChange: [{
4571
+ type: Output
4109
4572
  }], viewRect: [{
4110
4573
  type: ViewChild,
4111
4574
  args: ['rectElement', { static: false }]
@@ -4239,18 +4702,41 @@ class AnnotationViewComponent {
4239
4702
  if (selectedId) {
4240
4703
  const id = this.anno.id || this.anno.redactionId; // todo make it unique
4241
4704
  this.selected = selectedId.annotationId ? (selectedId.annotationId === id) : false;
4705
+ if (this.selected && !this.isKeyboardMoving) {
4706
+ this.showToolbarSubject.next(true);
4707
+ }
4708
+ else {
4709
+ this.showToolbarSubject.next(false);
4710
+ }
4242
4711
  }
4243
4712
  }
4244
4713
  constructor(toolbarEvents, store) {
4245
4714
  this.toolbarEvents = toolbarEvents;
4246
4715
  this.store = store;
4716
+ this.isKeyboardMoving = false;
4717
+ this.showToolbar = false;
4718
+ this.showToolbarSubject = new Subject();
4247
4719
  this.update = new EventEmitter();
4248
4720
  this.delete = new EventEmitter();
4249
4721
  this.annotationClick = new EventEmitter();
4722
+ this.showToolbarSubject
4723
+ .pipe(debounceTime$1(300))
4724
+ .subscribe(show => {
4725
+ this.showToolbar = show;
4726
+ });
4727
+ }
4728
+ ngOnDestroy() {
4729
+ this.showToolbarSubject.complete();
4730
+ }
4731
+ setShowToolbar(show) {
4732
+ this.showToolbarSubject.next(show);
4250
4733
  }
4251
4734
  onSelect() {
4252
4735
  const annotationId = this.anno.id || this.anno.redactionId;
4253
4736
  this.annotationClick.emit({ annotationId, editable: false, selected: true });
4737
+ if (!this.isKeyboardMoving) {
4738
+ this.setShowToolbar(true);
4739
+ }
4254
4740
  }
4255
4741
  onRectangleUpdate(rectangle) {
4256
4742
  const annotation = { ...this.anno };
@@ -4286,12 +4772,22 @@ class AnnotationViewComponent {
4286
4772
  this.annotationClick.emit({ annotationId: this.anno.id, editable: true, selected: true });
4287
4773
  this.toolbarEvents.toggleCommentsPanel(true);
4288
4774
  }
4775
+ onKeyboardMovingChange(isMoving) {
4776
+ this.isKeyboardMoving = isMoving;
4777
+ if (isMoving) {
4778
+ this.showToolbar = false;
4779
+ this.showToolbarSubject.next(false);
4780
+ }
4781
+ else if (this.selected) {
4782
+ this.setShowToolbar(true);
4783
+ }
4784
+ }
4289
4785
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnnotationViewComponent, deps: [{ token: ToolbarEventService }, { token: i1.Store }], target: i0.ɵɵFactoryTarget.Component }); }
4290
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AnnotationViewComponent, selector: "mv-annotation", inputs: { annotation: "annotation", zoom: "zoom", rotate: "rotate", selectedAnnoId: "selectedAnnoId", pageHeight: "pageHeight", pageWidth: "pageWidth" }, outputs: { update: "update", delete: "delete", annotationClick: "annotationClick" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div #container [tabindex]=\"anno.id\">\n <mv-ctx-toolbar *ngIf=\"selected\"\n [canDelete]=\"true\" [canComment]=\"true\"\n [rectangles]=\"anno.rectangles\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n (deleteHighlightEvent)=\"deleteHighlight()\"\n (addOrEditCommentEvent)=\"addOrEditComment()\">\n </mv-ctx-toolbar>\n <ng-container *ngFor=\"let rectangle of anno.rectangles\">\n <mv-anno-rectangle\n (selectEvent)=\"onSelect()\"\n (updateEvent)=\"onRectangleUpdate($event)\"\n [selected]=\"selected\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n [editable]=\"anno.rectangles.length <= 1\"\n [annoRect]=\"rectangle\"\n [color]=\"anno.color\">\n </mv-anno-rectangle>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: ["color", "zoom", "rotate", "editable", "pageHeight", "pageWidth", "annoRect", "selected"], outputs: ["selectEvent", "updateEvent"] }, { kind: "component", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: ["zoom", "rotate", "pageHeight", "pageWidth", "canHighlight", "canBookmark", "canComment", "canDelete", "rectangles"], outputs: ["createHighlightEvent", "deleteHighlightEvent", "addOrEditCommentEvent", "createBookmarkEvent"] }] }); }
4786
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AnnotationViewComponent, selector: "mv-annotation", inputs: { annotation: "annotation", zoom: "zoom", rotate: "rotate", selectedAnnoId: "selectedAnnoId", pageHeight: "pageHeight", pageWidth: "pageWidth" }, outputs: { update: "update", delete: "delete", annotationClick: "annotationClick" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }], ngImport: i0, template: "<div #container [tabindex]=\"-1\">\n <mv-ctx-toolbar *ngIf=\"selected && showToolbar\"\n [canDelete]=\"true\" [canComment]=\"true\"\n [rectangles]=\"anno.rectangles\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n (deleteHighlightEvent)=\"deleteHighlight()\"\n (addOrEditCommentEvent)=\"addOrEditComment()\">\n </mv-ctx-toolbar>\n <ng-container *ngFor=\"let rectangle of anno.rectangles; let i = index\">\n <mv-anno-rectangle\n (selectEvent)=\"onSelect()\"\n (updateEvent)=\"onRectangleUpdate($event)\"\n (keyboardMovingChange)=\"onKeyboardMovingChange($event)\"\n (deleteEvent)=\"deleteHighlight()\"\n [selected]=\"selected\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n [editable]=\"anno.rectangles.length <= 1\"\n [annoRect]=\"rectangle\"\n [rectangleTabIndex]=\"i + 1\"\n [color]=\"anno.color\">\n </mv-anno-rectangle>\n </ng-container>\n</div>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: RectangleComponent, selector: "mv-anno-rectangle", inputs: ["color", "zoom", "rotate", "editable", "pageHeight", "pageWidth", "rectangleTabIndex", "annoRect", "selected"], outputs: ["selectEvent", "updateEvent", "deleteEvent", "keyboardMovingChange"] }, { kind: "component", type: CtxToolbarComponent, selector: "mv-ctx-toolbar", inputs: ["zoom", "rotate", "pageHeight", "pageWidth", "canHighlight", "canBookmark", "canComment", "canDelete", "rectangles"], outputs: ["createHighlightEvent", "deleteHighlightEvent", "addOrEditCommentEvent", "createBookmarkEvent"] }] }); }
4291
4787
  }
4292
4788
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnnotationViewComponent, decorators: [{
4293
4789
  type: Component,
4294
- args: [{ selector: 'mv-annotation', template: "<div #container [tabindex]=\"anno.id\">\n <mv-ctx-toolbar *ngIf=\"selected\"\n [canDelete]=\"true\" [canComment]=\"true\"\n [rectangles]=\"anno.rectangles\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n (deleteHighlightEvent)=\"deleteHighlight()\"\n (addOrEditCommentEvent)=\"addOrEditComment()\">\n </mv-ctx-toolbar>\n <ng-container *ngFor=\"let rectangle of anno.rectangles\">\n <mv-anno-rectangle\n (selectEvent)=\"onSelect()\"\n (updateEvent)=\"onRectangleUpdate($event)\"\n [selected]=\"selected\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n [editable]=\"anno.rectangles.length <= 1\"\n [annoRect]=\"rectangle\"\n [color]=\"anno.color\">\n </mv-anno-rectangle>\n </ng-container>\n</div>\n" }]
4790
+ args: [{ selector: 'mv-annotation', template: "<div #container [tabindex]=\"-1\">\n <mv-ctx-toolbar *ngIf=\"selected && showToolbar\"\n [canDelete]=\"true\" [canComment]=\"true\"\n [rectangles]=\"anno.rectangles\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n (deleteHighlightEvent)=\"deleteHighlight()\"\n (addOrEditCommentEvent)=\"addOrEditComment()\">\n </mv-ctx-toolbar>\n <ng-container *ngFor=\"let rectangle of anno.rectangles; let i = index\">\n <mv-anno-rectangle\n (selectEvent)=\"onSelect()\"\n (updateEvent)=\"onRectangleUpdate($event)\"\n (keyboardMovingChange)=\"onKeyboardMovingChange($event)\"\n (deleteEvent)=\"deleteHighlight()\"\n [selected]=\"selected\"\n [zoom]=\"zoom\"\n [rotate]=\"rotate\"\n [pageHeight]=\"pageHeight\"\n [pageWidth]=\"pageWidth\"\n [editable]=\"anno.rectangles.length <= 1\"\n [annoRect]=\"rectangle\"\n [rectangleTabIndex]=\"i + 1\"\n [color]=\"anno.color\">\n </mv-anno-rectangle>\n </ng-container>\n</div>\n" }]
4295
4791
  }], ctorParameters: () => [{ type: ToolbarEventService }, { type: i1.Store }], propDecorators: { annotation: [{
4296
4792
  type: Input
4297
4793
  }], zoom: [{
@@ -4409,8 +4905,8 @@ class MetadataLayerComponent {
4409
4905
  this.rectangles = undefined;
4410
4906
  });
4411
4907
  }
4412
- saveAnnotation({ rectangles, page }) {
4413
- this.highlightService.saveAnnotation(rectangles, page);
4908
+ saveAnnotation({ rectangles, page, annotationId }) {
4909
+ this.highlightService.saveAnnotation(rectangles, page, annotationId);
4414
4910
  this.toolbarEvents.drawModeSubject.next(false);
4415
4911
  }
4416
4912
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MetadataLayerComponent, deps: [{ token: i1.Store }, { token: HighlightCreateService }, { token: ToolbarEventService }, { token: ViewerEventService }], target: i0.ɵɵFactoryTarget.Component }); }
@@ -6577,11 +7073,6 @@ class ConfirmActionDialogComponent {
6577
7073
  constructor(icpEventService) {
6578
7074
  this.icpEventService = icpEventService;
6579
7075
  }
6580
- ngAfterViewInit() {
6581
- if (this.modalContainer) {
6582
- this.modalContainer.nativeElement.focus();
6583
- }
6584
- }
6585
7076
  onCancel() {
6586
7077
  this.icpEventService.leavingSession.next(false);
6587
7078
  }
@@ -6590,15 +7081,12 @@ class ConfirmActionDialogComponent {
6590
7081
  this.icpEventService.leavingSession.next(false);
6591
7082
  }
6592
7083
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmActionDialogComponent, deps: [{ token: IcpEventService }], target: i0.ɵɵFactoryTarget.Component }); }
6593
- /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ConfirmActionDialogComponent, selector: "mv-confirm-action", viewQueries: [{ propertyName: "modalContainer", first: true, predicate: ["modalContainer"], descendants: true }], ngImport: i0, template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" \n class=\"modal-content govuk-width-container clearfix\"\n (click)=\"$event.stopPropagation()\"\n #modalContainer\n tabIndex=\"-1\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }); }
7084
+ /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ConfirmActionDialogComponent, selector: "mv-confirm-action", ngImport: i0, template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" class=\"modal-content govuk-width-container clearfix\" (click)=\"$event.stopPropagation()\">\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }); }
6594
7085
  }
6595
7086
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ConfirmActionDialogComponent, decorators: [{
6596
7087
  type: Component,
6597
- args: [{ selector: 'mv-confirm-action', template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" \n class=\"modal-content govuk-width-container clearfix\"\n (click)=\"$event.stopPropagation()\"\n #modalContainer\n tabIndex=\"-1\"\n role=\"dialog\"\n aria-modal=\"true\"\n >\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }]
6598
- }], ctorParameters: () => [{ type: IcpEventService }], propDecorators: { modalContainer: [{
6599
- type: ViewChild,
6600
- args: ['modalContainer']
6601
- }] } });
7088
+ args: [{ selector: 'mv-confirm-action', template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onCancel()\">\n <div id=\"modal\" class=\"modal-content govuk-width-container clearfix\" (click)=\"$event.stopPropagation()\">\n <h2 class=\"govuk-heading-s\">Are you sure you want to leave the presentation?</h2>\n <div class=\"button-container\">\n <button id=\"modal-close-button\" (click)=\"onConfirm()\" class=\"govuk-button\">Confirm</button>\n <button (click)=\"onCancel()\" class=\"govuk-button govuk-button--secondary\">Cancel</button>\n </div>\n </div>\n</div>\n" }]
7089
+ }], ctorParameters: () => [{ type: IcpEventService }] });
6602
7090
 
6603
7091
  var CoreContentTypes;
6604
7092
  (function (CoreContentTypes) {
@@ -6979,7 +7467,9 @@ class AnnotationsModule {
6979
7467
  MomentDatePipe,
6980
7468
  CommentFilterComponent,
6981
7469
  FilterPipe,
6982
- UnsnakePipe], imports: [A11yModule,
7470
+ UnsnakePipe,
7471
+ KeyboardBoxDrawDirective,
7472
+ KeyboardBoxMoveDirective], imports: [A11yModule,
6983
7473
  CommonModule,
6984
7474
  FormsModule,
6985
7475
  HttpClientModule,
@@ -7055,7 +7545,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
7055
7545
  MomentDatePipe,
7056
7546
  CommentFilterComponent,
7057
7547
  FilterPipe,
7058
- UnsnakePipe
7548
+ UnsnakePipe,
7549
+ KeyboardBoxDrawDirective,
7550
+ KeyboardBoxMoveDirective
7059
7551
  ],
7060
7552
  providers: [
7061
7553
  AnnotationApiService,
@@ -7099,7 +7591,11 @@ class AnnotationEffects {
7099
7591
  })));
7100
7592
  this.postAnnotation$ = createEffect(() => this.actions$.pipe(ofType(SAVE_ANNOTATION), concatMap((action) => {
7101
7593
  return this.annotationApiService.postAnnotation(action.payload).pipe(map(annotations => {
7102
- return new SaveAnnotationSuccess(annotations);
7594
+ const successAction = new SaveAnnotationSuccess(annotations);
7595
+ successAction.autoSelect = action.autoSelect;
7596
+ successAction.annotationId = action.payload.id;
7597
+ return successAction;
7598
+ // return new annotationsActions.SaveAnnotationSuccess(annotations);
7103
7599
  }), catchError(error => {
7104
7600
  return of(new LoadAnnotationSetFail(error));
7105
7601
  }));
@@ -7118,6 +7614,13 @@ class AnnotationEffects {
7118
7614
  return of(new SaveAnnotationSetFail(error));
7119
7615
  }));
7120
7616
  })));
7617
+ this.autoSelectAnnotation$ = createEffect(() => this.actions$.pipe(ofType(SAVE_ANNOTATION_SUCCESS), filter((action) => action.autoSelect === true && action.annotationId), map((action) => {
7618
+ return new SelectedAnnotation({
7619
+ annotationId: action.annotationId,
7620
+ editable: false,
7621
+ selected: true
7622
+ });
7623
+ })));
7121
7624
  }
7122
7625
  /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnnotationEffects, deps: [{ token: i1$2.Actions }, { token: AnnotationApiService }], target: i0.ɵɵFactoryTarget.Injectable }); }
7123
7626
  /** @nocollapse */ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AnnotationEffects }); }