Merge pull request #9985 from opf/bug/40267-opening-viewpoints-from-gallery-does-not-work-on-mobile

[#40267] Opening viewpoints on mobile
pull/10015/head
Eric Schubert 3 years ago committed by GitHub
commit ad2c13fb5c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      frontend/src/app/features/bim/ifc_models/bcf/list/bcf-list.component.html
  2. 30
      frontend/src/app/features/bim/ifc_models/bcf/list/bcf-list.component.ts
  3. 13
      frontend/src/app/features/bim/ifc_models/openproject-ifc-models.routes.ts
  4. 1
      frontend/src/app/features/bim/ifc_models/pages/viewer/ifc-viewer-page.component.ts
  5. 3
      frontend/src/app/features/work-packages/components/wp-card-view/wp-single-card/wp-single-card.component.ts
  6. 9
      frontend/src/app/features/work-packages/routing/split-view-routes.template.ts
  7. 2
      frontend/src/app/features/work-packages/routing/wp-list-view/wp-list-view.component.ts
  8. 7
      frontend/src/global_styles/content/modules/_bim.sass
  9. 8
      modules/bim/spec/features/bim_navigation_spec.rb
  10. 2
      modules/bim/spec/features/viewer/show_viewpoint_spec.rb
  11. 5
      spec/support/pages/work_packages/work_package_cards.rb

@ -24,7 +24,7 @@
[ngClass]="{ '_with-resizer': showResizerInCardView() }"> [ngClass]="{ '_with-resizer': showResizerInCardView() }">
<wp-grid [configuration]="wpTableConfiguration" <wp-grid [configuration]="wpTableConfiguration"
[showResizer]="showResizerInCardView()" [showResizer]="showResizerInCardView()"
(itemClicked)="handleWorkPackageCardClicked($event)" (itemClicked)="handleWorkPackageClicked($event)"
(stateLinkClicked)="openStateLink($event)" (stateLinkClicked)="openStateLink($event)"
resizerClass="work-packages-partitioned-page--content-right" resizerClass="work-packages-partitioned-page--content-right"
resizerStorageKey="openProject-splitViewFlexBasis"> resizerStorageKey="openProject-splitViewFlexBasis">

@ -29,22 +29,28 @@
import { import {
ChangeDetectionStrategy, Component, Input, NgZone, OnInit, ChangeDetectionStrategy, Component, Input, NgZone, OnInit,
} from '@angular/core'; } from '@angular/core';
import { WorkPackageListViewComponent } from 'core-app/features/work-packages/routing/wp-list-view/wp-list-view.component';
import { HalResourceNotificationService } from 'core-app/features/hal/services/hal-resource-notification.service';
import { WorkPackageNotificationService } from 'core-app/features/work-packages/services/notifications/work-package-notification.service';
import { DragAndDropService } from 'core-app/shared/helpers/drag-and-drop/drag-and-drop.service';
import { CausedUpdatesService } from 'core-app/features/boards/board/caused-updates/caused-updates.service';
import { BcfViewService } from 'core-app/features/bim/ifc_models/pages/viewer/bcf-view.service';
import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator';
import { IfcModelsDataService } from 'core-app/features/bim/ifc_models/pages/viewer/ifc-models-data.service';
import { WorkPackageViewColumnsService } from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-columns.service';
import { UIRouterGlobals } from '@uirouter/core'; import { UIRouterGlobals } from '@uirouter/core';
import { States } from 'core-app/core/states/states.service'; import { States } from 'core-app/core/states/states.service';
import { InjectField } from 'core-app/shared/helpers/angular/inject-field.decorator';
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin';
import { DragAndDropService } from 'core-app/shared/helpers/drag-and-drop/drag-and-drop.service';
import { BcfApiService } from 'core-app/features/bim/bcf/api/bcf-api.service'; import { BcfApiService } from 'core-app/features/bim/bcf/api/bcf-api.service';
import { QueryResource } from 'core-app/features/hal/resources/query-resource';
import { BcfViewService } from 'core-app/features/bim/ifc_models/pages/viewer/bcf-view.service';
import { splitViewRoute } from 'core-app/features/work-packages/routing/split-view-routes.helper'; import { splitViewRoute } from 'core-app/features/work-packages/routing/split-view-routes.helper';
import { ViewerBridgeService } from 'core-app/features/bim/bcf/bcf-viewer-bridge/viewer-bridge.service'; import { ViewerBridgeService } from 'core-app/features/bim/bcf/bcf-viewer-bridge/viewer-bridge.service';
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin'; import { CausedUpdatesService } from 'core-app/features/boards/board/caused-updates/caused-updates.service';
import { QueryResource } from 'core-app/features/hal/resources/query-resource'; import { IfcModelsDataService } from 'core-app/features/bim/ifc_models/pages/viewer/ifc-models-data.service';
import { HalResourceNotificationService } from 'core-app/features/hal/services/hal-resource-notification.service';
import {
WorkPackageListViewComponent,
} from 'core-app/features/work-packages/routing/wp-list-view/wp-list-view.component';
import {
WorkPackageViewColumnsService,
} from 'core-app/features/work-packages/routing/wp-view-base/view-services/wp-view-columns.service';
import {
WorkPackageNotificationService,
} from 'core-app/features/work-packages/services/notifications/work-package-notification.service';
@Component({ @Component({
templateUrl: './bcf-list.component.html', templateUrl: './bcf-list.component.html',
@ -118,7 +124,7 @@ export class BcfListComponent extends WorkPackageListViewComponent implements Un
} }
} }
if (double) { if (double || this.deviceService.isMobile) {
this.goToWpDetailState(workPackageId, this.uIRouterGlobals.params.cards); this.goToWpDetailState(workPackageId, this.uIRouterGlobals.params.cards);
} }
} }

@ -56,6 +56,9 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
redirectTo: 'bim.partitioned.list', redirectTo: 'bim.partitioned.list',
url: '', url: '',
component: IFCViewerPageComponent, component: IFCViewerPageComponent,
data: {
bodyClasses: 'router--bim',
},
}, },
{ {
name: 'bim.partitioned.list', name: 'bim.partitioned.list',
@ -85,7 +88,7 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
}, },
{ {
name: 'bim.partitioned.show', name: 'bim.partitioned.show',
url: '/show/{workPackageId:[0-9]+}?{cards:bool}', url: '/show/{workPackageId:[0-9]+}',
data: { data: {
baseRoute: 'bim.partitioned.list', baseRoute: 'bim.partitioned.list',
partition: '-left-only', partition: '-left-only',
@ -93,19 +96,23 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
reloadOnSearch: false, reloadOnSearch: false,
redirectTo: 'bim.partitioned.show.details', redirectTo: 'bim.partitioned.show.details',
}, },
// BCF single view for list // BCF full view detail routes for usage in revit addi-in
...makeSplitViewRoutes( ...makeSplitViewRoutes(
'bim.partitioned.list', 'bim.partitioned.list',
undefined, undefined,
WorkPackageSplitViewComponent, WorkPackageSplitViewComponent,
undefined, undefined,
true, true,
false,
'bim.partitioned.show', 'bim.partitioned.show',
), ),
// BCF single view for list // BCF split view detail routes
...makeSplitViewRoutes( ...makeSplitViewRoutes(
'bim.partitioned.list', 'bim.partitioned.list',
undefined, undefined,
WorkPackageSplitViewComponent, WorkPackageSplitViewComponent,
undefined,
false,
false,
), ),
]; ];

@ -70,6 +70,7 @@ import { WorkPackageSettingsButtonComponent } from 'core-app/features/work-packa
BcfViewService, BcfViewService,
QueryParamListenerService, QueryParamListenerService,
], ],
selector: 'op-ifc-viewer-page',
}) })
export class IFCViewerPageComponent extends PartitionedQuerySpacePageComponent implements UntilDestroyedMixin, OnInit { export class IFCViewerPageComponent extends PartitionedQuerySpacePageComponent implements UntilDestroyedMixin, OnInit {
text = { text = {

@ -7,7 +7,7 @@ import {
OnInit, OnInit,
Output, Output,
} from '@angular/core'; } from '@angular/core';
import { checkedClassName, uiStateLinkClass } from 'core-app/features/work-packages/components/wp-fast-table/builders/ui-state-link-builder'; import { uiStateLinkClass } from 'core-app/features/work-packages/components/wp-fast-table/builders/ui-state-link-builder';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service'; import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { Highlighting } from 'core-app/features/work-packages/components/wp-fast-table/builders/highlighting/highlighting.functions'; import { Highlighting } from 'core-app/features/work-packages/components/wp-fast-table/builders/highlighting/highlighting.functions';
import { StateService } from '@uirouter/core'; import { StateService } from '@uirouter/core';
@ -94,6 +94,7 @@ export class WorkPackageSingleCardComponent extends UntilDestroyedMixin implemen
this.wpTableSelection.setSelection(wp.id!, this.cardView.findRenderedCard(classIdentifier)); this.wpTableSelection.setSelection(wp.id!, this.cardView.findRenderedCard(classIdentifier));
this.wpTableFocus.updateFocus(wp.id!); this.wpTableFocus.updateFocus(wp.id!);
this.stateLinkClicked.emit({ workPackageId: wp.id!, requestedState: stateToEmit }); this.stateLinkClicked.emit({ workPackageId: wp.id!, requestedState: stateToEmit });
event.preventDefault();
} }
public cardClasses():{ [className:string]:boolean } { public cardClasses():{ [className:string]:boolean } {

@ -56,6 +56,7 @@ export function makeSplitViewRoutes(baseRoute:string,
showComponent:ComponentType<unknown>, showComponent:ComponentType<unknown>,
newComponent:ComponentType<unknown> = WorkPackageNewSplitViewComponent, newComponent:ComponentType<unknown> = WorkPackageNewSplitViewComponent,
makeFullWidth?:boolean, makeFullWidth?:boolean,
showMobileAlternative = true,
routeName = baseRoute):Ng2StateDeclaration[] { routeName = baseRoute):Ng2StateDeclaration[] {
// makeFullWidth configuration // makeFullWidth configuration
const views:{ [content:string]:{ component:ComponentType<unknown>; }; } = makeFullWidth const views:{ [content:string]:{ component:ComponentType<unknown>; }; } = makeFullWidth
@ -82,7 +83,7 @@ export function makeSplitViewRoutes(baseRoute:string,
baseRoute, baseRoute,
newRoute: `${routeName}.new`, newRoute: `${routeName}.new`,
partition, partition,
mobileAlternative: 'work-packages.show', mobileAlternative: showMobileAlternative ? 'work-packages.show' : undefined,
}, },
// Retarget and by that override the grandparent views // Retarget and by that override the grandparent views
// https://ui-router.github.io/guide/views#relative-parent-state // https://ui-router.github.io/guide/views#relative-parent-state
@ -96,7 +97,7 @@ export function makeSplitViewRoutes(baseRoute:string,
baseRoute, baseRoute,
menuItem: menuItemClass, menuItem: menuItemClass,
parent: `${routeName}.details`, parent: `${routeName}.details`,
mobileAlternative: 'work-packages.show', mobileAlternative: showMobileAlternative ? 'work-packages.show' : undefined,
}, },
}, },
// Split create route // Split create route
@ -116,7 +117,7 @@ export function makeSplitViewRoutes(baseRoute:string,
// Remember the base route so we can route back to it anywhere // Remember the base route so we can route back to it anywhere
baseRoute, baseRoute,
parent: baseRoute, parent: baseRoute,
mobileAlternative: 'work-packages.show', mobileAlternative: showMobileAlternative ? 'work-packages.show' : undefined,
}, },
views: { views: {
// Retarget and by that override the grandparent views // Retarget and by that override the grandparent views
@ -139,7 +140,7 @@ export function makeSplitViewRoutes(baseRoute:string,
bodyClasses: 'router--work-packages-partitioned-split-view', bodyClasses: 'router--work-packages-partitioned-split-view',
menuItem: menuItemClass, menuItem: menuItemClass,
partition: '-split', partition: '-split',
mobileAlternative: 'work-packages.show', mobileAlternative: showMobileAlternative ? 'work-packages.show' : undefined,
}, },
}, },
]; ];

@ -188,7 +188,7 @@ export class WorkPackageListViewComponent extends UntilDestroyedMixin implements
* Special handling for clicking on cards. * Special handling for clicking on cards.
* If we are on mobile, a click on the card should directly open the full view * If we are on mobile, a click on the card should directly open the full view
*/ */
handleWorkPackageCardClicked(event:{ workPackageId:string; double:boolean }) { handleWorkPackageCardClicked(event:{ workPackageId:string; double:boolean }):void {
if (this.deviceService.isMobile) { if (this.deviceService.isMobile) {
this.openInFullView(event.workPackageId); this.openInFullView(event.workPackageId);
} else { } else {

@ -7,6 +7,7 @@
flex: 0 0 250px flex: 0 0 250px
margin: 10px margin: 10px
padding: 10px padding: 10px
&.-failed &.-failed
border: 1px solid #EAEAEA border: 1px solid #EAEAEA
@ -17,6 +18,10 @@
margin-bottom: 50px margin-bottom: 50px
table.attributes-table table.attributes-table
td,th td, th
padding: 5px padding: 5px
text-align: center text-align: center
@media only screen and (max-width: 679px)
.router--bim .work-packages--details
min-width: 0

@ -82,8 +82,8 @@ describe 'BIM navigation spec',
end end
it 'can switch between the different view modes' do it 'can switch between the different view modes' do
# Go to single view # Opening details view with info icon
card_view.open_full_screen_by_details(work_package) card_view.click_info_icon(work_package)
details_view.ensure_page_loaded details_view.ensure_page_loaded
details_view.expect_subject details_view.expect_subject
@ -115,8 +115,8 @@ describe 'BIM navigation spec',
expect(page).to have_selector('[data-qa-selector="op-wp-card-view"]') expect(page).to have_selector('[data-qa-selector="op-wp-card-view"]')
card_view.expect_work_package_listed work_package card_view.expect_work_package_listed work_package
# Go to single view # Go to details view
card_view.open_full_screen_by_details(work_package) card_view.click_id_link(work_package)
details_view.ensure_page_loaded details_view.ensure_page_loaded
details_view.expect_subject details_view.expect_subject

@ -96,7 +96,7 @@ describe 'Show viewpoint in model viewer',
context 'when in details view' do context 'when in details view' do
before do before do
card_view.open_full_screen_by_details(work_package) card_view.click_info_icon(work_package)
bcf_details.expect_viewpoint_count(1) bcf_details.expect_viewpoint_count(1)
# We need to wait a bit for xeokit to be initialized # We need to wait a bit for xeokit to be initialized

@ -90,6 +90,11 @@ module Pages
card_element.find('[data-qa-selector="op-wp-single-card--details-button"]').click card_element.find('[data-qa-selector="op-wp-single-card--details-button"]').click
end end
def click_id_link(work_package)
card_element = card(work_package)
card_element.find('.__ui-state-link').click
end
def deselect_work_package(work_package) def deselect_work_package(work_package)
element = find("wp-single-card[data-work-package-id='#{work_package.id}']") element = find("wp-single-card[data-work-package-id='#{work_package.id}']")

Loading…
Cancel
Save