Fix calendar widget resize when adding or removing other widgets (#8784)

* Fix calendar widget resize when adding or removing other widgets

The fullcalendar dependency only reacts to the `document.resize` event. However in our case the widget can also resize
when neighboring widgets are added or removed. This fix adds a `ResizeObserver` listener to account for that. It is
supported in all evergreen browsers.

* Explicitly add resize observer typings

The typings file for ResizeObserver was not being autoloaded. This commit adds the typings explicitly, making sure tsc
picks up on them.

* Move typings include to a different file
pull/8832/head
Benjamin Bädorf 4 years ago committed by GitHub
parent 88af9625e5
commit 724a4514fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 51
      frontend/npm-shrinkwrap.json
  2. 33
      frontend/package.json
  3. 57
      frontend/src/app/modules/calendar/wp-calendar/wp-calendar.component.ts
  4. 1
      frontend/src/typings/shims.d.ts

@ -2530,6 +2530,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@types/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-32f/Uonzj4fU2WPRo3Jd8x7vilyZvjdUV6YZwMW2QNkTc/mRs0BLWIqUAjzwnYDnkMFREIwqsd1Qcl5cjE6A8A==",
"dev": true,
"requires": {
"assertion-error": "*"
}
@ -2546,6 +2547,7 @@
"version": "0.0.87",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-0.0.87.tgz",
"integrity": "sha512-Yv+cw1zckMDK35QJBMMK/z9ZWUHRUpQ2KJI+MCbR95HhDWtSQsS66j/W9OMq3JUqYL7Jb2zHA7fc575/0v1sfA==",
"dev": true,
"requires": {
"@types/tern": "*"
}
@ -2558,17 +2560,20 @@
"@types/dragula": {
"version": "3.7.0",
"resolved": "https://registry.npmjs.org/@types/dragula/-/dragula-3.7.0.tgz",
"integrity": "sha512-Scr3lQ7pDmwic+I4qrzDEIfPVGUhc/qo8S0VJJ9v5pzTyIIJzAXrnFajjsMSL8J84VERIkZUh7wH6wYEisY+TA=="
"integrity": "sha512-Scr3lQ7pDmwic+I4qrzDEIfPVGUhc/qo8S0VJJ9v5pzTyIIJzAXrnFajjsMSL8J84VERIkZUh7wH6wYEisY+TA==",
"dev": true
},
"@types/es6-shim": {
"version": "0.31.39",
"resolved": "https://registry.npmjs.org/@types/es6-shim/-/es6-shim-0.31.39.tgz",
"integrity": "sha512-z2JtmHE1wg75JTdT1qWGvW4eDOk6DUW1Exdzrs+8QTPFttkdTr4pKVzLLCCAOUC8i/KiG+QtkSEteQ5hDxwbpg=="
"integrity": "sha512-z2JtmHE1wg75JTdT1qWGvW4eDOk6DUW1Exdzrs+8QTPFttkdTr4pKVzLLCCAOUC8i/KiG+QtkSEteQ5hDxwbpg==",
"dev": true
},
"@types/estree": {
"version": "0.0.42",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.42.tgz",
"integrity": "sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ=="
"integrity": "sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==",
"dev": true
},
"@types/glob": {
"version": "7.1.3",
@ -2582,7 +2587,8 @@
"@types/hammerjs": {
"version": "2.0.36",
"resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.36.tgz",
"integrity": "sha512-7TUK/k2/QGpEAv/BCwSHlYu3NXZhQ9ZwBYpzr9tjlPIL2C5BeGhH3DmVavRx3ZNyELX5TLC91JTz/cen6AAtIQ=="
"integrity": "sha512-7TUK/k2/QGpEAv/BCwSHlYu3NXZhQ9ZwBYpzr9tjlPIL2C5BeGhH3DmVavRx3ZNyELX5TLC91JTz/cen6AAtIQ==",
"dev": true
},
"@types/jasmine": {
"version": "3.5.8",
@ -2603,6 +2609,7 @@
"version": "3.3.33",
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.33.tgz",
"integrity": "sha512-U6IdXYGkfUI42SR79vB2Spj+h1Ly3J3UZjpd8mi943lh126TK7CB+HZOxGh2nM3IySor7wqVQdemD/xtydsBKA==",
"dev": true,
"requires": {
"@types/sizzle": "*"
}
@ -2611,6 +2618,7 @@
"version": "1.12.10",
"resolved": "https://registry.npmjs.org/@types/jqueryui/-/jqueryui-1.12.10.tgz",
"integrity": "sha512-T8sctslWIiLl/2EHEQQfKCB92S9bMKBaeE3+iBRbSERMK/1gzyfqjaIEksduB4eUEsKq+Ji0Y+qVbiXQwI2Mwg==",
"dev": true,
"requires": {
"@types/jquery": "*"
}
@ -2623,7 +2631,8 @@
"@types/lodash": {
"version": "4.14.149",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz",
"integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ=="
"integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==",
"dev": true
},
"@types/minimatch": {
"version": "3.0.3",
@ -2634,6 +2643,7 @@
"version": "0.5.12",
"resolved": "https://registry.npmjs.org/@types/moment-timezone/-/moment-timezone-0.5.12.tgz",
"integrity": "sha512-hnHH2+Efg2vExr/dSz+IX860nSiyk9Sk4pJF2EmS11lRpMcNXeB4KBW5xcgw2QPsb9amTXdsVNEe5IoJXiT0uw==",
"dev": true,
"requires": {
"moment": ">=2.14.0"
}
@ -2641,7 +2651,8 @@
"@types/mousetrap": {
"version": "1.6.3",
"resolved": "https://registry.npmjs.org/@types/mousetrap/-/mousetrap-1.6.3.tgz",
"integrity": "sha512-13gmo3M2qVvjQrWNseqM3+cR6S2Ss3grbR2NZltgMq94wOwqJYQdgn8qzwDshzgXqMlSUtyPZjysImmktu22ew=="
"integrity": "sha512-13gmo3M2qVvjQrWNseqM3+cR6S2Ss3grbR2NZltgMq94wOwqJYQdgn8qzwDshzgXqMlSUtyPZjysImmktu22ew==",
"dev": true
},
"@types/node": {
"version": "13.9.0",
@ -2651,27 +2662,37 @@
"@types/pako": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/pako/-/pako-1.0.1.tgz",
"integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg=="
"integrity": "sha512-GdZbRSJ3Cv5fiwT6I0SQ3ckeN2PWNqxd26W9Z2fCK1tGrrasGy4puvNFtnddqH9UJFMQYXxEuuB7B8UK+LLwSg==",
"dev": true
},
"@types/promises-a-plus": {
"version": "0.0.27",
"resolved": "https://registry.npmjs.org/@types/promises-a-plus/-/promises-a-plus-0.0.27.tgz",
"integrity": "sha1-xkZRE0YUyEuPXXEUzokB02pgl4A="
"integrity": "sha1-xkZRE0YUyEuPXXEUzokB02pgl4A=",
"dev": true
},
"@types/q": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
},
"@types/resize-observer-browser": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@types/resize-observer-browser/-/resize-observer-browser-0.1.4.tgz",
"integrity": "sha512-rPvqs+1hL/5hbES/0HTdUu4lvNmneiwKwccbWe7HGLWbnsLdqKnQHyWLg4Pj0AMO7PLHCwBM1Cs8orChdkDONg==",
"dev": true
},
"@types/rosie": {
"version": "0.0.37",
"resolved": "https://registry.npmjs.org/@types/rosie/-/rosie-0.0.37.tgz",
"integrity": "sha512-ZjeBPOz2ny50513sxtGpI9iIyH8+N/Ac1F9MIxzPJsyf6nSTdVuzsCEMzEbKqCubru/u1uvBiQa4lUBptvdIUw=="
"integrity": "sha512-ZjeBPOz2ny50513sxtGpI9iIyH8+N/Ac1F9MIxzPJsyf6nSTdVuzsCEMzEbKqCubru/u1uvBiQa4lUBptvdIUw==",
"dev": true
},
"@types/sizzle": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
"integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg=="
"integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==",
"dev": true
},
"@types/source-list-map": {
"version": "0.1.2",
@ -2682,6 +2703,7 @@
"version": "0.23.3",
"resolved": "https://registry.npmjs.org/@types/tern/-/tern-0.23.3.tgz",
"integrity": "sha512-imDtS4TAoTcXk0g7u4kkWqedB3E4qpjXzCpD2LU5M5NAXHzCDsypyvXSaG7mM8DKYkCRa7tFp4tS/lp/Wo7Q3w==",
"dev": true,
"requires": {
"@types/estree": "*"
}
@ -2689,12 +2711,14 @@
"@types/urijs": {
"version": "1.19.6",
"resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.6.tgz",
"integrity": "sha512-kdnK+JtEiUgnpB7r99SAZjjz9nhZ/7MWo/hxTSNfvslAa4r8jpDXDEJ2cQrjemes4eX2Y5Om3udmcc8QalPzOA=="
"integrity": "sha512-kdnK+JtEiUgnpB7r99SAZjjz9nhZ/7MWo/hxTSNfvslAa4r8jpDXDEJ2cQrjemes4eX2Y5Om3udmcc8QalPzOA==",
"dev": true
},
"@types/webpack-env": {
"version": "1.15.1",
"resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.15.1.tgz",
"integrity": "sha512-eWN5ElDTeBc5lRDh95SqA8x18D0ll2pWudU3uWiyfsRmIZcmUXpEsxPU+7+BsdCrO2vfLRC629u/MmjbmF+2tA=="
"integrity": "sha512-eWN5ElDTeBc5lRDh95SqA8x18D0ll2pWudU3uWiyfsRmIZcmUXpEsxPU+7+BsdCrO2vfLRC629u/MmjbmF+2tA==",
"dev": true
},
"@types/webpack-sources": {
"version": "0.1.8",
@ -3296,7 +3320,8 @@
"assertion-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw=="
"integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true
},
"assign-symbols": {
"version": "1.0.0",

@ -9,6 +9,23 @@
"@types/jasmine": "~3.5.7",
"@types/jasminewd2": "~2.0.8",
"@types/node": "^13.7.7",
"@types/resize-observer-browser": "^0.1.4",
"@types/assertion-error": "^1.1.0",
"@types/chart.js": "^2.9.20",
"@types/codemirror": "0.0.87",
"@types/dragula": "^3.7.0",
"@types/es6-shim": "^0.31.39",
"@types/hammerjs": "^2.0.36",
"@types/jquery": "^3.3.33",
"@types/jqueryui": "^1.12.10",
"@types/lodash": "^4.14.149",
"@types/moment-timezone": "^0.5.12",
"@types/mousetrap": "^1.6.3",
"@types/pako": "^1.0.1",
"@types/promises-a-plus": "0.0.27",
"@types/rosie": "0.0.37",
"@types/urijs": "^1.19.6",
"@types/webpack-env": "^1.15.1",
"body-parser": "^1.19.0",
"circular-dependency-plugin": "^5.2.0",
"codelyzer": "^6.0.0",
@ -51,22 +68,6 @@
"@ng-select/ng-option-highlight": "0.0.5",
"@ng-select/ng-select": "^4.0.4",
"@sentry/browser": "^5.13.0",
"@types/assertion-error": "^1.1.0",
"@types/chart.js": "^2.9.20",
"@types/codemirror": "0.0.87",
"@types/dragula": "^3.7.0",
"@types/es6-shim": "^0.31.39",
"@types/hammerjs": "^2.0.36",
"@types/jquery": "^3.3.33",
"@types/jqueryui": "^1.12.10",
"@types/lodash": "^4.14.149",
"@types/moment-timezone": "^0.5.12",
"@types/mousetrap": "^1.6.3",
"@types/pako": "^1.0.1",
"@types/promises-a-plus": "0.0.27",
"@types/rosie": "0.0.37",
"@types/urijs": "^1.19.6",
"@types/webpack-env": "^1.15.1",
"@uirouter/angular": "^7.0.0",
"@uirouter/core": "^6.0.6",
"@uirouter/rx": "^0.6.5",

@ -24,7 +24,8 @@ import {WorkPackagesListChecksumService} from "core-components/wp-list/wp-list-c
import {OpTitleService} from "core-components/html/op-title.service";
import dayGridPlugin from '@fullcalendar/daygrid';
import {CalendarOptions, EventApi, EventInput} from '@fullcalendar/core';
import {take} from 'rxjs/operators';
import {Subject} from "rxjs";
import {take, debounceTime} from 'rxjs/operators';
import {ToolbarInput} from '@fullcalendar/common';
import {ConfigurationService} from "core-app/modules/common/config/configuration.service";
import {UntilDestroyedMixin} from "core-app/helpers/angular/until-destroyed.mixin";
@ -41,26 +42,42 @@ interface CalendarViewEvent {
selector: 'wp-calendar',
})
export class WorkPackagesCalendarController extends UntilDestroyedMixin implements OnInit {
private resizeObserver:ResizeObserver;
private resizeSubject = new Subject<any>();
private ucCalendar:FullCalendarComponent;
@ViewChild(FullCalendarComponent)
set container(v:FullCalendarComponent|undefined) {
// ViewChild reference may be undefined initially
// due to ngIf
if (v !== undefined) {
this.ucCalendar = v;
// The full-calendar component's outputs do not seem to work
// see: https://github.com/fullcalendar/fullcalendar-angular/issues/228#issuecomment-523505044
// Therefore, setting the outputs via the underlying API
this.ucCalendar.getApi().setOption('eventDidMount', (event:CalendarViewEvent) => {
this.addTooltip(event);
});
this.ucCalendar.getApi().setOption('eventClick', (event:CalendarViewEvent) => {
this.toWPFullView(event);
});
}
set container(v:FullCalendarComponent|undefined) {
// ViewChild reference may be undefined initially
// due to ngIf
if (!v) {
return;
}
this.ucCalendar = v;
// The full-calendar component's outputs do not seem to work
// see: https://github.com/fullcalendar/fullcalendar-angular/issues/228#issuecomment-523505044
// Therefore, setting the outputs via the underlying API
this.ucCalendar.getApi().setOption('eventDidMount', (event:CalendarViewEvent) => {
this.addTooltip(event);
});
this.ucCalendar.getApi().setOption('eventClick', (event:CalendarViewEvent) => {
this.toWPFullView(event);
});
}
@ViewChild('ucCalendar', { read: ElementRef })
set ucCalendarElement(v:ElementRef|undefined) {
if (!v) {
return;
}
if (!this.resizeObserver) {
this.resizeObserver = new ResizeObserver(() => this.resizeSubject.next());
}
this.resizeObserver.observe(v.nativeElement);
}
@Input() projectIdentifier:string;
@Input() static:boolean = false;
static MAX_DISPLAYED = 100;
@ -88,6 +105,12 @@ export class WorkPackagesCalendarController extends UntilDestroyedMixin implemen
}
ngOnInit() {
this.resizeSubject
.pipe(debounceTime(50))
.subscribe(() => {
this.ucCalendar.getApi().updateSize();
});
// Clear any old subscribers
this.querySpace.stopAllSubscriptions.next();

@ -13,6 +13,7 @@
/// <reference path="../../node_modules/@types/webpack-env/index.d.ts" />
/// <reference path="../../node_modules/@types/es6-shim/index.d.ts" />
/// <reference path="../../node_modules/@types/dragula/index.d.ts" />
/// <reference path="../../node_modules/@types/resize-observer-browser/index.d.ts" />
import {ErrorReporter} from "core-app/sentry/sentry-reporter";
import {Injector} from '@angular/core';

Loading…
Cancel
Save