Skip to content

Commit

Permalink
Merge pull request #15980 from opf/implementation/55183-replace-sidem…
Browse files Browse the repository at this point in the history
…enu-of-bim-page-with-rails-component

[55183] Replace sidemenu of BIM page with Rails component
  • Loading branch information
HDinger authored Jun 28, 2024
2 parents f676295 + 142b883 commit ce6b3ed
Show file tree
Hide file tree
Showing 19 changed files with 280 additions and 96 deletions.
16 changes: 15 additions & 1 deletion frontend/src/app/core/main-menu/submenu.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,30 @@ import { StateService } from '@uirouter/core';
export class SubmenuService {
constructor(protected $state:StateService) {}

reloadSubmenu():void {
reloadSubmenu(selectedQueryId:string|null):void {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
const menuIdentifier:string|undefined = this.$state.current.data.sideMenuOptions?.sidemenuId;

if (menuIdentifier) {
const menu = (document.getElementById(menuIdentifier) as HTMLElement&TurboElement);
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const sideMenuOptions = this.$state.$current.data?.sideMenuOptions as { hardReloadOnBaseRoute?:boolean, defaultQuery?:string };
const currentSrc = menu.getAttribute('src');

if (currentSrc && menu) {
const frameUrl = new URL(currentSrc);
const defaultQuery = sideMenuOptions.defaultQuery;

if (selectedQueryId) {
// If there is a default query passed in the route definition, it means that id passed as argument and not as parameter,
// e.g. calendars/:id, team_planner/:id, ...
// Otherwise, we will just replace the params
if (defaultQuery) {
frameUrl.search = `?id=${selectedQueryId}`;
} else {
frameUrl.search = `?query_id=${selectedQueryId}`;
}
}

// Override the frame src to enforce a reload
menu.setAttribute('src', frameUrl.href);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,18 @@ import { WorkPackagesBaseComponent } from 'core-app/features/work-packages/routi
import { BcfSplitLeftComponent } from 'core-app/features/bim/ifc_models/bcf/split/left/bcf-split-left.component';
import { BcfSplitRightComponent } from 'core-app/features/bim/ifc_models/bcf/split/right/bcf-split-right.component';

export const sidemenuId = 'bim_sidemenu';

export const sideMenuOptions = {
sidemenuId,
hardReloadOnBaseRoute: true,
};

export const IFC_ROUTES:Ng2StateDeclaration[] = [
{
name: 'bim',
parent: 'optional_project',
url: '/bcf?query_id&query_props&models&viewpoint',
url: '/bcf?query_id&query_props&models&viewpoint&name',
abstract: true,
component: WorkPackagesBaseComponent,
redirectTo: 'bim.partitioned.list',
Expand All @@ -49,6 +56,7 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
query_props: { type: 'opQueryString', dynamic: true },
models: { type: 'opQueryString', dynamic: true },
viewpoint: { type: 'int', dynamic: true },
name: { type: 'string', dynamic: true },
},
},
{
Expand All @@ -58,6 +66,7 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
component: IFCViewerPageComponent,
data: {
bodyClasses: 'router--bim',
sideMenuOptions,
},
},
{
Expand All @@ -67,6 +76,7 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
baseRoute: 'bim.partitioned.list',
newRoute: 'bim.partitioned.list.new',
partition: '-split',
sideMenuOptions,
},
reloadOnSearch: false,
views: {
Expand All @@ -83,6 +93,7 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
allowMovingInEditMode: true,
partition: '-left-only',
successState: 'bim.partitioned.show',
sideMenuOptions,
},
views: { 'content-left': { component: WorkPackageNewFullViewComponent } },
},
Expand All @@ -92,6 +103,7 @@ export const IFC_ROUTES:Ng2StateDeclaration[] = [
data: {
baseRoute: 'bim.partitioned.list',
partition: '-left-only',
sideMenuOptions,
},
reloadOnSearch: false,
redirectTo: 'bim.partitioned.show.details',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,22 @@ import {
ToolbarButtonComponentDefinition,
ViewPartitionState,
} from 'core-app/features/work-packages/routing/partitioned-query-space-page/partitioned-query-space-page.component';
import { StateService, TransitionService } from '@uirouter/core';
import {
StateService,
TransitionService,
} from '@uirouter/core';
import { BoardFilterComponent } from 'core-app/features/boards/board/board-filter/board-filter.component';
import { Board } from 'core-app/features/boards/board/board';
import { ToastService } from 'core-app/shared/components/toaster/toast.service';
import { HalResourceNotificationService } from 'core-app/features/hal/services/hal-resource-notification.service';
import { BoardService } from 'core-app/features/boards/board/board.service';
import { DragAndDropService } from 'core-app/shared/helpers/drag-and-drop/drag-and-drop.service';
import { WorkPackageFilterButtonComponent } from 'core-app/features/work-packages/components/wp-buttons/wp-filter-button/wp-filter-button.component';
import { ZenModeButtonComponent } from 'core-app/features/work-packages/components/wp-buttons/zen-mode-toggle-button/zen-mode-toggle-button.component';
import { BoardsMenuButtonComponent } from 'core-app/features/boards/board/toolbar-menu/boards-menu-button.component';
import { RequestSwitchmap } from 'core-app/shared/helpers/rxjs/request-switchmap';
import { componentDestroyed } from '@w11k/ngx-componentdestroyed';
import {
catchError,
finalize,
take,
tap,
} from 'rxjs/operators';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { UntilDestroyedMixin } from 'core-app/shared/helpers/angular/until-destroyed.mixin';
Expand All @@ -35,11 +34,7 @@ import { BoardFiltersService } from 'core-app/features/boards/board/board-filter
import { CardViewHandlerRegistry } from 'core-app/features/work-packages/components/wp-card-view/event-handler/card-view-handler-registry';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import { OpTitleService } from 'core-app/core/html/op-title.service';
import {
EMPTY,
Observable,
of,
} from 'rxjs';
import { EMPTY } from 'rxjs';
import { SubmenuService } from 'core-app/core/main-menu/submenu.service';

export function boardCardViewHandlerFactory(injector:Injector) {
Expand Down Expand Up @@ -249,6 +244,6 @@ export class BoardPartitionedPageComponent extends UntilDestroyedMixin {
}

private reloadSidemenu():void {
this.submenuService.reloadSubmenu();
this.submenuService.reloadSubmenu(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ export class WorkPackagesListService {
// Reload the query, and then reload the menu
this.reloadQuery(createdQuery).subscribe(() => {
this.states.changes.queries.next(createdQuery.id);
this.reloadSidemenu();
this.reloadSidemenu(createdQuery.id);
});

return createdQuery;
Expand Down Expand Up @@ -313,7 +313,7 @@ export class WorkPackagesListService {
if (queryAccessibleByUser) {
void this.$state.go('.', { query_id: query.id, query_props: null }, { reload: true });
this.states.changes.queries.next(query.id);
this.reloadSidemenu();
this.reloadSidemenu(query.id);
} else {
this.navigateToDefaultQuery(query);
}
Expand Down Expand Up @@ -344,7 +344,7 @@ export class WorkPackagesListService {
this.toastService.addSuccess(this.I18n.t('js.notice_successful_update'));

this.states.changes.queries.next(query.id!);
this.reloadSidemenu();
this.reloadSidemenu(query.id);
});

return promise;
Expand Down Expand Up @@ -458,11 +458,11 @@ export class WorkPackagesListService {
void this.loadDefaultQuery(projectId);

this.states.changes.queries.next(query.id);
this.reloadSidemenu();
this.reloadSidemenu(null);
}
}

private reloadSidemenu():void {
this.submenuService.reloadSubmenu();
private reloadSidemenu(selectedQueryId:string|null):void {
this.submenuService.reloadSubmenu(selectedQueryId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export class StaticQueriesService {

if (this.$state.params.name) {
const nameKey = this.$state.params.name as string;
return this.I18n.t(`js.queries.${nameKey}`);
return this.I18n.t(`js.work_packages.default_queries.${nameKey}`);
}
}

Expand Down Expand Up @@ -143,33 +143,6 @@ export class StaticQueriesService {
},
view: 'WorkPackagesTable',
},
{
title: this.text.all_open,
uiSref: 'bim.partitioned.list',
uiParams: {
query_id: undefined,
query_props: '{"c":["id","subject","bcfThumbnail","type","status","assignee","updatedAt"],"t":"id:desc"}',
},
view: 'Bim',
},
{
title: this.text.latest_activity,
uiSref: 'bim.partitioned.list',
uiParams: {
query_id: undefined,
query_props: '{"c":["id","subject","bcfThumbnail","type","status","assignee","updatedAt"],"t":"updatedAt:desc","f":[{"n":"status","o":"o","v":[]}]}',
},
view: 'Bim',
},
{
title: this.text.recently_created,
uiSref: 'bim.partitioned.list',
uiParams: {
query_id: undefined,
query_props: '{"c":["id","subject","bcfThumbnail","type","status","assignee","createdAt"],"t":"createdAt:desc","f":[{"n":"status","o":"o","v":[]}]}',
},
view: 'Bim',
},
];

const projectIdentifier = this.CurrentProject.identifier;
Expand Down Expand Up @@ -237,24 +210,6 @@ export class StaticQueriesService {
isEnterprise: true,
...this.eeGuardedShareWithMeRoute,
},
{
title: this.text.created_by_me,
uiSref: 'bim.partitioned.list',
uiParams: {
query_id: undefined,
query_props: '{"c":["id","subject","bcfThumbnail","type","status","assignee","updatedAt"],"t":"id:desc","f":[{"n":"status","o":"o","v":[]},{"n":"author","o":"=","v":["me"]}]}',
},
view: 'Bim',
},
{
title: this.text.assigned_to_me,
uiSref: 'bim.partitioned.list',
uiParams: {
query_id: undefined,
query_props: '{"c":["id","subject","bcfThumbnail","type","status","author","updatedAt"],"t":"id:desc","f":[{"n":"status","o":"o","v":[]},{"n":"assigneeOrGroup","o":"=","v":["me"]}]}',
},
view: 'Bim',
},
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,10 @@ def prepare_form(ifc_model)
end

def frontend_redirect(model_ids)
props = '{"c":["id","subject","bcfThumbnail","type","status","assignee","updatedAt"],"t":"id:desc"}'
props = Bim::Menus::DefaultQueryGeneratorService.new.call
redirect_to bcf_project_frontend_path(models: JSON.dump(Array(model_ids)),
query_props: props)
query_props: props[:query_props],
name: props[:name])
end

def find_all_ifc_models
Expand Down
39 changes: 39 additions & 0 deletions modules/bim/app/controllers/bim/menus_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# -- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2010-2023 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 ::Bim
class MenusController < ApplicationController
before_action :find_project_by_project_id,
:authorize

def show
@submenu_menu_items = ::Bim::Menu.new(project: @project, params:).menu_items

render layout: nil
end
end
end
57 changes: 57 additions & 0 deletions modules/bim/app/menus/bim/menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2010-2023 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 Bim
class Menu < Submenu
attr_reader :view_type, :project, :params

def initialize(project: nil, params: nil)
@view_type = "bim"
@project = project
@params = params

super(view_type:, project:, params:)
end

def default_queries
query_generator = Bim::Menus::DefaultQueryGeneratorService.new
Bim::Menus::DefaultQueryGeneratorService::QUERY_OPTIONS.filter_map do |query_key|
params = query_generator.call(query_key:)
next if params.nil?

menu_item(
I18n.t("js.work_packages.default_queries.#{query_key}"),
params
)
end
end

def query_path(query_params)
bcf_project_frontend_path(project, query_params)
end
end
end
Loading

0 comments on commit ce6b3ed

Please sign in to comment.