+
share
diff --git a/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.component.ts b/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.component.ts
index 75de55e76..7a1443414 100644
--- a/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.component.ts
+++ b/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.component.ts
@@ -6,14 +6,13 @@ import { NgClass, AsyncPipe } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatAnchor, MatButton, MatIconButton } from '@angular/material/button';
-import { MatCardContent } from '@angular/material/card';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDialog } from '@angular/material/dialog';
import { MatIcon } from '@angular/material/icon';
-import { MatProgressBar } from '@angular/material/progress-bar';
import { MatRadioModule } from '@angular/material/radio';
import { MatTooltip } from '@angular/material/tooltip';
import { RouterLink } from '@angular/router';
+import { addMinutes, differenceInMinutes } from 'date-fns';
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
import { BehaviorSubject, map } from 'rxjs';
import { Session } from 'src/app/openapi';
@@ -21,6 +20,7 @@ import { BeautifyService } from 'src/app/services/beatify/beautify.service';
import { OwnUserWrapperService } from 'src/app/services/user/user.service';
import { ConnectionDialogComponent } from 'src/app/sessions/user-sessions-wrapper/active-sessions/connection-dialog/connection-dialog.component';
import { SessionSharingDialogComponent } from 'src/app/sessions/user-sessions-wrapper/active-sessions/session-sharing-dialog/session-sharing-dialog.component';
+import { RelativeTimeComponent } from '../../../general/relative-time/relative-time.component';
import { DeleteSessionDialogComponent } from '../../delete-session-dialog/delete-session-dialog.component';
import { FeedbackWrapperService } from '../../feedback/feedback.service';
import {
@@ -42,8 +42,6 @@ import { FileBrowserDialogComponent } from './file-browser-dialog/file-browser-d
RouterLink,
MatIcon,
NgClass,
- MatCardContent,
- MatProgressBar,
MatButton,
AsyncPipe,
MatIconButton,
@@ -51,6 +49,7 @@ import { FileBrowserDialogComponent } from './file-browser-dialog/file-browser-d
MatCheckboxModule,
MatRadioModule,
FormsModule,
+ RelativeTimeComponent,
],
})
export class ActiveSessionsComponent implements OnInit {
@@ -133,6 +132,29 @@ export class ActiveSessionsComponent implements OnInit {
isSessionShared(session: Session): boolean {
return session.owner.id != this.userWrapperService.user?.id;
}
+
+ minutesUntilSessionTermination(session: Session): number | null {
+ if (session.idle_state.available) {
+ if (session.idle_state.idle_for_minutes === -1) {
+ // session was never connected to, use creation time
+ return (
+ session.idle_state.terminate_after_minutes -
+ differenceInMinutes(session.created_at, Date.now())
+ );
+ } else {
+ return (
+ session.idle_state.terminate_after_minutes -
+ session.idle_state.idle_for_minutes!
+ );
+ }
+ } else {
+ return null;
+ }
+ }
+
+ protected readonly Date = Date;
+ protected readonly addMinutes = addMinutes;
+ protected readonly differenceInMinutes = differenceInMinutes;
}
type SessionWithSelection = Session & { selected: boolean };
diff --git a/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.stories.ts b/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.stories.ts
index 15766968b..d53b54bb3 100644
--- a/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.stories.ts
+++ b/frontend/src/app/sessions/user-sessions-wrapper/active-sessions/active-sessions.stories.ts
@@ -8,6 +8,7 @@ import {
componentWrapperDecorator,
moduleMetadata,
} from '@storybook/angular';
+import MockDate from 'mockdate';
import { Observable, of } from 'rxjs';
import {
Session,
@@ -54,6 +55,9 @@ const meta: Meta
= {
(story) => `${story}
`,
),
],
+ beforeEach: () => {
+ MockDate.set(new Date('2024-05-01'));
+ },
};
export default meta;
@@ -167,6 +171,32 @@ export const SessionRunningState: Story = {
],
};
+export const SessionTerminatingSoon: Story = {
+ args: {},
+ decorators: [
+ moduleMetadata({
+ providers: [
+ {
+ provide: UserSessionService,
+ useFactory: () =>
+ new MockUserSessionService({
+ ...createPersistentSessionWithState(
+ SessionPreparationState.Completed,
+ SessionState.Running,
+ ),
+ idle_state: {
+ available: true,
+ terminate_after_minutes: 90,
+ idle_for_minutes: 80,
+ unavailable_reason: null,
+ },
+ }),
+ },
+ ],
+ }),
+ ],
+};
+
export const SessionTerminatedState: Story = {
args: {},
decorators: [
@@ -341,6 +371,56 @@ export const SessionSharedWithUser: Story = {
}),
],
};
+export const SessionSharedWithUserTerminatingSoon: Story = {
+ args: {},
+ decorators: [
+ moduleMetadata({
+ providers: [
+ {
+ provide: UserSessionService,
+ useFactory: () =>
+ new MockUserSessionService({
+ ...mockPersistentSession,
+ connection_method: {
+ ...mockHttpConnectionMethod,
+ sharing: { enabled: true },
+ },
+ idle_state: {
+ available: true,
+ terminate_after_minutes: 90,
+ idle_for_minutes: 80,
+ unavailable_reason: null,
+ },
+ shared_with: [
+ {
+ user: {
+ id: 1,
+ name: 'user_1',
+ role: 'administrator',
+ email: null,
+ idp_identifier: 'user_1',
+ beta_tester: false,
+ },
+ created_at: '2024-04-29T15:00:00Z',
+ },
+ {
+ user: {
+ id: 2,
+ name: 'user_2',
+ role: 'user',
+ email: null,
+ idp_identifier: 'user_2',
+ beta_tester: false,
+ },
+ created_at: '2024-04-29T15:00:00Z',
+ },
+ ],
+ }),
+ },
+ ],
+ }),
+ ],
+};
export const SharedSession: Story = {
args: {},
diff --git a/frontend/src/app/sessions/user-sessions-wrapper/create-sessions/create-session-history/create-session-history.component.html b/frontend/src/app/sessions/user-sessions-wrapper/create-sessions/create-session-history/create-session-history.component.html
index 85011069e..cd3902c56 100644
--- a/frontend/src/app/sessions/user-sessions-wrapper/create-sessions/create-session-history/create-session-history.component.html
+++ b/frontend/src/app/sessions/user-sessions-wrapper/create-sessions/create-session-history/create-session-history.component.html
@@ -17,38 +17,28 @@
}
@for (session of sortedResolvedHistory; track $index) {