Merge pull request #8070 from opf/feature/bim-view-toggle
Readd view toggle componentpull/8078/head
commit
fbdef4729d
@ -0,0 +1,94 @@ |
||||
//-- copyright
|
||||
// OpenProject is an open source project management software.
|
||||
// Copyright (C) 2012-2020 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 docs/COPYRIGHT.rdoc for more details.
|
||||
//++
|
||||
|
||||
import {OPContextMenuService} from "core-components/op-context-menu/op-context-menu.service"; |
||||
import {Directive, ElementRef} from "@angular/core"; |
||||
import {OpContextMenuTrigger} from "core-components/op-context-menu/handlers/op-context-menu-trigger.directive"; |
||||
import {I18nService} from "core-app/modules/common/i18n/i18n.service"; |
||||
import { |
||||
bimListViewIdentifier, |
||||
bimSplitViewIdentifier, |
||||
bimViewerViewIdentifier |
||||
} from "core-app/modules/ifc_models/view-toggle/bim-view-toggle.component"; |
||||
import {StateService} from "@uirouter/core"; |
||||
import {BimViewService} from "core-app/modules/ifc_models/view-toggle/bim-view.service"; |
||||
|
||||
@Directive({ |
||||
selector: '[bimViewDropdown]' |
||||
}) |
||||
export class BimViewToggleDropdownDirective extends OpContextMenuTrigger { |
||||
constructor(readonly elementRef:ElementRef, |
||||
readonly opContextMenu:OPContextMenuService, |
||||
readonly bimView:BimViewService, |
||||
readonly I18n:I18nService, |
||||
readonly state:StateService) { |
||||
|
||||
super(elementRef, opContextMenu); |
||||
} |
||||
|
||||
protected open(evt:JQuery.TriggeredEvent) { |
||||
this.buildItems(); |
||||
this.opContextMenu.show(this, evt); |
||||
} |
||||
|
||||
public get locals() { |
||||
return { |
||||
items: this.items, |
||||
contextMenuId: 'bim-view-context-menu' |
||||
}; |
||||
} |
||||
|
||||
private buildItems() { |
||||
const current = this.bimView.current; |
||||
const viewRoute = this.state.current.data.viewRoute; |
||||
|
||||
this.items = [bimViewerViewIdentifier, bimListViewIdentifier, bimSplitViewIdentifier] |
||||
.map(key => { |
||||
return { |
||||
hidden: key === current, |
||||
linkText: this.bimView.text[key], |
||||
onClick: () => { |
||||
switch (key) { |
||||
case bimListViewIdentifier: |
||||
this.state.go('bim.space.list'); |
||||
break; |
||||
case bimViewerViewIdentifier: |
||||
this.state.go(viewRoute + '.model'); |
||||
break; |
||||
case bimSplitViewIdentifier: |
||||
this.state.go(viewRoute); |
||||
break; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
}; |
||||
}); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,62 @@ |
||||
// -- copyright
|
||||
// OpenProject is an open source project management software.
|
||||
// Copyright (C) 2012-2020 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 docs/COPYRIGHT.rdoc for more details.
|
||||
// ++
|
||||
|
||||
import {ChangeDetectionStrategy, Component} from '@angular/core'; |
||||
import {I18nService} from 'core-app/modules/common/i18n/i18n.service'; |
||||
import {BimViewService} from "core-app/modules/ifc_models/view-toggle/bim-view.service"; |
||||
|
||||
|
||||
export const bimListViewIdentifier = 'list'; |
||||
export const bimViewerViewIdentifier = 'viewer'; |
||||
export const bimSplitViewIdentifier = 'split'; |
||||
|
||||
@Component({ |
||||
template: ` |
||||
<ng-container *ngIf="(view$ | async) as current"> |
||||
<button class="button" |
||||
id="bim-view-toggle-button" |
||||
bimViewDropdown> |
||||
<span class="button--text" |
||||
aria-hidden="true" |
||||
[textContent]="bimView.text[current]"> |
||||
</span> |
||||
<op-icon icon-classes="button--icon icon-small icon-pulldown"></op-icon> |
||||
</button> |
||||
</ng-container> |
||||
`,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush, |
||||
selector: 'bim-view-toggle-button' |
||||
}) |
||||
export class BimViewToggleComponent { |
||||
|
||||
view$ = this.bimView.view.values$(); |
||||
|
||||
constructor(readonly I18n:I18nService, |
||||
readonly bimView:BimViewService) { |
||||
} |
||||
} |
@ -0,0 +1,91 @@ |
||||
// -- copyright
|
||||
// OpenProject is an open source project management software.
|
||||
// Copyright (C) 2012-2020 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 docs/COPYRIGHT.rdoc for more details.
|
||||
// ++
|
||||
|
||||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Injectable, OnDestroy, OnInit} from '@angular/core'; |
||||
import {I18nService} from 'core-app/modules/common/i18n/i18n.service'; |
||||
import {DynamicBootstrapper} from "core-app/globals/dynamic-bootstrapper"; |
||||
import { |
||||
WorkPackageViewDisplayRepresentationService, |
||||
wpDisplayCardRepresentation, |
||||
wpDisplayListRepresentation, wpDisplayRepresentation |
||||
} from "core-app/modules/work_packages/routing/wp-view-base/view-services/wp-view-display-representation.service"; |
||||
import {untilComponentDestroyed} from "ng2-rx-componentdestroyed"; |
||||
import {WorkPackageViewTimelineService} from "core-app/modules/work_packages/routing/wp-view-base/view-services/wp-view-timeline.service"; |
||||
import {combineLatest, Observable} from "rxjs"; |
||||
import {StateService, TransitionService} from "@uirouter/core"; |
||||
import {input} from "reactivestates"; |
||||
import {OpenprojectIFCModelsModule} from "core-app/modules/ifc_models/openproject-ifc-models.module"; |
||||
|
||||
|
||||
export const bimListViewIdentifier = 'list'; |
||||
export const bimViewerViewIdentifier = 'viewer'; |
||||
export const bimSplitViewIdentifier = 'split'; |
||||
|
||||
export type BimViewState = 'list'|'viewer'|'split'; |
||||
|
||||
@Injectable({ providedIn: OpenprojectIFCModelsModule }) |
||||
export class BimViewService implements OnDestroy { |
||||
public view = input<BimViewState>(); |
||||
|
||||
public text:any = { |
||||
list: this.I18n.t('js.ifc_models.views.list'), |
||||
viewer: this.I18n.t('js.ifc_models.views.viewer'), |
||||
split: this.I18n.t('js.ifc_models.views.split') |
||||
}; |
||||
|
||||
private transitionFn:Function; |
||||
|
||||
constructor(readonly I18n:I18nService, |
||||
readonly transitions:TransitionService, |
||||
readonly state:StateService) { |
||||
|
||||
this.detectView(); |
||||
|
||||
this.transitionFn = this.transitions.onSuccess({}, (transition) => { |
||||
this.detectView(); |
||||
}); |
||||
} |
||||
|
||||
get current():BimViewState { |
||||
return this.view.getValueOr(bimSplitViewIdentifier); |
||||
} |
||||
|
||||
private detectView() { |
||||
if (this.state.current.name === 'bim.space.list') { |
||||
this.view.putValue(bimListViewIdentifier); |
||||
} else if (this.state.includes('bim.**.model')) { |
||||
this.view.putValue(bimViewerViewIdentifier); |
||||
} else { |
||||
this.view.putValue(bimSplitViewIdentifier); |
||||
} |
||||
} |
||||
|
||||
ngOnDestroy() { |
||||
this.transitionFn(); |
||||
} |
||||
} |
@ -0,0 +1,102 @@ |
||||
#-- copyright |
||||
# OpenProject is an open source project management software. |
||||
# Copyright (C) 2012-2020 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-2017 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 docs/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
require_relative '../support/pages/ifc_models/show' |
||||
require_relative '../support/pages/ifc_models/show_default' |
||||
|
||||
describe 'BIM navigation spec', type: :feature, js: true do |
||||
let(:project) { FactoryBot.create :project, enabled_module_names: [:bim, :work_package_tracking] } |
||||
let!(:work_package) { FactoryBot.create(:work_package, project: project) } |
||||
let(:role) { FactoryBot.create(:role, permissions: %i[view_ifc_models manage_ifc_models view_work_packages]) } |
||||
|
||||
let(:user) do |
||||
FactoryBot.create :user, |
||||
member_in_project: project, |
||||
member_through_role: role |
||||
end |
||||
|
||||
let!(:model) do |
||||
FactoryBot.create(:ifc_model_converted, |
||||
project: project, |
||||
uploader: user) |
||||
end |
||||
|
||||
let(:card_view) { ::Pages::WorkPackageCards.new(project) } |
||||
|
||||
|
||||
shared_examples 'can switch from split to viewer to list-only' do |
||||
before do |
||||
login_as(user) |
||||
model_page.visit! |
||||
model_page.finished_loading |
||||
end |
||||
|
||||
context 'deep link on the page' do |
||||
before do |
||||
login_as(user) |
||||
model_page.visit! |
||||
model_page.finished_loading |
||||
end |
||||
|
||||
it 'can switch from split to viewer only to list' do |
||||
# Should be at split view |
||||
model_page.model_viewer_visible true |
||||
model_page.model_viewer_shows_a_toolbar true |
||||
model_page.page_shows_a_toolbar true |
||||
model_page.sidebar_shows_viewer_menu true |
||||
expect(page).to have_selector('.wp-cards-container') |
||||
card_view.expect_work_package_listed work_package |
||||
|
||||
# Go to viewer only |
||||
model_page.switch_view 'Viewer only' |
||||
|
||||
model_page.model_viewer_visible true |
||||
expect(page).to have_no_selector('.wp-cards-container') |
||||
|
||||
# Go to list only |
||||
model_page.switch_view 'List only' |
||||
|
||||
model_page.model_viewer_visible false |
||||
expect(page).to have_selector('.wp-cards-container') |
||||
card_view.expect_work_package_listed work_package |
||||
end |
||||
end |
||||
end |
||||
|
||||
context 'on default page' do |
||||
let(:model_page) { ::Pages::IfcModels::ShowDefault.new project } |
||||
it_behaves_like 'can switch from split to viewer to list-only' |
||||
end |
||||
|
||||
context 'on show page' do |
||||
let(:model_page) { ::Pages::IfcModels::Show.new project, model.id } |
||||
it_behaves_like 'can switch from split to viewer to list-only' |
||||
end |
||||
end |
Loading…
Reference in new issue