Skip to content

Commit

Permalink
[46837] Preview of linked WP is cut off in split view when close to t…
Browse files Browse the repository at this point in the history
…he edge (#12801)

* set the right value of the preview modal to zero

* use floating-ui/dom library for repositioning

* undo style changes

* fix eslint errors
  • Loading branch information
bsatarnejad committed Jul 17, 2023
1 parent b646fcf commit cff4174
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 34 deletions.
Expand Up @@ -36,31 +36,37 @@ export class PreviewTriggerService {

private mouseInModal = false;

constructor(readonly opModalService:OpModalService,
constructor(
readonly opModalService:OpModalService,
readonly ngZone:NgZone,
readonly injector:Injector) {
readonly injector:Injector,
) {
}

setupListener() {
jQuery(document.body).on('mouseover', '.preview-trigger', (e) => {
e.preventDefault();
e.stopPropagation();
const el = jQuery(e.target);
const href = el.attr('href');
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const el = e.target as HTMLElement;
if (el) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const href = el.getAttribute('href');

if (!href) {
return;
}
if (!href) {
return;
}

this.opModalService.show(
WpPreviewModalComponent,
this.injector,
{ workPackageLink: href, event: e },
true,
).subscribe((previewModal) => {
this.modalElement = previewModal.elementRef.nativeElement as HTMLElement;
previewModal.reposition(jQuery(this.modalElement), el);
});
this.opModalService.show(
WpPreviewModalComponent,
this.injector,
{ workPackageLink: href, event: e },
true,
).subscribe((previewModal) => {
this.modalElement = previewModal.elementRef.nativeElement as HTMLElement;
void previewModal.reposition(this.modalElement, el);
});
}
});

jQuery(document.body).on('mouseleave', '.preview-trigger', () => {
Expand Down Expand Up @@ -93,11 +99,12 @@ export class PreviewTriggerService {
}

const previewElement = jQuery(this.modalElement.children[0]);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (previewElement && previewElement.offset()) {
const horizontalHover = e.pageX >= Math.floor(previewElement.offset()!.left)
&& e.pageX < previewElement.offset()!.left + previewElement.width()!;
const verticalHover = e.pageY >= Math.floor(previewElement.offset()!.top)
&& e.pageY < previewElement.offset()!.top + previewElement.height()!;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const horizontalHover = e.pageX >= Math.floor(previewElement.offset()!.left) && e.pageX < previewElement.offset()!.left + previewElement.width()!;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const verticalHover = e.pageY >= Math.floor(previewElement.offset()!.top) && e.pageY < previewElement.offset()!.top + previewElement.height()!;
return horizontalHover && verticalHover;
}
return false;
Expand Down
Expand Up @@ -27,7 +27,13 @@
//++

import {
ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Inject, OnInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
Inject,
OnInit,
Input,
} from '@angular/core';
import { OpModalComponent } from 'core-app/shared/components/modal/modal.component';
import { OpModalLocalsToken, OpModalService } from 'core-app/shared/components/modal/modal.service';
Expand All @@ -37,6 +43,13 @@ import { WorkPackageResource } from 'core-app/features/hal/resources/work-packag
import idFromLink from 'core-app/features/hal/helpers/id-from-link';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { StateService } from '@uirouter/core';
import {
computePosition,
flip,
limitShift,
Placement,
shift,
} from '@floating-ui/dom';

@Component({
templateUrl: './wp-preview.modal.html',
Expand All @@ -50,20 +63,26 @@ export class WpPreviewModalComponent extends OpModalComponent implements OnInit
created_by: this.i18n.t('js.label_created_by'),
};

constructor(readonly elementRef:ElementRef,
@Input() public alignment?:Placement = 'bottom-end';

@Input() public allowRepositioning? = true;

constructor(
readonly elementRef:ElementRef,
@Inject(OpModalLocalsToken) readonly locals:OpModalLocalsMap,
readonly cdRef:ChangeDetectorRef,
readonly i18n:I18nService,
readonly apiV3Service:ApiV3Service,
readonly opModalService:OpModalService,
readonly $state:StateService) {
readonly $state:StateService,
) {
super(locals, cdRef, elementRef);
}

ngOnInit() {
super.ngOnInit();
const { workPackageLink } = this.locals;
const workPackageId = idFromLink(workPackageLink);
const workPackageId = idFromLink(workPackageLink as string|null);

this
.apiV3Service
Expand All @@ -74,23 +93,37 @@ export class WpPreviewModalComponent extends OpModalComponent implements OnInit
this.workPackage = workPackage;
this.cdRef.detectChanges();

const modal = jQuery(this.elementRef.nativeElement);
this.reposition(modal, this.locals.event.target);
const modal = this.elementRef.nativeElement as HTMLElement;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-explicit-any
void this.reposition(modal, this.locals.event.target as HTMLElement);
});
}

public reposition(element:JQuery<HTMLElement>, target:JQuery<HTMLElement>) {
element.position({
my: 'right top',
at: 'right bottom',
of: target,
collision: 'flipfit',
public async reposition(element:HTMLElement, target:HTMLElement) {
const floatingEl = element.children[0] as HTMLElement;
const { x, y } = await computePosition(
target,
floatingEl,
{
placement: this.alignment,
middleware: this.allowRepositioning ? [
flip({
mainAxis: true,
crossAxis: true,
fallbackAxisSideDirection: 'start',
}),
shift({ limiter: limitShift() }),
] : [],
},
);
Object.assign(floatingEl.style, {
left: `${x}px`,
top: `${y}px`,
});
}

public openStateLink(event:{ workPackageId:string; requestedState:string }) {
const params = { workPackageId: event.workPackageId };

this.$state.go(event.requestedState, params);
void this.$state.go(event.requestedState, params);
}
}

0 comments on commit cff4174

Please sign in to comment.