Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/components/work_packages/split_create_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<%= helpers.angular_component_tag "opce-wp-split-create",
inputs: { projectIdentifier: @project_identifier } %>
37 changes: 37 additions & 0 deletions app/components/work_packages/split_create_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

#-- 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.
#++

class WorkPackages::SplitCreateComponent < ApplicationComponent
def initialize(project_identifier:)
super

@project_identifier = project_identifier
end
end
8 changes: 8 additions & 0 deletions app/helpers/work_packages/split_view_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ def render_work_package_split_view?
params[:work_package_split_view].present?
end

def render_work_package_split_create?
params[:work_package_split_create].present?
end

def split_create_instance
WorkPackages::SplitCreateComponent.new(project_identifier: params[:project_id])
end

def split_view_instance
WorkPackages::SplitViewComponent.new(id: params[:work_package_id],
tab: params[:tab],
Expand Down
3 changes: 3 additions & 0 deletions app/views/work_packages/split_create.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<%= turbo_frame_tag "content-bodyRight" do %>
<%= render(split_create_instance) %>
<% end %>
11 changes: 11 additions & 0 deletions frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,15 @@ import {
import {
WorkPackageSplitViewEntryComponent,
} from 'core-app/features/work-packages/routing/wp-split-view/wp-split-view-entry.component';
import {
WorkPackageSplitCreateEntryComponent,
} from 'core-app/features/work-packages/routing/wp-split-create/wp-split-create-entry.component';
import {
BoardEntryComponent,
} from 'core-app/features/boards/board/board-partitioned-page/board-entry.component';
import { CalendarEntryComponent } from 'core-app/features/calendar/calendar-entry.component';
import { TeamPlannerEntryComponent } from 'core-app/features/team-planner/team-planner/team-planner-entry.component';
import { TeamPlannerModule } from 'core-app/features/team-planner/team-planner/team-planner.module';
import {
StorageLoginButtonComponent,
} from 'core-app/shared/components/storages/storage-login-button/storage-login-button.component';
Expand Down Expand Up @@ -300,6 +306,8 @@ export function runBootstrap(appRef:ApplicationRef) {
OpenprojectWorkPackageGraphsModule,
// Calendar module
OpenprojectCalendarModule,
// Team Planner module
TeamPlannerModule,

// MyPage
OpenprojectMyPageModule,
Expand Down Expand Up @@ -392,7 +400,10 @@ export class OpenProjectModule implements DoBootstrap {

registerCustomElement('opce-notification-center', InAppNotificationCenterComponent, { injector });
registerCustomElement('opce-wp-split-view', WorkPackageSplitViewEntryComponent, { injector });
registerCustomElement('opce-wp-split-create', WorkPackageSplitCreateEntryComponent, { injector });
registerCustomElement('opce-board-view', BoardEntryComponent, { injector });
registerCustomElement('opce-calendar-view', CalendarEntryComponent, { injector });
registerCustomElement('opce-team-planner-view', TeamPlannerEntryComponent, { injector });
registerCustomElement('opce-wp-full-view', WorkPackageFullViewEntryComponent, { injector });
registerCustomElement('opce-wp-full-create', WorkPackageFullCreateEntryComponent, { injector });
registerCustomElement('opce-wp-full-copy', WorkPackageFullCopyEntryComponent, { injector });
Expand Down
42 changes: 21 additions & 21 deletions frontend/src/app/core/main-menu/submenu.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,31 @@ export class SubmenuService {
reloadSubmenu(selectedQueryId:string|null, sidemenuId?:string):void {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment
const menuIdentifier:string|undefined = sidemenuId ?? this.$state.current.data?.sideMenuOptions?.sidemenuId;
if (!menuIdentifier) { return; }

if (menuIdentifier) {
const menu = document.getElementById(menuIdentifier) as FrameElement;
// 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');
const menu = document.getElementById(menuIdentifier) as FrameElement|null;
const currentSrc = menu?.getAttribute('src');
if (!currentSrc || !menu) { return; }

if (currentSrc && menu) {
const frameUrl = new URL(currentSrc, window.location.origin);
const defaultQuery = sideMenuOptions?.defaultQuery;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
const sideMenuOptions = this.$state.$current.data?.sideMenuOptions as { hardReloadOnBaseRoute?:boolean, defaultQuery?:string };
const frameUrl = new URL(currentSrc, window.location.origin);

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}`;
}
}
if (selectedQueryId) {
// Prefer the data attribute on the frame, then fall back to route sideMenuOptions,
// then default to 'query_id'. Modules with path-based IDs (e.g. calendars/:id)
// set data-query-param="id" on the frame.
const queryParam = menu.getAttribute('data-query-param')
?? (sideMenuOptions?.defaultQuery ? 'id' : 'query_id');

// Override the frame src to enforce a reload
menu.setAttribute('src', frameUrl.href);
}
frameUrl.search = `?${queryParam}=${selectedQueryId}`;
}

const newSrc = frameUrl.href;
if (menu.getAttribute('src') !== newSrc) {
menu.setAttribute('src', newSrc);
} else {
void menu.reload();
}
}
}
4 changes: 0 additions & 4 deletions frontend/src/app/core/routing/openproject.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ import {
mobileGuardActivated,
redirectToMobileAlternative,
} from 'core-app/shared/helpers/routing/mobile-guard.helper';
import { TEAM_PLANNER_LAZY_ROUTES } from 'core-app/features/team-planner/team-planner/team-planner.lazy-routes';
import { CALENDAR_LAZY_ROUTES } from 'core-app/features/calendar/calendar.lazy-routes';

export const OPENPROJECT_ROUTES:Ng2StateDeclaration[] = [
{
Expand Down Expand Up @@ -74,8 +72,6 @@ export const OPENPROJECT_ROUTES:Ng2StateDeclaration[] = [
url: '/bcf',
loadChildren: () => import('../../features/bim/ifc_models/openproject-ifc-models.module').then((m) => m.OpenprojectIFCModelsModule),
},
...TEAM_PLANNER_LAZY_ROUTES,
...CALENDAR_LAZY_ROUTES,
];

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@
// See COPYRIGHT and LICENSE files for more details.
//++

import { ChangeDetectionStrategy, Component, ElementRef, Injector, Input } from '@angular/core';
import {
ChangeDetectionStrategy,
Component,
ElementRef,
Injector,
Input,
OnDestroy,
} from '@angular/core';
import { populateInputsFromDataset } from 'core-app/shared/components/dataset-inputs';
import {
WorkPackageIsolatedQuerySpaceDirective,
Expand All @@ -43,7 +50,7 @@ import { QueryUpdatedService } from 'core-app/features/boards/board/query-update
@Component({
selector: 'board-entry',
hostDirectives: [WorkPackageIsolatedQuerySpaceDirective],
template: `<board-partitioned-page [boardId]="boardId" />`,
template: '<board-partitioned-page [boardId]="boardId"><board-list-container [boardId]="boardId" /></board-partitioned-page>',
changeDetection: ChangeDetectionStrategy.OnPush,
providers: [
BoardConfigurationService,
Expand All @@ -56,7 +63,7 @@ import { QueryUpdatedService } from 'core-app/features/boards/board/query-update
],
standalone: false,
})
export class BoardEntryComponent {
export class BoardEntryComponent implements OnDestroy {
@Input() boardId:string;

constructor(
Expand All @@ -74,4 +81,8 @@ export class BoardEntryComponent {
registry.add('subproject', injector.get(BoardSubprojectActionService));
registry.add('subtasks', injector.get(BoardSubtasksActionService));
}

ngOnDestroy() {
document.body.classList.remove('router--boards-full-view');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function boardCardViewHandlerFactory(injector:Injector) {

@Component({
selector: 'board-partitioned-page',
templateUrl: './board-partitioned-page.component.html',
templateUrl: '../../../work-packages/routing/partitioned-query-space-page/primerized-partitioned-query-space-page.component.html',
styleUrls: [
'../../../work-packages/routing/partitioned-query-space-page/partitioned-query-space-page.component.sass',
'./board-partitioned-page.component.sass',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,33 @@
// See COPYRIGHT and LICENSE files for more details.
//++

import { Ng2StateDeclaration } from '@uirouter/angular';
import {
ChangeDetectionStrategy,
Component,
ElementRef,
Input,
OnDestroy,
} from '@angular/core';
import { populateInputsFromDataset } from 'core-app/shared/components/dataset-inputs';
import {
WorkPackageIsolatedQuerySpaceDirective,
} from 'core-app/features/work-packages/directives/query-space/wp-isolated-query-space.directive';

export const CALENDAR_LAZY_ROUTES:Ng2StateDeclaration[] = [
{
name: 'calendar.**',
parent: 'optional_project',
url: '/calendars',
loadChildren: () => import('./openproject-calendar.module').then((m) => m.OpenprojectCalendarModule),
},
];
@Component({
hostDirectives: [WorkPackageIsolatedQuerySpaceDirective],
template: '<op-wp-calendar-page [queryId]="queryId"><op-wp-calendar /></op-wp-calendar-page>',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
})
export class CalendarEntryComponent implements OnDestroy {
@Input() queryId:string;

constructor(readonly elementRef:ElementRef) {

Check failure on line 50 in frontend/src/app/features/calendar/calendar-entry.component.ts

View workflow job for this annotation

GitHub Actions / eslint

[eslint] frontend/src/app/features/calendar/calendar-entry.component.ts#L50 <@angular-eslint/prefer-inject>(https://github.com/angular-eslint/angular-eslint/blob/main/packages/eslint-plugin/docs/rules/prefer-inject.md)

Prefer using the inject() function over constructor parameter injection. Use Angular's migration schematic to automatically refactor: ng generate @angular/core:inject
Raw output
{"ruleId":"@angular-eslint/prefer-inject","severity":2,"message":"Prefer using the inject() function over constructor parameter injection. Use Angular's migration schematic to automatically refactor: ng generate @angular/core:inject","line":50,"column":15,"nodeType":"TSParameterProperty","messageId":"preferInject","endLine":50,"endColumn":45}
populateInputsFromDataset(this);
document.body.classList.add('router--calendar');
}

ngOnDestroy() {
document.body.classList.add('router--calendar');
}
}
84 changes: 0 additions & 84 deletions frontend/src/app/features/calendar/calendar.routes.ts

This file was deleted.

Loading
Loading