Skip to content

Commit

Permalink
Rename "wpPreviewModal" to a more generic "hoverCard" and use a turbo…
Browse files Browse the repository at this point in the history
…Frame inside to be more flexible about the content
  • Loading branch information
HDinger committed Oct 2, 2024
1 parent df3cd50 commit 92a09fc
Show file tree
Hide file tree
Showing 20 changed files with 128 additions and 103 deletions.
37 changes: 37 additions & 0 deletions app/controllers/work_packages/hover_card_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See COPYRIGHT and LICENSE files for more details.
#++
module WorkPackages
class HoverCardController < ApplicationController
before_action :load_and_authorize_in_optional_project

def show
@id = params[:id]
render layout: nil
end
end
end
2 changes: 1 addition & 1 deletion app/helpers/work_packages_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def send_notification_option(checked = false)

# Returns a string of css classes that apply to the issue
def work_package_css_classes(work_package)
s = "work_package preview-trigger".html_safe
s = "work_package op-hover-card--preview-trigger".html_safe
s << " status-#{work_package.status.position}" if work_package.status
s << " priority-#{work_package.priority.position}" if work_package.priority
s << " closed" if work_package.closed?
Expand Down
3 changes: 3 additions & 0 deletions app/views/work_packages/hover_card/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<turbo-frame id="op-hover-card-body">
Hallo WELT
</turbo-frame>
3 changes: 2 additions & 1 deletion config/initializers/permissions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@
work_packages: %i[show index],
work_packages_api: [:get],
"work_packages/reports": %i[report report_details],
"work_packages/menus": %i[show]
"work_packages/menus": %i[show],
"work_packages/hover_card": %i[show]
},
permissible_on: %i[work_package project],
contract_actions: { work_packages: %i[read] }
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,8 @@
resources :work_packages, only: [:index] do
concerns :shareable

get "hover_card" => "work_packages/hover_card#show", on: :member

# move bulk of wps
get "move/new" => "work_packages/moves#new", on: :collection, as: "new_move"
post "move" => "work_packages/moves#create", on: :collection, as: "move"
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { OpenprojectDashboardsModule } from 'core-app/features/dashboards/openpr
import {
OpenprojectWorkPackageGraphsModule,
} from 'core-app/shared/components/work-package-graphs/openproject-work-package-graphs.module';
import { PreviewTriggerService } from 'core-app/core/setup/globals/global-listeners/preview-trigger.service';
import { HoverCardTriggerService } from 'core-app/core/setup/globals/global-listeners/hover-card-trigger.service';
import { OpenprojectOverviewModule } from 'core-app/features/overview/openproject-overview.module';
import { OpenprojectMyPageModule } from 'core-app/features/my-page/openproject-my-page.module';
import { OpenprojectProjectsModule } from 'core-app/features/projects/openproject-projects.module';
Expand All @@ -77,8 +77,8 @@ import {
PasswordConfirmationModalComponent,
} from 'core-app/shared/components/modals/request-for-confirmation/password-confirmation.modal';
import {
WpPreviewModalComponent,
} from 'core-app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal';
HoverCardComponent,
} from 'core-app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal';
import {
OpHeaderProjectSelectComponent,
} from 'core-app/shared/components/header-project-select/header-project-select.component';
Expand Down Expand Up @@ -240,7 +240,7 @@ import { SpotSwitchComponent } from 'core-app/spot/components/switch/switch.comp

export function initializeServices(injector:Injector) {
return () => {
const PreviewTrigger = injector.get(PreviewTriggerService);
const PreviewTrigger = injector.get(HoverCardTriggerService);
const topMenuService = injector.get(TopMenuService);
const keyboardShortcuts = injector.get(KeyboardShortcutService);
// Conditionally add the Revit Add-In settings button
Expand Down Expand Up @@ -370,7 +370,7 @@ export function initializeServices(injector:Injector) {
ConfirmDialogModalComponent,
DynamicContentModalComponent,
PasswordConfirmationModalComponent,
WpPreviewModalComponent,
HoverCardComponent,

// Main menu
MainMenuResizerComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@

import { Injectable, Injector, NgZone } from '@angular/core';
import { OpModalService } from 'core-app/shared/components/modal/modal.service';
import { WpPreviewModalComponent } from 'core-app/shared/components/modals/preview-modal/wp-preview-modal/wp-preview.modal';
import { HoverCardComponent } from 'core-app/shared/components/modals/preview-modal/hover-card-modal/hover-card.modal';

@Injectable({ providedIn: 'root' })
export class PreviewTriggerService {
export class HoverCardTriggerService {
private modalElement:HTMLElement;

private mouseInModal = false;
Expand All @@ -44,7 +44,7 @@ export class PreviewTriggerService {
}

setupListener() {
jQuery(document.body).on('mouseover', '.preview-trigger', (e) => {
jQuery(document.body).on('mouseover', '.op-hover-card--preview-trigger', (e) => {
e.preventDefault();
e.stopPropagation();
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
Expand All @@ -58,8 +58,9 @@ export class PreviewTriggerService {
}

this.opModalService.show(
WpPreviewModalComponent,
HoverCardComponent,
this.injector,
// TODO
{ workPackageLink: href, event: e },
true,
).subscribe((previewModal) => {
Expand All @@ -69,16 +70,16 @@ export class PreviewTriggerService {
}
});

jQuery(document.body).on('mouseleave', '.preview-trigger', () => {
jQuery(document.body).on('mouseleave', '.op-hover-card--preview-trigger', () => {
this.closeAfterTimeout();
});

jQuery(document.body).on('mouseleave', '.op-wp-preview-modal', () => {
jQuery(document.body).on('mouseleave', '.op-hover-card', () => {
this.mouseInModal = false;
this.closeAfterTimeout();
});

jQuery(document.body).on('mouseenter', '.op-wp-preview-modal', () => {
jQuery(document.body).on('mouseenter', '.op-hover-card', () => {
this.mouseInModal = true;
});
}
Expand All @@ -92,21 +93,4 @@ export class PreviewTriggerService {
}, 100);
});
}

private isMouseOverPreview(e:JQuery.MouseLeaveEvent) {
if (!this.modalElement) {
return false;
}

const previewElement = jQuery(this.modalElement.children[0]);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
if (previewElement && previewElement.offset()) {
// 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[displayFieldOptions]="{ writable: false }"
fieldName="type">
</display-field>
<a class="work-package--quickinfo preview-trigger"
<a class="op-hover-card--preview-trigger"
target="_top"
[href]="workPackageLink"
[attr.data-work-package-id]="workPackage.id">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div
class="op-hover-card"
*ngIf="turboFrameSrc"
>
<turbo-frame
loading="lazy"
id="op-hover-card-body"
[src]="turboFrameSrc">
<op-content-loader
viewBox="0 0 180 80"
>
<svg:rect x="10" y="10" width="80%" height="16" rx="1" />
<svg:rect x="10" y="30" width="80%" height="16" rx="1" />
<svg:rect x="10" y="50" width="60%" height="16" rx="1" />
</op-content-loader>
</turbo-frame>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@import "helpers"

.op-hover-card
position: absolute
background-color: var(--body-background)
z-index: 5000
min-width: 350px
box-shadow: var(--shadow-floating-large)
pointer-events: all
padding: 1rem
Original file line number Diff line number Diff line change
Expand Up @@ -32,75 +32,70 @@ import {
Component,
ElementRef,
Inject,
OnInit,
Input,
OnInit,
} from '@angular/core';
import { OpModalComponent } from 'core-app/shared/components/modal/modal.component';
import { OpModalLocalsToken, OpModalService } from 'core-app/shared/components/modal/modal.service';
import { OpModalLocalsToken } from 'core-app/shared/components/modal/modal.service';
import { OpModalLocalsMap } from 'core-app/shared/components/modal/modal.types';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource';
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';
import { WorkPackageIsolatedQuerySpaceDirective } from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive';
import { fromEvent } from 'rxjs';
import {
WorkPackageIsolatedQuerySpaceDirective,
} from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive';
filter,
tap,
throttleTime,
} from 'rxjs/operators';

@Component({
templateUrl: './wp-preview.modal.html',
styleUrls: ['./wp-preview.modal.sass'],
templateUrl: './hover-card.modal.html',
styleUrls: ['./hover-card.modal.sass'],
changeDetection: ChangeDetectionStrategy.OnPush,
hostDirectives: [WorkPackageIsolatedQuerySpaceDirective],
})
export class WpPreviewModalComponent extends OpModalComponent implements OnInit {
public workPackage:WorkPackageResource;

public text = {
created_by: this.i18n.t('js.label_created_by'),
};
export class HoverCardComponent extends OpModalComponent implements OnInit {
@Input() public turboFrameSrc:string = "/work_packages/50/hover_card";

@Input() public alignment?:Placement = 'bottom-end';

@Input() public allowRepositioning? = true;

public test:string;

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

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

this
.apiV3Service
.work_packages
.id(workPackageId)
.requireAndStream()
.subscribe((workPackage:WorkPackageResource) => {
this.workPackage = workPackage;
this.cdRef.detectChanges();
this.test = this.turboFrameSrc;

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);
});
// TODO
fromEvent(document, 'turbo:frame-load')
.pipe(
filter((event:CustomEvent) => {
return (event.target as HTMLElement).id?.includes('op-hover-card-body');
}),
throttleTime(100),
tap(() => {
this.cdRef.detectChanges();

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 async reposition(element:HTMLElement, target:HTMLElement) {
Expand All @@ -125,9 +120,4 @@ export class WpPreviewModalComponent extends OpModalComponent implements OnInit
top: `${y}px`,
});
}

public openStateLink(event:{ workPackageId:string; requestedState:string }) {
const params = { workPackageId: event.workPackageId };
void this.$state.go(event.requestedState, params);
}
}

This file was deleted.

This file was deleted.

2 changes: 1 addition & 1 deletion lib/open_project/text_formatting/filters/mention_filter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def group_mention(group)
def work_package_mention(work_package)
link_to("##{work_package.id}",
work_package_path_or_url(id: work_package.id, only_path: context[:only_path]),
class: "issue work_package preview-trigger")
class: "issue work_package op-hover-card--preview-trigger")
end

def class_from_mention(mention)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def render_work_package_macro(wp_id, detailed: false)
def render_work_package_link(wp_id)
link_to("##{wp_id}",
work_package_path_or_url(id: wp_id, only_path: context[:only_path]),
class: "issue work_package preview-trigger")
class: "issue work_package op-hover-card--preview-trigger")
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@

wp_page.expect_comment text: "Single ##{work_package2.id}"
expect(page).to have_css(".user-comment opce-macro-wp-quickinfo", count: 2)
expect(page).to have_css(".user-comment .work-package--quickinfo.preview-trigger", count: 2)
expect(page).to have_css(".user-comment .op-hover-card--preview-trigger", count: 2)
end
end

Expand Down
Loading

0 comments on commit 92a09fc

Please sign in to comment.