Skip to content

Commit

Permalink
Replace path visiting
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverguenther committed Jun 13, 2024
1 parent ebc852f commit d3ebd6e
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 91 deletions.
14 changes: 13 additions & 1 deletion frontend/src/app/core/path-helper/path-helper.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ export class PathHelperService {
return `${this.staticBase}/notifications`;
}

public notificationsDetailsPath(workPackageId:string, tab?:string):string {
return `${this.notificationsPath()}/details/${workPackageId}${tab ? `/${tab}` : ''}`;
}

public loginPath() {
return `${this.staticBase}/login`;
}
Expand Down Expand Up @@ -260,8 +264,16 @@ export class PathHelperService {
return `${this.workPackagePath(workPackageId)}/copy`;
}

public workPackageDetailsPath(projectIdentifier:string, workPackageId:string|number, tab?:string) {
if (tab) {
return `${this.projectWorkPackagePath(projectIdentifier, workPackageId)}/details/${tab}`;
}

return `${this.projectWorkPackagesPath(projectIdentifier)}/details/${workPackageId}`;
}

public workPackageDetailsCopyPath(projectIdentifier:string, workPackageId:string|number) {
return `${this.projectWorkPackagesPath(projectIdentifier)}/details/${workPackageId}/copy`;
return this.workPackageDetailsPath(projectIdentifier, workPackageId, 'copy');
}

public workPackageSharePath(workPackageId:string|number) {
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/core/url-params/url-params.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export class UrlParamsService {
return this.searchParams.get(key);
}

public pathMatching(key:RegExp):string|null {
return window.location.pathname.match(key)?.[0] || null;
}

public has(key:string):boolean {
return this.searchParams.has(key);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,16 @@
//++

import { Injectable, Injector } from '@angular/core';
import {
debounceTime,
defaultIfEmpty,
distinctUntilChanged,
map,
mapTo,
pluck,
shareReplay,
switchMap,
take,
tap,
} from 'rxjs/operators';
import { forkJoin, from, Observable, Subject } from 'rxjs';
import { debounceTime, defaultIfEmpty, distinctUntilChanged, map, mapTo, switchMap, take, tap } from 'rxjs/operators';
import { forkJoin, from, Observable, of, Subject } from 'rxjs';
import { ID, Query } from '@datorama/akita';
import { UIRouterGlobals } from '@uirouter/core';
import { StateService } from '@uirouter/angular';

import { I18nService } from 'core-app/core/i18n/i18n.service';
import { IToast, ToastService } from 'core-app/shared/components/toaster/toast.service';
import {
centerUpdatedInPlace,
markNotificationsAsRead,
markNotificationsAsReadByFilters,
notificationCountIncreased,
notificationsMarkedRead,
} from 'core-app/core/state/in-app-notifications/in-app-notifications.actions';
Expand All @@ -72,6 +59,8 @@ import idFromLink from 'core-app/features/hal/helpers/id-from-link';
import { DeviceService } from 'core-app/core/browser/device.service';
import { ApiV3ListFilter, ApiV3ListParameters } from 'core-app/core/apiv3/paths/apiv3-list-resource.interface';
import { FrameElement } from '@hotwired/turbo';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { UrlParamsService } from 'core-app/core/url-params/url-params.service';

export interface INotificationPageQueryParameters {
filter?:string|null;
Expand All @@ -95,20 +84,6 @@ export class IanCenterService extends UntilDestroyedMixin {

menuFrame = document.getElementById('notifications_sidemenu') as FrameElement;

// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
activeReason$:Observable<string|null> = this.uiRouterGlobals.params$!.pipe(
this.untilDestroyed(),
distinctUntilChanged(),
map((params) => {
if (params.filter === 'reason') {
return params.name as string;
}

return null;
}),
shareReplay(1),
);

loading$:Observable<boolean> = this.query.selectLoading();

selectNotifications$:Observable<INotification[]> = this
Expand Down Expand Up @@ -204,13 +179,7 @@ export class IanCenterService extends UntilDestroyedMixin {

public selectedNotification:INotification;

stateChanged$ = this.uiRouterGlobals.params$?.pipe(
this.untilDestroyed(),
pluck('workPackageId'),
distinctUntilChanged(),
map((workPackageId:string) => (workPackageId ? this.apiV3Service.work_packages.id(workPackageId).path : undefined)),
shareReplay(),
);
stateChanged$ = of(this.urlParams.pathMatching(/\/details\/\d+/));

constructor(
readonly I18n:I18nService,
Expand All @@ -219,9 +188,10 @@ export class IanCenterService extends UntilDestroyedMixin {
readonly actions$:ActionsService,
readonly apiV3Service:ApiV3Service,
readonly toastService:ToastService,
readonly uiRouterGlobals:UIRouterGlobals,
readonly urlParams:UrlParamsService,
readonly state:StateService,
readonly deviceService:DeviceService,
readonly pathHelper:PathHelperService,
) {
super();
this.reload.subscribe();
Expand Down Expand Up @@ -261,13 +231,8 @@ export class IanCenterService extends UntilDestroyedMixin {
);
}

// eslint-disable-next-line @typescript-eslint/no-inferrable-types
openSplitScreen(workPackageId:string|null, tabIdentifier:string = 'activity'):void {
void this.state.go(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/restrict-template-expressions
`${this.state.current.data.baseRoute}.details.tabs`,
{ workPackageId, tabIdentifier },
);
openSplitScreen(workPackageId:string, tabIdentifier:string = 'activity'):void {
window.location.href = this.pathHelper.notificationsDetailsPath(workPackageId, tabIdentifier);
}

openFullView(workPackageId:string|null):void {
Expand Down Expand Up @@ -358,7 +323,7 @@ export class IanCenterService extends UntilDestroyedMixin {
}

// Reload the sidemenu frame
this.menuFrame.reload();
void this.menuFrame.reload();
}

private sideLoadInvolvedWorkPackages(elements:INotification[]):Promise<unknown> {
Expand Down Expand Up @@ -396,7 +361,7 @@ export class IanCenterService extends UntilDestroyedMixin {
(notifications:INotification[][]) => {
for (let i = 0; i < notifications.length; ++i) {
if (notifications[i][0]._links.resource
&& idFromLink(notifications[i][0]._links.resource.href) === this.uiRouterGlobals.params.workPackageId) {
&& idFromLink(notifications[i][0]._links.resource.href) === this.urlParams.pathMatching(/\/details\/(\d+)/)) {
this.selectedNotificationIndex = i;
[this.selectedNotification] = notifications[i];
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
import {
ChangeDetectionStrategy,
Component,
HostBinding,
Input,
OnInit,
ViewEncapsulation,
} from '@angular/core';
import { ChangeDetectionStrategy, Component, HostBinding, Input, OnInit, ViewEncapsulation } from '@angular/core';
import { WorkPackageResource } from 'core-app/features/hal/resources/work-package-resource';
import { Observable } from 'rxjs';
import { ApiV3Service } from 'core-app/core/apiv3/api-v3.service';
import idFromLink from 'core-app/features/hal/helpers/id-from-link';
import { I18nService } from 'core-app/core/i18n/i18n.service';
import { TimezoneService } from 'core-app/core/datetime/timezone.service';
import {
map,
shareReplay,
withLatestFrom,
} from 'rxjs/operators';
import { PathHelperService } from 'core-app/core/path-helper/path-helper.service';
import { take } from 'rxjs/internal/operators/take';
import { StateService } from '@uirouter/angular';
import { HalResource } from 'core-app/features/hal/resources/hal-resource';
import { INotification } from 'core-app/core/state/in-app-notifications/in-app-notification.model';
import { IanCenterService } from 'core-app/features/in-app-notifications/center/state/ian-center.service';
import { DeviceService } from 'core-app/core/browser/device.service';
import { UrlParamsService } from 'core-app/core/url-params/url-params.service';

@Component({
selector: 'op-in-app-notification-entry',
Expand All @@ -41,22 +28,10 @@ export class InAppNotificationEntryComponent implements OnInit {

workPackage$:Observable<WorkPackageResource>|null = null;

showDateAlert$:Observable<boolean> = this
.storeService
.activeReason$
.pipe(
map((reason) => reason === 'date_alert'),
map((dateAlertFiltered) => {
const dateAlerts = this.aggregatedNotifications.filter((notification) => notification.reason === 'dateAlert');
return dateAlertFiltered || dateAlerts.length === this.aggregatedNotifications.length;
}),
shareReplay(1),
);
showDateAlert = false;

loading$ = this.storeService.query.selectLoading();

stateChanged$ = this.storeService.stateChanged$;

// The translated reason, if available
translatedReasons:{ [reason:string]:number };

Expand All @@ -70,32 +45,45 @@ export class InAppNotificationEntryComponent implements OnInit {

private clickTimer:ReturnType<typeof setTimeout>;

private workPackageId:string|null;

constructor(
readonly apiV3Service:ApiV3Service,
readonly I18n:I18nService,
readonly storeService:IanCenterService,
readonly timezoneService:TimezoneService,
readonly pathHelper:PathHelperService,
readonly state:StateService,
readonly deviceService:DeviceService,
readonly urlParams:UrlParamsService,
) {
}

ngOnInit():void {
const href = this.notification._links.resource?.href;
this.workPackageId = href && HalResource.matchFromLink(href, 'work_packages');

this.showDateAlert = this.hasActiveDateAlert();
this.buildTranslatedReason();
this.buildProject();
this.loadWorkPackage();
}

private hasActiveDateAlert():boolean {
if (this.urlParams.get('filter') === 'reason' && this.urlParams.get('name') === 'date_alert') {
return true;
}

const dateAlerts = this.aggregatedNotifications.filter((notification) => notification.reason === 'dateAlert');
return dateAlerts.length === this.aggregatedNotifications.length;
}

private loadWorkPackage() {
const href = this.notification._links.resource?.href;
const id = href && HalResource.matchFromLink(href, 'work_packages');
// not a work package reference
if (id) {
if (this.workPackageId) {
this.workPackage$ = this
.apiV3Service
.work_packages
.id(id)
.id(this.workPackageId)
.requireAndStream();
}
}
Expand All @@ -110,20 +98,12 @@ export class InAppNotificationEntryComponent implements OnInit {
}

showDetails():void {
if (!this.workPackage$) {
if (!this.workPackageId) {
return;
}

this
.workPackage$
.pipe(
take(1),
withLatestFrom(this.showDateAlert$),
)
.subscribe(([wp, openDetailsTab]) => {
const tab = openDetailsTab ? 'overview' : 'activity';
this.storeService.openSplitScreen(wp.id, tab);
});
const tab = this.showDateAlert ? 'overview' : 'activity';
this.storeService.openSplitScreen(this.workPackageId, tab);
}

onDoubleClick():void {
Expand Down

0 comments on commit d3ebd6e

Please sign in to comment.